├── .gitattributes ├── plugins ├── default │ └── deps.txt ├── hello_triangle │ ├── deps.txt │ ├── res │ │ ├── shader.frag │ │ ├── ui.shader.frag │ │ ├── shader.vert │ │ └── ui.shader.vert │ └── src │ │ └── hello_triangle │ │ └── image.vx └── core │ └── src │ └── core │ ├── host.vx │ ├── lz4.vx │ ├── zstd.vx │ ├── qoi.vx │ ├── math.vx │ ├── mimalloc.vx │ ├── mdbx.vx │ ├── tracy.vx │ ├── kernel32.vx │ ├── enet.vx │ ├── vector.vx │ ├── utils.vx │ ├── format.vx │ ├── glfw3.vx │ ├── vulkan │ └── vma.vx │ └── shaderc.vx ├── .gitmodules ├── host ├── deps │ ├── lz4.d │ ├── tracy.d │ ├── zstd.d │ ├── mimalloc.d │ ├── kernel32.d │ ├── tracy_lib.d │ ├── tracy_ptr.d │ ├── tracy_stub.d │ ├── enet.d │ ├── shaderc.d │ ├── vma.d │ ├── mdbx.d │ ├── game_networking_sockets.d │ └── glfw3.d ├── qoi.d └── main.d ├── .gitignore ├── .editorconfig ├── license.md ├── .github └── workflows │ └── ci.yml └── readme.md /.gitattributes: -------------------------------------------------------------------------------- 1 | *.vx linguist-language=D -------------------------------------------------------------------------------- /plugins/default/deps.txt: -------------------------------------------------------------------------------- 1 | hello_triangle -------------------------------------------------------------------------------- /plugins/hello_triangle/deps.txt: -------------------------------------------------------------------------------- 1 | core -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "vox"] 2 | path = vox 3 | url = https://github.com/MrSmith33/vox.git 4 | -------------------------------------------------------------------------------- /host/deps/lz4.d: -------------------------------------------------------------------------------- 1 | module deps.lz4; 2 | extern(C): 3 | void LZ4_compress_default(); 4 | void LZ4_decompress_safe(); 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.cmd 2 | *.def 3 | *.dll 4 | *.exe 5 | *.lib 6 | *.lst 7 | *.obj 8 | *.pdb 9 | *.sublime-project 10 | *.sublime-workspace 11 | /bin 12 | /lib -------------------------------------------------------------------------------- /plugins/core/src/core/host.vx: -------------------------------------------------------------------------------- 1 | /// Host function bindings 2 | module core.host; 3 | @extern(module, "host"): 4 | 5 | void host_print(u8[] str); 6 | void __debugbreak(); 7 | -------------------------------------------------------------------------------- /plugins/core/src/core/lz4.vx: -------------------------------------------------------------------------------- 1 | module core.lz4; 2 | @extern(module, "lz4"): 3 | 4 | i32 LZ4_compress_default(u8* source, u8* dest, i32 sourceSize, i32 maxDestSize); 5 | i32 LZ4_decompress_safe(u8* source, u8* dest, i32 compressedSize, i32 maxDecompressedSize); 6 | -------------------------------------------------------------------------------- /host/deps/tracy.d: -------------------------------------------------------------------------------- 1 | module deps.tracy; 2 | 3 | extern(C): 4 | 5 | struct TracyLoc { 6 | const char* name; 7 | const char* func; 8 | const char* file; 9 | uint line; 10 | uint color; 11 | } 12 | 13 | struct TracyCZoneCtx { 14 | uint id; 15 | int active; 16 | } 17 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | 6 | [*.{vx,c,h,d,di,dd,json}] 7 | insert_final_newline = true 8 | indent_style = tab 9 | indent_size = 4 10 | trim_trailing_whitespace = true 11 | charset = utf-8 12 | 13 | [*.md] 14 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /plugins/hello_triangle/res/shader.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location = 0) in vec3 fragColor; 4 | layout(location = 1) in vec2 fragTexCoord; 5 | 6 | layout(set = 0, binding = 1) uniform sampler2D texSampler; 7 | 8 | layout(location = 0) out vec4 outColor; 9 | 10 | void main() { 11 | outColor = vec4(fragColor, 1.0) * texture(texSampler, fragTexCoord); 12 | } -------------------------------------------------------------------------------- /host/deps/zstd.d: -------------------------------------------------------------------------------- 1 | module deps.zstd; 2 | 3 | extern(C): 4 | 5 | void ZSTD_compress(); 6 | void ZSTD_decompress(); 7 | void ZSTD_getFrameContentSize(); 8 | void ZSTD_getDecompressedSize(); 9 | void ZSTD_findFrameCompressedSize(); 10 | void ZSTD_compressBound(); 11 | void ZSTD_isError(); 12 | void ZSTD_getErrorName(); 13 | void ZSTD_minCLevel(); 14 | void ZSTD_maxCLevel(); 15 | void ZSTD_defaultCLevel(); 16 | -------------------------------------------------------------------------------- /plugins/hello_triangle/src/hello_triangle/image.vx: -------------------------------------------------------------------------------- 1 | module hello_triangle.image; 2 | 3 | import core.utils; 4 | import core.vector; 5 | import core.mimalloc; 6 | 7 | // 4 channels, u8u8u8u8 rgba 8 | struct ImageData { 9 | u8* ptr; 10 | uvec2 size; 11 | 12 | u32 byteLength() { return size.x * size.y * 4; } 13 | 14 | void free() { 15 | mi_free(ptr); 16 | ptr = null; 17 | size = uvec2(0, 0); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /plugins/core/src/core/zstd.vx: -------------------------------------------------------------------------------- 1 | module core.zstd; 2 | @extern(module, "zstd"): 3 | 4 | void ZSTD_compress(); 5 | void ZSTD_decompress(); 6 | void ZSTD_getFrameContentSize(); 7 | void ZSTD_getDecompressedSize(); 8 | void ZSTD_findFrameCompressedSize(); 9 | void ZSTD_compressBound(); 10 | void ZSTD_isError(); 11 | void ZSTD_getErrorName(); 12 | void ZSTD_minCLevel(); 13 | void ZSTD_maxCLevel(); 14 | void ZSTD_defaultCLevel(); 15 | -------------------------------------------------------------------------------- /plugins/core/src/core/qoi.vx: -------------------------------------------------------------------------------- 1 | module core.qoi; 2 | @extern(module, "qoi"): 3 | 4 | enum QOI_COLORSPACE : u8 { 5 | SRGB = 0, 6 | LINEAR = 1, 7 | } 8 | 9 | struct qoi_desc { 10 | u32 width; 11 | u32 height; 12 | u8 channels; 13 | QOI_COLORSPACE colorspace; 14 | } 15 | 16 | void* qoi_encode(void* data, qoi_desc* desc, i32* out_len, void* function(u64 size) malloc); 17 | void* qoi_decode(void* data, i32 size, qoi_desc* desc, i32 channels, void* function(u64 size) malloc); 18 | -------------------------------------------------------------------------------- /plugins/core/src/core/math.vx: -------------------------------------------------------------------------------- 1 | module core.math; 2 | 3 | enum f64 PI = 3.14159265358979323846; 4 | 5 | f32 tan_f32(f32 v) { return sin_f32(v) / cos_f32(v); } 6 | f64 tan_f64(f64 v) { return sin_f64(v) / cos_f64(v); } 7 | f32 cot_f32(f32 v) { return cos_f32(v) / sin_f32(v); } 8 | f64 cot_f64(f64 v) { return cos_f64(v) / sin_f64(v); } 9 | 10 | @extern(module, "host"): 11 | f32 sin_f32(f32); 12 | f64 sin_f64(f64); 13 | f32 cos_f32(f32); 14 | f64 cos_f64(f64); 15 | f32 sqrt_f32(f32); 16 | f64 sqrt_f64(f64); 17 | -------------------------------------------------------------------------------- /plugins/hello_triangle/res/ui.shader.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(location = 0) in vec3 fragColor; 4 | layout(location = 1) in vec2 fragTexCoord; 5 | 6 | layout(set = 0, binding = 1) uniform sampler2D texSampler; 7 | 8 | layout(location = 0) out vec4 outColor; 9 | 10 | void main() { 11 | // outColor = vec4(fragColor, 1.0) * texture(texSampler, fragTexCoord); 12 | // outColor = vec4(fragColor, 1.0) * texture(texSampler, fragTexCoord / 200); 13 | outColor = vec4(fragColor, 1.0) * texture(texSampler, fragTexCoord / textureSize(texSampler, 0)); 14 | } -------------------------------------------------------------------------------- /plugins/hello_triangle/res/shader.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(row_major) layout(set = 0, binding = 0) uniform UniformBufferObject { 4 | mat4 model; 5 | mat4 view; 6 | mat4 proj; 7 | } ubo; 8 | 9 | layout(location = 0) in vec3 inPosition; 10 | layout(location = 1) in vec2 inTexCoord; 11 | layout(location = 2) in vec3 inColor; 12 | 13 | layout(location = 0) out vec3 fragColor; 14 | layout(location = 1) out vec2 fragTexCoord; 15 | 16 | void main() { 17 | gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 1.0); 18 | fragColor = inColor; 19 | fragTexCoord = inTexCoord; 20 | } -------------------------------------------------------------------------------- /plugins/hello_triangle/res/ui.shader.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout(row_major) layout(set = 0, binding = 0) uniform UniformBufferObject { 4 | vec2 screenSize; 5 | } ubo; 6 | 7 | layout(location = 0) in vec2 inPosition; 8 | layout(location = 1) in vec2 inTexCoord; 9 | layout(location = 2) in vec3 inColor; 10 | 11 | layout(location = 0) out vec3 fragColor; 12 | layout(location = 1) out vec2 fragTexCoord; 13 | 14 | void main() { 15 | // gl_Position = vec4(inPosition, 0.0, 1.0); 16 | gl_Position = vec4((inPosition / ubo.screenSize) * 2 - 1, 0.0, 1.0); 17 | fragColor = inColor; 18 | fragTexCoord = inTexCoord; 19 | } -------------------------------------------------------------------------------- /host/deps/mimalloc.d: -------------------------------------------------------------------------------- 1 | module deps.mimalloc; 2 | extern(C): 3 | // Standard malloc interface 4 | void* mi_malloc(size_t size); 5 | void* mi_calloc(size_t count, size_t size); 6 | void* mi_realloc(void* p, size_t newsize); 7 | void* mi_recalloc(void *p, size_t count, size_t size); 8 | void* mi_expand(void* p, size_t newsize); 9 | void mi_free(void* p); 10 | // Extended functionality 11 | void* mi_malloc_small(size_t size); 12 | void* mi_zalloc_small(size_t size); 13 | void* mi_zalloc(size_t size); 14 | void* mi_mallocn(size_t count, size_t size); 15 | void* mi_reallocn(void* p, size_t count, size_t size); 16 | void* mi_reallocf(void* p, size_t newsize); 17 | size_t mi_usable_size(void* p); 18 | size_t mi_good_size(size_t size); 19 | // Zero initialized re-allocation 20 | void* mi_rezalloc(void* p, size_t newsize); 21 | -------------------------------------------------------------------------------- /plugins/core/src/core/mimalloc.vx: -------------------------------------------------------------------------------- 1 | module core.mimalloc; 2 | @extern(module, "mimalloc"): 3 | 4 | // Docs: https://microsoft.github.io/mimalloc 5 | 6 | void* mi_malloc(u64 size); 7 | void* mi_calloc(u64 count, u64 size); 8 | void* mi_realloc(void* p, u64 newsize); 9 | void* mi_recalloc(void *p, u64 count, u64 size); 10 | void* mi_expand(void* p, u64 newsize); 11 | void mi_free(void* p); 12 | // Extended functionality 13 | void* mi_malloc_small(u64 size); 14 | void* mi_zalloc_small(u64 size); 15 | void* mi_zalloc(u64 size); 16 | void* mi_mallocn(u64 count, u64 size); 17 | void* mi_reallocn(void* p, u64 count, u64 size); 18 | void* mi_reallocf(void* p, u64 newsize); 19 | u64 mi_usable_size(void* p); 20 | u64 mi_good_size(u64 size); 21 | // Zero initialized re-allocation 22 | void* mi_rezalloc(void* p, u64 newsize); 23 | -------------------------------------------------------------------------------- /host/deps/kernel32.d: -------------------------------------------------------------------------------- 1 | module deps.kernel32; 2 | extern(C): 3 | void CreateFileA(); 4 | void ExitProcess(); 5 | void ExitThread(); 6 | void GetProcessHeap(); 7 | void GetStdHandle(); 8 | void GetFileSizeEx(); 9 | void GetTickCount64(); 10 | void HeapAlloc(); 11 | void HeapFree(); 12 | void QueryPerformanceCounter(); 13 | void QueryPerformanceFrequency(); 14 | void ReadFile(); 15 | void RtlCopyMemory(); 16 | bool SetConsoleOutputCP(uint); 17 | void WriteConsoleA(); 18 | void WriteFile(); 19 | void Sleep(); 20 | void CloseHandle(); 21 | int GetLastError(); // llvm complains if types do not match 22 | void LocalFree(); 23 | void FormatMessageA(); 24 | bool SetThreadPriority(void* hThread, int nPriority); 25 | void GetCurrentThreadId(); 26 | void* GetCurrentThread(); 27 | size_t SetThreadAffinityMask(void* hThread, size_t dwThreadAffinityMask); 28 | -------------------------------------------------------------------------------- /plugins/core/src/core/mdbx.vx: -------------------------------------------------------------------------------- 1 | module core.mdbx; 2 | @extern(module, "mdbx"): 3 | 4 | struct MDBX_env; 5 | i32 mdbx_env_create(MDBX_env **penv); 6 | i32 mdbx_env_open(MDBX_env *env, u8* pathname, u32 flags, u16 mode); 7 | i32 mdbx_env_close_ex(MDBX_env *env, bool dont_sync = false); 8 | 9 | enum MDBX_env_flags_t : u32 { 10 | MDBX_ENV_DEFAULTS = 0, 11 | MDBX_NOSUBDIR = 0x4000, 12 | MDBX_RDONLY = 0x20000, 13 | MDBX_EXCLUSIVE = 0x400000, 14 | MDBX_ACCEDE = 0x40000000, 15 | MDBX_WRITEMAP = 0x80000, 16 | MDBX_NOTLS = 0x200000, 17 | MDBX_NORDAHEAD = 0x800000, 18 | MDBX_NOMEMINIT = 0x1000000, 19 | MDBX_COALESCE = 0x2000000, 20 | MDBX_LIFORECLAIM = 0x4000000, 21 | MDBX_PAGEPERTURB = 0x8000000, 22 | MDBX_SYNC_DURABLE = 0, 23 | MDBX_NOMETASYNC = 0x40000, 24 | MDBX_SAFE_NOSYNC = 0x10000, 25 | MDBX_MAPASYNC = MDBX_SAFE_NOSYNC, 26 | MDBX_UTTERLY_NOSYNC = MDBX_SAFE_NOSYNC | 0x100000, 27 | } 28 | -------------------------------------------------------------------------------- /host/deps/tracy_lib.d: -------------------------------------------------------------------------------- 1 | module deps.tracy_lib; 2 | 3 | import deps.tracy; 4 | 5 | extern(C): 6 | 7 | void ___tracy_startup_profiler(); 8 | void ___tracy_shutdown_profiler(); 9 | TracyCZoneCtx ___tracy_emit_zone_begin(const TracyLoc* srcloc, int active); 10 | TracyCZoneCtx ___tracy_emit_zone_begin_callstack(const TracyLoc* srcloc, int depth, int active); 11 | void ___tracy_emit_zone_end(TracyCZoneCtx ctx); 12 | void ___tracy_emit_frame_mark(const char* name); 13 | void ___tracy_emit_frame_mark_start(const char* name); 14 | void ___tracy_emit_frame_mark_end(const char* name); 15 | 16 | void ___tracy_set_thread_name(const char* name); 17 | 18 | void ___tracy_emit_plot(const char* name, double val); 19 | void ___tracy_emit_message_appinfo(const char* txt, size_t size); 20 | void ___tracy_emit_message(const char* txt, size_t size, int callstack); 21 | void ___tracy_emit_messageL(const char* txt, int callstack); 22 | void ___tracy_emit_messageC(const char* txt, size_t size, uint color, int callstack); 23 | void ___tracy_emit_messageLC(const char* txt, uint color, int callstack); 24 | 25 | -------------------------------------------------------------------------------- /plugins/core/src/core/tracy.vx: -------------------------------------------------------------------------------- 1 | module core.tracy; 2 | @extern(module, "tracy"): 3 | 4 | struct TracyLoc 5 | { 6 | u8* name; 7 | u8* func; 8 | u8* file; 9 | u32 line; 10 | u32 color; 11 | } 12 | 13 | struct TracyZoneCtx 14 | { 15 | u32 id; 16 | i32 active; 17 | } 18 | 19 | TracyZoneCtx tracy_emit_zone_begin(TracyLoc* srcloc, i32 active); 20 | TracyZoneCtx tracy_emit_zone_begin_callstack(TracyLoc* srcloc, i32 depth, i32 active); 21 | void tracy_emit_zone_end(TracyZoneCtx ctx); 22 | void tracy_emit_frame_mark(u8* name = null); 23 | void tracy_emit_frame_mark_start(u8* name); 24 | void tracy_emit_frame_mark_end(u8* name); 25 | void tracy_set_thread_name(u8* name); 26 | void tracy_emit_plot(u8* name, f64 val); 27 | void tracy_emit_message_appinfo(u8* txt, u64 size); 28 | void tracy_emit_message(u8* txt, u64 size, i32 callstack = 0); 29 | void tracy_emit_messageL(u8* txt, i32 callstack = 0); // literal 30 | void tracy_emit_messageC(u8* txt, u64 size, u32 color, i32 callstack = 0); // colored 31 | void tracy_emit_messageLC(u8* txt, u32 color, i32 callstack = 0); // literal colored 32 | -------------------------------------------------------------------------------- /host/deps/tracy_ptr.d: -------------------------------------------------------------------------------- 1 | module deps.tracy_ptr; 2 | 3 | public import deps.tracy; 4 | 5 | extern(C): 6 | 7 | void function() tracy_startup_profiler; 8 | void function() tracy_shutdown_profiler; 9 | TracyCZoneCtx function(const TracyLoc* srcloc, int active) tracy_emit_zone_begin; 10 | TracyCZoneCtx function(const TracyLoc* srcloc, int depth, int active) tracy_emit_zone_begin_callstack; 11 | void function(TracyCZoneCtx ctx) tracy_emit_zone_end; 12 | void function(const char* name) tracy_emit_frame_mark; 13 | void function(const char* name) tracy_emit_frame_mark_start; 14 | void function(const char* name) tracy_emit_frame_mark_end; 15 | 16 | void function(const char* name) tracy_set_thread_name; 17 | 18 | void function(const char* name, double val) tracy_emit_plot; 19 | void function(const char* txt, size_t size) tracy_emit_message_appinfo; 20 | void function(const char* txt, size_t size, int callstack) tracy_emit_message; 21 | void function(const char* txt, int callstack) tracy_emit_messageL; 22 | void function(const char* txt, size_t size, uint color, int callstack) tracy_emit_messageC; 23 | void function(const char* txt, uint color, int callstack) tracy_emit_messageLC; 24 | -------------------------------------------------------------------------------- /host/deps/tracy_stub.d: -------------------------------------------------------------------------------- 1 | module deps.tracy_stub; 2 | 3 | import deps.tracy; 4 | 5 | extern(C): 6 | 7 | void stub_tracy_startup_profiler() {} 8 | void stub_tracy_shutdown_profiler() {} 9 | TracyCZoneCtx stub_tracy_emit_zone_begin(const TracyLoc* srcloc, int active) { return TracyCZoneCtx(); } 10 | TracyCZoneCtx stub_tracy_emit_zone_begin_callstack(const TracyLoc* srcloc, int depth, int active) { return TracyCZoneCtx(); } 11 | void stub_tracy_emit_zone_end(TracyCZoneCtx ctx) {} 12 | void stub_tracy_emit_frame_mark(const char* name) {} 13 | void stub_tracy_emit_frame_mark_start(const char* name) {} 14 | void stub_tracy_emit_frame_mark_end(const char* name) {} 15 | void stub_tracy_set_thread_name(const char* name) {} 16 | void stub_tracy_emit_plot(const char* name, double val) {} 17 | void stub_tracy_emit_message_appinfo(const char* txt, size_t size) {} 18 | void stub_tracy_emit_message(const char* txt, size_t size, int callstack) {} 19 | void stub_tracy_emit_messageL(const char* txt, int callstack) {} 20 | void stub_tracy_emit_messageC(const char* txt, size_t size, uint color, int callstack) {} 21 | void stub_tracy_emit_messageLC(const char* txt, uint color, int callstack) {} 22 | -------------------------------------------------------------------------------- /license.md: -------------------------------------------------------------------------------- 1 | Boost Software License - Version 1.0 - August 17th, 2003 2 | 3 | Copyright (c) 2021 Andrey Penechko 4 | 5 | Permission is hereby granted, free of charge, to any person or organization 6 | obtaining a copy of the software and accompanying documentation covered by 7 | this license (the "Software") to use, reproduce, display, distribute, 8 | execute, and transmit the Software, and to prepare derivative works of the 9 | Software, and to permit third-parties to whom the Software is furnished to 10 | do so, all subject to the following: 11 | 12 | The copyright notices in the Software and this entire statement, including 13 | the above license grant, this restriction and the following disclaimer, 14 | must be included in all copies of the Software, in whole or in part, and 15 | all derivative works of the Software, unless such copies or derivative 16 | works are solely in the form of machine-executable object code generated by 17 | a source language processor. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 22 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 23 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 24 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /host/deps/enet.d: -------------------------------------------------------------------------------- 1 | module deps.enet; 2 | extern(C): 3 | void enet_address_get_host(); 4 | void enet_address_get_host_ip(); 5 | void enet_address_set_host(); 6 | void enet_address_set_host_ip(); 7 | void enet_crc32(); 8 | void enet_deinitialize(); 9 | void enet_host_bandwidth_limit(); 10 | void enet_host_broadcast(); 11 | void enet_host_channel_limit(); 12 | void enet_host_check_events(); 13 | void enet_host_compress(); 14 | void enet_host_compress_with_range_coder(); 15 | void enet_host_connect(); 16 | void enet_host_create(); 17 | void enet_host_destroy(); 18 | void enet_host_flush(); 19 | void enet_host_service(); 20 | void enet_initialize(); 21 | void enet_initialize_with_callbacks(); 22 | void enet_linked_version(); 23 | void enet_packet_create(); 24 | void enet_packet_destroy(); 25 | void enet_packet_resize(); 26 | void enet_peer_disconnect(); 27 | void enet_peer_disconnect_later(); 28 | void enet_peer_disconnect_now(); 29 | void enet_peer_ping(); 30 | void enet_peer_ping_interval(); 31 | void enet_peer_receive(); 32 | void enet_peer_reset(); 33 | void enet_peer_send(); 34 | void enet_peer_throttle_configure(); 35 | void enet_peer_timeout(); 36 | void enet_range_coder_compress(); 37 | void enet_range_coder_create(); 38 | void enet_range_coder_decompress(); 39 | void enet_range_coder_destroy(); 40 | void enet_socket_accept(); 41 | void enet_socket_bind(); 42 | void enet_socket_connect(); 43 | void enet_socket_create(); 44 | void enet_socket_destroy(); 45 | void enet_socket_get_address(); 46 | void enet_socket_get_option(); 47 | void enet_socket_listen(); 48 | void enet_socket_receive(); 49 | void enet_socket_send(); 50 | void enet_socket_set_option(); 51 | void enet_socket_shutdown(); 52 | void enet_socket_wait(); 53 | void enet_socketset_select(); 54 | void enet_time_get(); 55 | void enet_time_set(); 56 | -------------------------------------------------------------------------------- /host/deps/shaderc.d: -------------------------------------------------------------------------------- 1 | module deps.shaderc; 2 | extern(C): 3 | 4 | void shaderc_compiler_initialize(); 5 | void shaderc_compiler_release(); 6 | void shaderc_compile_options_initialize(); 7 | void shaderc_compile_options_clone(); 8 | void shaderc_compile_options_release(); 9 | void shaderc_compile_options_add_macro_definition(); 10 | void shaderc_compile_options_set_source_language(); 11 | void shaderc_compile_options_set_generate_debug_info(); 12 | void shaderc_compile_options_set_optimization_level(); 13 | void shaderc_compile_options_set_forced_version_profile(); 14 | void shaderc_compile_options_set_include_callbacks(); 15 | void shaderc_compile_options_set_suppress_warnings(); 16 | void shaderc_compile_options_set_target_env(); 17 | void shaderc_compile_options_set_target_spirv(); 18 | void shaderc_compile_options_set_warnings_as_errors(); 19 | void shaderc_compile_options_set_limit(); 20 | void shaderc_compile_options_set_auto_bind_uniforms(); 21 | void shaderc_compile_options_set_auto_combined_image_sampler(); 22 | void shaderc_compile_options_set_hlsl_io_mapping(); 23 | void shaderc_compile_options_set_hlsl_offsets(); 24 | void shaderc_compile_options_set_binding_base(); 25 | void shaderc_compile_options_set_binding_base_for_stage(); 26 | void shaderc_compile_options_set_auto_map_locations(); 27 | void shaderc_compile_options_set_hlsl_register_set_and_binding_for_stage(); 28 | void shaderc_compile_options_set_hlsl_register_set_and_binding(); 29 | void shaderc_compile_options_set_hlsl_functionality1(); 30 | void shaderc_compile_options_set_invert_y(); 31 | void shaderc_compile_options_set_nan_clamp(); 32 | void shaderc_compile_into_spv(); 33 | void shaderc_compile_into_spv_assembly(); 34 | void shaderc_compile_into_preprocessed_text(); 35 | void shaderc_assemble_into_spv(); 36 | void shaderc_result_release(); 37 | void shaderc_result_get_length(); 38 | void shaderc_result_get_num_warnings(); 39 | void shaderc_result_get_num_errors(); 40 | void shaderc_result_get_compilation_status(); 41 | void shaderc_result_get_bytes(); 42 | void shaderc_result_get_error_message(); 43 | void shaderc_get_spv_version(); 44 | void shaderc_parse_version_profile(); 45 | -------------------------------------------------------------------------------- /host/deps/vma.d: -------------------------------------------------------------------------------- 1 | module deps.vma; 2 | 3 | extern(C): 4 | 5 | void vmaAllocateMemory(); 6 | void vmaAllocateMemoryForBuffer(); 7 | void vmaAllocateMemoryForImage(); 8 | void vmaAllocateMemoryPages(); 9 | void vmaBeginDefragmentation(); 10 | void vmaBeginDefragmentationPass(); 11 | void vmaBindBufferMemory(); 12 | void vmaBindBufferMemory2(); 13 | void vmaBindImageMemory(); 14 | void vmaBindImageMemory2(); 15 | void vmaCalculatePoolStatistics(); 16 | void vmaCalculateStatistics(); 17 | void vmaCalculateVirtualBlockStatistics(); 18 | void vmaCheckCorruption(); 19 | void vmaCheckPoolCorruption(); 20 | void vmaClearVirtualBlock(); 21 | void vmaCreateAliasingBuffer(); 22 | void vmaCreateAliasingImage(); 23 | void vmaCreateAllocator(); 24 | void vmaCreateBuffer(); 25 | void vmaCreateBufferWithAlignment(); 26 | void vmaCreateImage(); 27 | void vmaCreatePool(); 28 | void vmaCreateVirtualBlock(); 29 | void vmaDestroyAllocator(); 30 | void vmaDestroyBuffer(); 31 | void vmaDestroyImage(); 32 | void vmaDestroyPool(); 33 | void vmaDestroyVirtualBlock(); 34 | void vmaEndDefragmentation(); 35 | void vmaEndDefragmentationPass(); 36 | void vmaFindMemoryTypeIndex(); 37 | void vmaFindMemoryTypeIndexForBufferInfo(); 38 | void vmaFindMemoryTypeIndexForImageInfo(); 39 | void vmaFlushAllocation(); 40 | void vmaFlushAllocations(); 41 | void vmaFreeMemory(); 42 | void vmaFreeMemoryPages(); 43 | void vmaGetAllocationInfo(); 44 | void vmaGetAllocationMemoryProperties(); 45 | void vmaGetAllocatorInfo(); 46 | void vmaGetHeapBudgets(); 47 | void vmaGetMemoryProperties(); 48 | void vmaGetMemoryTypeProperties(); 49 | void vmaGetPhysicalDeviceProperties(); 50 | void vmaGetPoolName(); 51 | void vmaGetPoolStatistics(); 52 | void vmaGetVirtualAllocationInfo(); 53 | void vmaGetVirtualBlockStatistics(); 54 | void vmaInvalidateAllocation(); 55 | void vmaInvalidateAllocations(); 56 | void vmaIsVirtualBlockEmpty(); 57 | void vmaMapMemory(); 58 | void vmaSetAllocationName(); 59 | void vmaSetAllocationUserData(); 60 | void vmaSetCurrentFrameIndex(); 61 | void vmaSetPoolName(); 62 | void vmaSetVirtualAllocationUserData(); 63 | void vmaUnmapMemory(); 64 | void vmaVirtualAllocate(); 65 | void vmaVirtualFree(); 66 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | push: # test + build + release 4 | branches: [ master ] 5 | pull_request: # test + build 6 | branches: [ master ] 7 | release: # test + build + release 8 | types: [ published ] 9 | env: 10 | DC1: ldc-1.30.0 11 | DC2: dmd-2.101.0 12 | LINKFLAGS: -L/NODEFAULTLIB:libcmt -L/NODEFAULTLIB:libvcruntime 13 | LIBS: lib/liblz4_static.lib lib/glfw3.lib lib/enet64.lib lib/mdbx.lib lib/mimalloc-static.lib lib/shaderc_combined.lib lib/zstd_static.lib lib/TracyProfiler.lib lib/VulkanMemoryAllocator.lib lib/GameNetworkingSockets_s.lib lib/libprotobuf.lib lib/libcrypto.lib ntdll.lib User32.lib Advapi32.lib ws2_32.lib winmm.lib gdi32.lib msvcrt.lib crypt32.lib 14 | DEPS: -I=vox/source -I=host 15 | 16 | defaults: 17 | run: 18 | shell: bash 19 | 20 | jobs: 21 | build-ldc-debug: 22 | name: LDC debug 23 | runs-on: windows-latest 24 | steps: 25 | - uses: actions/checkout@v2 26 | with: 27 | submodules: 'true' 28 | - uses: dlang-community/setup-dlang@v1 29 | with: 30 | compiler: ${{ env.DC1 }} 31 | - name: Download lib.7z 32 | run: curl -OLs https://github.com/MrSmith33/voxelman2/releases/download/deps/lib.7z 33 | - name: Unpack lib.7z 34 | run: 7z x -ba -bso0 -bsp0 lib.7z 35 | - name: Try build ldc debug 36 | run: ldc2 -m64 -g -i host/main.d -of=bin/voxelman.exe $DEPS $LIBS $LINKFLAGS 37 | 38 | build-ldc-release: 39 | name: LDC release 40 | runs-on: windows-latest 41 | steps: 42 | - uses: actions/checkout@v2 43 | with: 44 | submodules: 'true' 45 | - uses: dlang-community/setup-dlang@v1 46 | with: 47 | compiler: ${{ env.DC1 }} 48 | - name: Download lib.7z 49 | run: curl -OLs https://github.com/MrSmith33/voxelman2/releases/download/deps/lib.7z 50 | - name: Unpack lib.7z 51 | run: 7z x -ba -bso0 -bsp0 lib.7z 52 | - name: Try build release 53 | run: ldc2 -m64 -O3 -release -boundscheck=off -enable-inlining -mcpu=native -flto=full -i -g host/main.d -of=bin/voxelman.exe $DEPS $LIBS $LINKFLAGS 54 | 55 | build-dmd: 56 | name: DMD debug 57 | runs-on: windows-latest 58 | steps: 59 | - uses: actions/checkout@v2 60 | with: 61 | submodules: 'true' 62 | - uses: dlang-community/setup-dlang@v1 63 | with: 64 | compiler: ${{ env.DC2 }} 65 | - name: Download libs 66 | run: | 67 | curl -OLs https://github.com/MrSmith33/voxelman2/releases/download/deps/lib.7z 68 | 7z x -ba -bso0 -bsp0 lib.7z 69 | - name: Try build 70 | run: dmd -m64 -g -i host/main.d -of=bin/voxelman.exe $DEPS $LIBS $LINKFLAGS 71 | -------------------------------------------------------------------------------- /plugins/core/src/core/kernel32.vx: -------------------------------------------------------------------------------- 1 | module core.kernel32; 2 | @extern(module, "kernel32"): 3 | 4 | u32 GetLastError(); 5 | 6 | u32 GetCurrentThreadId(); 7 | noreturn ExitProcess(u32 uExitCode); 8 | noreturn ExitThread(u32 uExitCode); 9 | u64 GetTickCount64(); 10 | void QueryPerformanceCounter(i64* performanceCount); 11 | void QueryPerformanceFrequency(i64* frequency); 12 | void Sleep(u32 milliseconds); 13 | 14 | bool SetConsoleOutputCP(u32); 15 | 16 | u8 WriteConsoleA( 17 | void* hConsoleOutput, 18 | u8* lpBuffer, 19 | u32 nNumberOfCharsToWrite, 20 | u32* lpNumberOfCharsWritten, 21 | void* lpReserved 22 | ); 23 | 24 | bool GetFileSizeEx(void* hFile, i64* lpFileSize); 25 | 26 | void* CreateFileA( 27 | u8* lpFileName, 28 | u32 dwDesiredAccess, 29 | u32 dwShareMode, 30 | void* lpSecurityAttributes, 31 | u32 dwCreationDisposition, 32 | u32 dwFlagsAndAttributes, 33 | void* hTemplateFile 34 | ); 35 | 36 | bool CloseHandle(void*); 37 | 38 | bool ReadFile( 39 | void* hFile, 40 | u8* lpBuffer, 41 | u32 nNumberOfBytesToRead, 42 | u32* lpNumberOfBytesRead, 43 | void* lpOverlapped 44 | ); 45 | 46 | bool WriteFile( 47 | void* hFile, 48 | u8* lpBuffer, 49 | u32 nNumberOfCharsToWrite, 50 | u32* lpNumberOfCharsWritten, 51 | void* lpOverlapped 52 | ); 53 | 54 | void* GetStdHandle(u32 nStdHandle); 55 | 56 | 57 | enum u32 STD_INPUT_HANDLE = 0xFFFFFFF6; 58 | enum u32 STD_OUTPUT_HANDLE = 0xFFFFFFF5; 59 | enum u32 STD_ERROR_HANDLE = 0xFFFFFFF4; 60 | 61 | enum u32 FILE_SHARE_READ = 0x00000001; 62 | enum u32 FILE_SHARE_WRITE = 0x00000002; 63 | enum u32 FILE_SHARE_DELETE = 0x00000004; 64 | enum u32 GENERIC_READ = 0x80000000; 65 | 66 | enum u32 CREATE_NEW = 1; 67 | enum u32 CREATE_ALWAYS = 2; 68 | enum u32 OPEN_EXISTING = 3; 69 | enum u32 OPEN_ALWAYS = 4; 70 | enum u32 TRUNCATE_EXISTING = 5; 71 | 72 | enum u32 FILE_FLAG_OVERLAPPED = 0x40000000; 73 | enum u32 FILE_ATTRIBUTE_NORMAL = 0x00000080; 74 | enum u32 INVALID_FILE_ATTRIBUTES = 0xFFFFFFFF; 75 | enum u32 INVALID_FILE_SIZE = 0xFFFFFFFF; 76 | enum u32 INVALID_SET_FILE_POINTER = 0xFFFFFFFF; 77 | 78 | enum void* INVALID_HANDLE_VALUE = 0XFFFFFFFFFFFFFFFF; 79 | 80 | alias HANDLE = void*; 81 | HANDLE GetProcessHeap(); 82 | void* HeapAlloc(HANDLE heap, u32 flags, u64 bytes); 83 | bool HeapFree(HANDLE heap, u32 flags, void* mem); 84 | void RtlCopyMemory(void* destination, void* source, u64 length); 85 | 86 | enum : u32 { 87 | HEAP_GENERATE_EXCEPTIONS = 0x00000004, 88 | HEAP_NO_SERIALIZE = 0x00000001, 89 | HEAP_ZERO_MEMORY = 0x00000008, 90 | } 91 | 92 | void* LocalFree(void* hMem); 93 | 94 | u32 FormatMessageA( 95 | u32 dwFlags, 96 | u8* lpSource, 97 | u32 dwMessageId, 98 | u32 dwLanguageId, 99 | u8** lpBuffer, 100 | u32 nSize, 101 | void* Arguments, 102 | ); 103 | 104 | enum u32 FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100; 105 | enum u32 FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200; 106 | enum u32 FORMAT_MESSAGE_FROM_STRING = 0x00000400; 107 | enum u32 FORMAT_MESSAGE_FROM_HMODULE = 0x00000800; 108 | enum u32 FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000; 109 | enum u32 FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000; 110 | enum u32 FORMAT_MESSAGE_MAX_WIDTH_MASK = 0x000000FF; 111 | -------------------------------------------------------------------------------- /host/deps/mdbx.d: -------------------------------------------------------------------------------- 1 | module deps.mdbx; 2 | extern(C): 3 | void mdbx_build(); 4 | void mdbx_canary_get(); 5 | void mdbx_canary_put(); 6 | void mdbx_cmp(); 7 | void mdbx_cursor_bind(); 8 | void mdbx_cursor_close(); 9 | void mdbx_cursor_copy(); 10 | void mdbx_cursor_count(); 11 | void mdbx_cursor_create(); 12 | void mdbx_cursor_dbi(); 13 | void mdbx_cursor_del(); 14 | void mdbx_cursor_eof(); 15 | void mdbx_cursor_get(); 16 | void mdbx_cursor_get_userctx(); 17 | void mdbx_cursor_on_first(); 18 | void mdbx_cursor_on_last(); 19 | void mdbx_cursor_open(); 20 | void mdbx_cursor_put(); 21 | void mdbx_cursor_renew(); 22 | void mdbx_cursor_set_userctx(); 23 | void mdbx_cursor_txn(); 24 | void mdbx_dbi_close(); 25 | void mdbx_dbi_dupsort_depthmask(); 26 | void mdbx_dbi_flags(); 27 | void mdbx_dbi_flags_ex(); 28 | void mdbx_dbi_open(); 29 | void mdbx_dbi_open_ex(); 30 | void mdbx_dbi_sequence(); 31 | void mdbx_dbi_stat(); 32 | void mdbx_dcmp(); 33 | void mdbx_default_pagesize(); 34 | void mdbx_del(); 35 | void mdbx_double_from_key(); 36 | void mdbx_drop(); 37 | void mdbx_dump_val(); 38 | void mdbx_env_close(); 39 | void mdbx_env_close_ex(); 40 | void mdbx_env_copy(); 41 | void mdbx_env_copy2fd(); 42 | void mdbx_env_create(); 43 | void mdbx_env_delete(); 44 | void mdbx_env_get_fd(); 45 | void mdbx_env_get_flags(); 46 | void mdbx_env_get_hsr(); 47 | void mdbx_env_get_maxdbs(); 48 | void mdbx_env_get_maxkeysize(); 49 | void mdbx_env_get_maxkeysize_ex(); 50 | void mdbx_env_get_maxreaders(); 51 | void mdbx_env_get_maxvalsize_ex(); 52 | void mdbx_env_get_option(); 53 | void mdbx_env_get_path(); 54 | void mdbx_env_get_userctx(); 55 | void mdbx_env_info(); 56 | void mdbx_env_info_ex(); 57 | void mdbx_env_open(); 58 | void mdbx_env_open_for_recovery(); 59 | void mdbx_env_pgwalk(); 60 | void mdbx_env_set_assert(); 61 | void mdbx_env_set_flags(); 62 | void mdbx_env_set_geometry(); 63 | void mdbx_env_set_hsr(); 64 | void mdbx_env_set_mapsize(); 65 | void mdbx_env_set_maxdbs(); 66 | void mdbx_env_set_maxreaders(); 67 | void mdbx_env_set_option(); 68 | void mdbx_env_set_syncbytes(); 69 | void mdbx_env_set_syncperiod(); 70 | void mdbx_env_set_userctx(); 71 | void mdbx_env_stat(); 72 | void mdbx_env_stat_ex(); 73 | void mdbx_env_sync(); 74 | void mdbx_env_sync_ex(); 75 | void mdbx_env_sync_poll(); 76 | void mdbx_env_turn_for_recovery(); 77 | void mdbx_estimate_distance(); 78 | void mdbx_estimate_move(); 79 | void mdbx_estimate_range(); 80 | void mdbx_float_from_key(); 81 | void mdbx_get(); 82 | void mdbx_get_datacmp(); 83 | void mdbx_get_equal_or_great(); 84 | void mdbx_get_ex(); 85 | void mdbx_get_keycmp(); 86 | void mdbx_int32_from_key(); 87 | void mdbx_int64_from_key(); 88 | void mdbx_is_dirty(); 89 | void mdbx_is_readahead_reasonable(); 90 | void mdbx_jsonInteger_from_key(); 91 | void mdbx_key_from_double(); 92 | void mdbx_key_from_float(); 93 | void mdbx_key_from_int32(); 94 | void mdbx_key_from_int64(); 95 | void mdbx_key_from_jsonInteger(); 96 | void mdbx_key_from_ptrdouble(); 97 | void mdbx_key_from_ptrfloat(); 98 | void mdbx_liberr2str(); 99 | void mdbx_limits_dbsize_max(); 100 | void mdbx_limits_dbsize_min(); 101 | void mdbx_limits_keysize_max(); 102 | void mdbx_limits_pgsize_max(); 103 | void mdbx_limits_pgsize_min(); 104 | void mdbx_limits_txnsize_max(); 105 | void mdbx_limits_valsize_max(); 106 | void mdbx_panic(); 107 | void mdbx_put(); 108 | void mdbx_reader_check(); 109 | void mdbx_reader_list(); 110 | void mdbx_replace(); 111 | void mdbx_replace_ex(); 112 | void mdbx_setup_debug(); 113 | void mdbx_strerror(); 114 | void mdbx_thread_register(); 115 | void mdbx_thread_unregister(); 116 | void mdbx_txn_abort(); 117 | void mdbx_txn_begin(); 118 | void mdbx_txn_begin_ex(); 119 | void mdbx_txn_break(); 120 | void mdbx_txn_commit(); 121 | void mdbx_txn_commit_ex(); 122 | void mdbx_txn_env(); 123 | void mdbx_txn_flags(); 124 | void mdbx_txn_get_userctx(); 125 | void mdbx_txn_id(); 126 | void mdbx_txn_info(); 127 | void mdbx_txn_lock(); 128 | void mdbx_txn_renew(); 129 | void mdbx_txn_reset(); 130 | void mdbx_txn_set_userctx(); 131 | void mdbx_txn_straggler(); 132 | void mdbx_txn_unlock(); 133 | void mdbx_version(); 134 | -------------------------------------------------------------------------------- /plugins/core/src/core/enet.vx: -------------------------------------------------------------------------------- 1 | module core.enet; 2 | @extern(module, "enet"): 3 | 4 | struct ENetHost; 5 | struct ENetPacket; 6 | struct ENetPeer; 7 | struct ENetAddress; 8 | 9 | alias ENetSocket = u64; 10 | alias ENetVersion = u32; 11 | 12 | alias ENetSocketType = i32; 13 | enum : ENetSocketType 14 | { 15 | ENET_SOCKET_TYPE_STREAM = 1, 16 | ENET_SOCKET_TYPE_DATAGRAM = 2, 17 | } 18 | 19 | alias ENetEventType = i32; 20 | enum : ENetEventType 21 | { 22 | ENET_EVENT_TYPE_NONE = 0, 23 | ENET_EVENT_TYPE_CONNECT = 1, 24 | ENET_EVENT_TYPE_DISCONNECT = 2, 25 | ENET_EVENT_TYPE_RECEIVE = 3, 26 | } 27 | 28 | alias ENetSocketOption = i32; 29 | enum : ENetSocketOption 30 | { 31 | ENET_SOCKOPT_NONBLOCK = 1, 32 | ENET_SOCKOPT_BROADCAST = 2, 33 | ENET_SOCKOPT_RCVBUF = 3, 34 | ENET_SOCKOPT_SNDBUF = 4, 35 | ENET_SOCKOPT_REUSEADDR = 5, 36 | ENET_SOCKOPT_RCVTIMEO = 6, 37 | ENET_SOCKOPT_SNDTIMEO = 7, 38 | ENET_SOCKOPT_ERROR = 8, 39 | } 40 | 41 | struct ENetEvent 42 | { 43 | ENetEventType type; 44 | ENetPeer* peer; 45 | u8 channelID; 46 | u32 data; 47 | ENetPacket* packet; 48 | } 49 | 50 | struct ENetCallbacks 51 | { 52 | void* function(u64 size) malloc; 53 | void function(void* memory) free; 54 | void function() no_memory; 55 | } 56 | 57 | struct ENetBuffer 58 | { 59 | u64 dataLength; 60 | void* data; 61 | } 62 | 63 | alias ENetSocketShutdown = i32; 64 | enum : ENetSocketShutdown 65 | { 66 | ENET_SOCKET_SHUTDOWN_READ = 0, 67 | ENET_SOCKET_SHUTDOWN_WRITE = 1, 68 | ENET_SOCKET_SHUTDOWN_READ_WRITE = 2 69 | } 70 | 71 | enum ENET_HOST_ANY = 0; 72 | enum ENET_HOST_BROADCAST = 0xFFFFFFFF; 73 | enum ENET_PORT_ANY = 0; 74 | 75 | enum FD_SETSIZE = 64; 76 | 77 | struct ENetSocketSet 78 | { 79 | u32 fd_count; 80 | ENetSocket[FD_SETSIZE] fd_array; 81 | } 82 | 83 | struct ENetCompressor 84 | { 85 | void* context; 86 | u64 function(void* context, ENetBuffer* inBuffers, u64 inBufferCount, u64 inLimit, u8* outData, u64 outLimit) compress; 87 | u64 function(void* context, u8* inData, u64 inLimit, u8* outData, u64 outLimit) decompress; 88 | void function(void* context) destroy; 89 | } 90 | 91 | i32 enet_initialize(); 92 | i32 enet_initialize_with_callbacks(ENetVersion version_, ENetCallbacks* inits); 93 | void enet_deinitialize(); 94 | ENetVersion enet_linked_version(); 95 | 96 | u32 enet_crc32(ENetBuffer*, u64); 97 | 98 | u32 enet_time_get(); 99 | void enet_time_set(u32); 100 | 101 | i32 enet_address_get_host(ENetAddress* address, u8* hostName, u64 nameLength); 102 | i32 enet_address_get_host_ip(ENetAddress* address, u8* hostName, u64 nameLength); 103 | i32 enet_address_set_host(ENetAddress* address, u8* hostName); 104 | i32 enet_address_set_host_ip(ENetAddress* address, u8* hostName); 105 | 106 | ENetHost* enet_host_create(ENetAddress* address, u64, u64, u32, u32); 107 | void enet_host_destroy(ENetHost*); 108 | void enet_host_bandwidth_limit(ENetHost*, u32, u32); 109 | void enet_host_broadcast(ENetHost*, u8, ENetPacket*); 110 | void enet_host_channel_limit(ENetHost*, u64); 111 | i32 enet_host_check_events(ENetHost*, ENetEvent*); 112 | void enet_host_compress(ENetHost*, ENetCompressor*); 113 | i32 enet_host_compress_with_range_coder(ENetHost* host); 114 | ENetPeer* enet_host_connect(ENetHost*, ENetAddress* address, u64, u32); 115 | void enet_host_flush(ENetHost*); 116 | i32 enet_host_service(ENetHost*, ENetEvent*, u32); 117 | 118 | ENetPacket* enet_packet_create(void*, u64, u32); 119 | void enet_packet_destroy(ENetPacket*); 120 | i32 enet_packet_resize (ENetPacket*, u64); 121 | 122 | void enet_peer_disconnect(ENetPeer*, u32); 123 | void enet_peer_disconnect_later(ENetPeer*, u32); 124 | void enet_peer_disconnect_now(ENetPeer*, u32); 125 | void enet_peer_ping(ENetPeer*); 126 | void enet_peer_ping_interval(ENetPeer*, u32); 127 | ENetPacket* enet_peer_receive(ENetPeer*, u8* channelID); 128 | void enet_peer_reset(ENetPeer*); 129 | i32 enet_peer_send(ENetPeer*, u8, ENetPacket*); 130 | void enet_peer_throttle_configure(ENetPeer*, u32, u32, u32); 131 | void enet_peer_timeout(ENetPeer*, u32, u32, u32); 132 | 133 | void* enet_range_coder_create(); 134 | void enet_range_coder_destroy(void*); 135 | u64 enet_range_coder_compress(void*, ENetBuffer*, u64, u64, u8*, u64); 136 | u64 enet_range_coder_decompress(void*, u8*, u64, u8*, u64); 137 | 138 | i32 enet_socket_connect(ENetSocket, ENetAddress*); 139 | void enet_socket_destroy(ENetSocket); 140 | ENetSocket enet_socket_accept(ENetSocket, ENetAddress* address); 141 | i32 enet_socket_bind(ENetSocket, ENetAddress*); 142 | ENetSocket enet_socket_create(ENetSocketType); 143 | i32 enet_socket_get_address(ENetSocket, ENetAddress*); 144 | i32 enet_socket_get_option(ENetSocket, ENetSocketOption, i32*); 145 | i32 enet_socket_listen(ENetSocket, i32); 146 | i32 enet_socket_receive(ENetSocket, ENetAddress*, ENetBuffer*, u64); 147 | i32 enet_socket_send(ENetSocket, ENetAddress*, ENetBuffer*, u64); 148 | i32 enet_socket_set_option(ENetSocket, ENetSocketOption, i32); 149 | i32 enet_socket_shutdown(ENetSocket, ENetSocketShutdown); 150 | i32 enet_socket_wait(ENetSocket, u32*, u32); 151 | i32 enet_socketset_select(ENetSocket, ENetSocketSet*, ENetSocketSet*, u32); 152 | -------------------------------------------------------------------------------- /host/deps/game_networking_sockets.d: -------------------------------------------------------------------------------- 1 | module deps.game_networking_sockets; 2 | extern(C): 3 | 4 | // List obtained from running `dumpbin /exports GameNetworkingSockets.dll` 5 | void GameNetworkingSockets_Init(); 6 | void GameNetworkingSockets_Kill(); 7 | void SteamAPI_ISteamNetworkingSockets_AcceptConnection(); 8 | void SteamAPI_ISteamNetworkingSockets_CloseConnection(); 9 | void SteamAPI_ISteamNetworkingSockets_CloseListenSocket(); 10 | void SteamAPI_ISteamNetworkingSockets_ConfigureConnectionLanes(); 11 | void SteamAPI_ISteamNetworkingSockets_ConnectByIPAddress(); 12 | void SteamAPI_ISteamNetworkingSockets_CreateCustomSignaling(); 13 | void SteamAPI_ISteamNetworkingSockets_CreateListenSocketIP(); 14 | void SteamAPI_ISteamNetworkingSockets_CreatePollGroup(); 15 | void SteamAPI_ISteamNetworkingSockets_CreateSocketPair(); 16 | void SteamAPI_ISteamNetworkingSockets_DestroyPollGroup(); 17 | void SteamAPI_ISteamNetworkingSockets_FlushMessagesOnConnection(); 18 | void SteamAPI_ISteamNetworkingSockets_GetAuthenticationStatus(); 19 | void SteamAPI_ISteamNetworkingSockets_GetCertificateRequest(); 20 | void SteamAPI_ISteamNetworkingSockets_GetConnectionInfo(); 21 | void SteamAPI_ISteamNetworkingSockets_GetConnectionName(); 22 | void SteamAPI_ISteamNetworkingSockets_GetConnectionRealTimeStatus(); 23 | void SteamAPI_ISteamNetworkingSockets_GetConnectionUserData(); 24 | void SteamAPI_ISteamNetworkingSockets_GetDetailedConnectionStatus(); 25 | void SteamAPI_ISteamNetworkingSockets_GetIdentity(); 26 | void SteamAPI_ISteamNetworkingSockets_GetListenSocketAddress(); 27 | void SteamAPI_ISteamNetworkingSockets_InitAuthentication(); 28 | void SteamAPI_ISteamNetworkingSockets_ReceiveMessagesOnConnection(); 29 | void SteamAPI_ISteamNetworkingSockets_ReceiveMessagesOnPollGroup(); 30 | void SteamAPI_ISteamNetworkingSockets_ReceivedP2PCustomSignal2(); 31 | void SteamAPI_ISteamNetworkingSockets_RunCallbacks(); 32 | void SteamAPI_ISteamNetworkingSockets_SendMessageToConnection(); 33 | void SteamAPI_ISteamNetworkingSockets_SendMessages(); 34 | void SteamAPI_ISteamNetworkingSockets_SetCertificate(); 35 | void SteamAPI_ISteamNetworkingSockets_SetConnectionName(); 36 | void SteamAPI_ISteamNetworkingSockets_SetConnectionPollGroup(); 37 | void SteamAPI_ISteamNetworkingSockets_SetConnectionUserData(); 38 | void SteamAPI_ISteamNetworkingUtils_AllocateMessage(); 39 | void SteamAPI_ISteamNetworkingUtils_GetConfigValue(); 40 | void SteamAPI_ISteamNetworkingUtils_GetConfigValueInfo(); 41 | void SteamAPI_ISteamNetworkingUtils_GetLocalTimestamp(); 42 | void SteamAPI_ISteamNetworkingUtils_IterateGenericEditableConfigValues(); 43 | void SteamAPI_ISteamNetworkingUtils_SetConfigValue(); 44 | void SteamAPI_ISteamNetworkingUtils_SetConfigValueStruct(); 45 | void SteamAPI_ISteamNetworkingUtils_SetConnectionConfigValueFloat(); 46 | void SteamAPI_ISteamNetworkingUtils_SetConnectionConfigValueInt32(); 47 | void SteamAPI_ISteamNetworkingUtils_SetConnectionConfigValueString(); 48 | void SteamAPI_ISteamNetworkingUtils_SetDebugOutputFunction(); 49 | void SteamAPI_ISteamNetworkingUtils_SetGlobalCallback_SteamNetAuthenticationStatusChanged(); 50 | void SteamAPI_ISteamNetworkingUtils_SetGlobalCallback_SteamNetConnectionStatusChanged(); 51 | void SteamAPI_ISteamNetworkingUtils_SetGlobalCallback_SteamRelayNetworkStatusChanged(); 52 | void SteamAPI_ISteamNetworkingUtils_SetGlobalConfigValueFloat(); 53 | void SteamAPI_ISteamNetworkingUtils_SetGlobalConfigValueInt32(); 54 | void SteamAPI_ISteamNetworkingUtils_SetGlobalConfigValuePtr(); 55 | void SteamAPI_ISteamNetworkingUtils_SetGlobalConfigValueString(); 56 | void SteamAPI_SteamNetworkingIPAddr_Clear(); 57 | void SteamAPI_SteamNetworkingIPAddr_GetIPv4(); 58 | void SteamAPI_SteamNetworkingIPAddr_IsEqualTo(); 59 | void SteamAPI_SteamNetworkingIPAddr_IsIPv4(); 60 | void SteamAPI_SteamNetworkingIPAddr_IsIPv6AllZeros(); 61 | void SteamAPI_SteamNetworkingIPAddr_IsLocalHost(); 62 | void SteamAPI_SteamNetworkingIPAddr_ParseString(); 63 | void SteamAPI_SteamNetworkingIPAddr_SetIPv4(); 64 | void SteamAPI_SteamNetworkingIPAddr_SetIPv6(); 65 | void SteamAPI_SteamNetworkingIPAddr_SetIPv6LocalHost(); 66 | void SteamAPI_SteamNetworkingIPAddr_ToString(); 67 | void SteamAPI_SteamNetworkingIdentity_Clear(); 68 | void SteamAPI_SteamNetworkingIdentity_GetGenericBytes(); 69 | void SteamAPI_SteamNetworkingIdentity_GetGenericString(); 70 | void SteamAPI_SteamNetworkingIdentity_GetIPAddr(); 71 | void SteamAPI_SteamNetworkingIdentity_GetSteamID(); 72 | void SteamAPI_SteamNetworkingIdentity_GetSteamID64(); 73 | void SteamAPI_SteamNetworkingIdentity_IsEqualTo(); 74 | void SteamAPI_SteamNetworkingIdentity_IsInvalid(); 75 | void SteamAPI_SteamNetworkingIdentity_IsLocalHost(); 76 | void SteamAPI_SteamNetworkingIdentity_ParseString(); 77 | void SteamAPI_SteamNetworkingIdentity_SetGenericBytes(); 78 | void SteamAPI_SteamNetworkingIdentity_SetGenericString(); 79 | void SteamAPI_SteamNetworkingIdentity_SetIPAddr(); 80 | void SteamAPI_SteamNetworkingIdentity_SetLocalHost(); 81 | void SteamAPI_SteamNetworkingIdentity_SetSteamID(); 82 | void SteamAPI_SteamNetworkingIdentity_SetSteamID64(); 83 | void SteamAPI_SteamNetworkingIdentity_ToString(); 84 | void SteamAPI_SteamNetworkingMessage_t_Release(); 85 | void SteamAPI_SteamNetworkingSockets_v009(); 86 | void SteamAPI_SteamNetworkingUtils_v003(); 87 | void SteamNetworkingIPAddr_GetFakeIPType(); 88 | void SteamNetworkingIPAddr_ParseString(); 89 | void SteamNetworkingIPAddr_ToString(); 90 | void SteamNetworkingIdentity_ParseString(); 91 | void SteamNetworkingIdentity_ToString(); 92 | void SteamNetworkingMessages_LibV2(); 93 | void SteamNetworkingSockets_DefaultPreFormatDebugOutputHandler(); 94 | void SteamNetworkingSockets_LibV12(); 95 | void SteamNetworkingSockets_Poll(); 96 | void SteamNetworkingSockets_SetLockAcquiredCallback(); 97 | void SteamNetworkingSockets_SetLockHeldCallback(); 98 | void SteamNetworkingSockets_SetLockWaitWarningThreshold(); 99 | void SteamNetworkingSockets_SetManualPollMode(); 100 | void SteamNetworkingSockets_SetPreFormatDebugOutputHandler(); 101 | void SteamNetworkingUtils_LibV4(); 102 | -------------------------------------------------------------------------------- /plugins/core/src/core/vector.vx: -------------------------------------------------------------------------------- 1 | module core.vector; 2 | 3 | import core.format; 4 | import core.math; 5 | import core.utils; 6 | 7 | struct ivec2 { i32 x; i32 y; } 8 | struct uvec2 { u32 x; u32 y; } 9 | struct u16vec2 { u16 x; u16 y; } 10 | 11 | struct vec2 { f32 x; f32 y; } 12 | struct vec3 { f32 x; f32 y; f32 z; } 13 | struct vec3x { f32 x; f32 y; f32 z; f32 pad; } 14 | struct vec4 { f32 x; f32 y; f32 z; f32 w; } 15 | 16 | alias mat4 = f32[16]; 17 | 18 | f32 degtorad(f32 deg) { 19 | return deg / 180 * cast(f32)PI; 20 | } 21 | 22 | vec3 cross_vec3(vec3 a, vec3 b) { 23 | return vec3( 24 | (a.y * b.z) - (a.z * b.y), 25 | (a.z * b.x) - (a.x * b.z), 26 | (a.x * b.y) - (a.y * b.x), 27 | ); 28 | } 29 | 30 | vec2 add_vec2(vec2 a, vec2 b) { 31 | return vec2( 32 | a.x + b.x, 33 | a.y + b.y, 34 | ); 35 | } 36 | 37 | vec3 add_vec3(vec3 a, vec3 b) { 38 | return vec3( 39 | a.x + b.x, 40 | a.y + b.y, 41 | a.z + b.z, 42 | ); 43 | } 44 | 45 | vec3 sub_vec3(vec3 a, vec3 b) { 46 | return vec3( 47 | a.x - b.x, 48 | a.y - b.y, 49 | a.z - b.z, 50 | ); 51 | } 52 | 53 | f32 dot_vec3(vec3 a, vec3 b) { 54 | return a.x * b.x + a.y * b.y + a.z * b.z; 55 | } 56 | 57 | f32 length_sqr_vec3(vec3 v) { 58 | return v.x * v.x + v.y * v.y + v.z * v.z; 59 | } 60 | 61 | f32 length_vec3(vec3 v) { 62 | return sqrt_f32(v.x * v.x + v.y * v.y + v.z * v.z); 63 | } 64 | 65 | vec3 depth_div(vec4 v) { 66 | return vec3(v.x / v.w, v.y / v.w, v.z / v.w); 67 | } 68 | 69 | vec4 mult_mat4_vec4(mat4 m, vec4 v) { 70 | return vec4( 71 | m[0] * v.x + m[1] * v.y + m[2] * v.z + m[3] * v.w, 72 | m[4] * v.x + m[5] * v.y + m[6] * v.z + m[7] * v.w, 73 | m[8] * v.x + m[9] * v.y + m[10] * v.z + m[11] * v.w, 74 | m[12] * v.x + m[13] * v.y + m[14] * v.z + m[15] * v.w, 75 | ); 76 | } 77 | 78 | vec3 normalized_vec3(vec3 v) { 79 | f32 length_sqr = length_sqr_vec3(v); 80 | //if (length_sqr > 0.0) // until float comparison with a constant is implemented in the compiler 81 | //{ 82 | f32 coef = 1 / sqrt_f32(length_sqr); 83 | return vec3(v.x * coef, v.y * coef, v.z * coef); 84 | //} 85 | //else 86 | //{ 87 | // return v; 88 | //} 89 | } 90 | 91 | mat4 identityMatrix() 92 | { 93 | mat4 res; 94 | 95 | res[ 0] = 1.0; 96 | res[ 1] = 0.0; 97 | res[ 2] = 0.0; 98 | res[ 3] = 0.0; 99 | 100 | res[ 4] = 0.0; 101 | res[ 5] = 1.0; 102 | res[ 6] = 0.0; 103 | res[ 7] = 0.0; 104 | 105 | res[ 8] = 0.0; 106 | res[ 9] = 0.0; 107 | res[10] = 1.0; 108 | res[11] = 0.0; 109 | 110 | res[12] = 0.0; 111 | res[13] = 0.0; 112 | res[14] = 0.0; 113 | res[15] = 1.0; 114 | 115 | return res; 116 | } 117 | 118 | void print_mat4(mat4 m) { 119 | writeln("(", m[ 0], " ", m[ 1], " ", m[ 2], " ", m[ 3]); 120 | writeln(" ", m[ 4], " ", m[ 5], " ", m[ 6], " ", m[ 7]); 121 | writeln(" ", m[ 8], " ", m[ 9], " ", m[10], " ", m[11]); 122 | writeln(" ", m[12], " ", m[13], " ", m[14], " ", m[15], ")"); 123 | } 124 | 125 | void print_vec3(vec3 v) { 126 | writeln("(", v.x, " ", v.y, " ", v.z, ")"); 127 | } 128 | 129 | void print_vec4(vec4 v) { 130 | writeln("(", v.x, " ", v.y, " ", v.z, " ", v.w, ")"); 131 | } 132 | 133 | // up is the direction of cameras +Y axis 134 | mat4 lookAtMatrix(vec3 camera_pos, vec3 target, vec3 up) 135 | { 136 | mat4 res; 137 | 138 | // this is for right-handed system 139 | // matrix is filled by rows 140 | // we calculate each camera space axis as a vector in the world space 141 | // for example if camera looks up (-Y in world space) then camera space forward vector (+Z) must be (0 -1 0) in world space 142 | // then matrix will perform dot product of input vertex with forward vector, giving us positive value if it is in front of the camera 143 | // this scalar is the value of the Z camera space coordinates. Same with the rest of components. 144 | vec3 z_axis = sub_vec3(target, camera_pos).normalized_vec3; 145 | vec3 x_axis = cross_vec3(up.normalized_vec3, z_axis).normalized_vec3; 146 | vec3 y_axis = cross_vec3(z_axis, x_axis); 147 | 148 | res[ 0] = x_axis.x; 149 | res[ 1] = x_axis.y; 150 | res[ 2] = x_axis.z; 151 | res[ 3] = -dot_vec3(x_axis, camera_pos); 152 | 153 | res[ 4] = y_axis.x; 154 | res[ 5] = y_axis.y; 155 | res[ 6] = y_axis.z; 156 | res[ 7] = -dot_vec3(y_axis, camera_pos); 157 | 158 | res[ 8] = z_axis.x; 159 | res[ 9] = z_axis.y; 160 | res[10] = z_axis.z; 161 | res[11] = -dot_vec3(z_axis, camera_pos); 162 | 163 | res[12] = 0; 164 | res[13] = 0; 165 | res[14] = 0; 166 | res[15] = 1; 167 | 168 | //vec3 offset = vec3(-dot_vec3(x_axis, camera_pos), -dot_vec3(y_axis, camera_pos), -dot_vec3(z_axis, camera_pos)); 169 | //print_vec3(x_axis); 170 | //print_vec3(y_axis); 171 | //print_vec3(z_axis); 172 | //writeln; 173 | //print_vec3(camera_pos); 174 | //print_vec3(offset); 175 | 176 | return res; 177 | } 178 | 179 | /// inv_aspect = height / width 180 | mat4 perspectiveMatrix(f32 fov_y, f32 inv_aspect, f32 near, f32 far) 181 | { 182 | mat4 res; 183 | 184 | f32 cot_half_fov_y = cot_f32(0.5_f32 * fov_y); 185 | f32 inv_far_near = 1 / (far - near); 186 | 187 | res[ 0] = inv_aspect * cot_half_fov_y; 188 | res[ 1] = 0; 189 | res[ 2] = 0; 190 | res[ 3] = 0; 191 | 192 | res[ 4] = 0; 193 | res[ 5] = cot_half_fov_y; 194 | res[ 6] = 0; 195 | res[ 7] = 0; 196 | 197 | res[ 8] = 0; 198 | res[ 9] = 0; 199 | 200 | // Infinite Far, inverse Z (best) 201 | res[10] = 0; 202 | res[11] = near; 203 | 204 | // Infinite Far, non-inverse Z 205 | //res[10] = 1; 206 | //res[11] = -near; 207 | 208 | // Finite Far, non-inverse Z 209 | //res[10] = far * inv_far_near; 210 | //res[11] = -near * far * inv_far_near; 211 | 212 | // Finite Far, inverse Z 213 | // res[10] = -near * inv_far_near; 214 | // res[11] = (near * far) * inv_far_near; 215 | 216 | res[12] = 0; 217 | res[13] = 0; 218 | res[14] = 1; 219 | res[15] = 0; 220 | 221 | return res; 222 | } 223 | 224 | mat4 rotationMatrixX(f32 angle) 225 | { 226 | mat4 res; 227 | 228 | f32 s = sin_f32(angle); 229 | f32 c = cos_f32(angle); 230 | 231 | res[ 0] = 1; res[ 1] = 0; res[ 2] = 0; res[ 3] = 0; 232 | res[ 4] = 0; res[ 5] = c; res[ 6] =-s; res[ 7] = 0; 233 | res[ 8] = 0; res[ 9] = s; res[10] = c; res[11] = 0; 234 | res[12] = 0; res[13] = 0; res[14] = 0; res[15] = 1; 235 | 236 | return res; 237 | } 238 | 239 | mat4 rotationMatrixY(f32 angle) 240 | { 241 | mat4 res; 242 | 243 | f32 s = sin_f32(angle); 244 | f32 c = cos_f32(angle); 245 | 246 | res[ 0] = c; res[ 1] = 0; res[ 2] = s; res[ 3] = 0; 247 | res[ 4] = 0; res[ 5] = 1; res[ 6] = 0; res[ 7] = 0; 248 | res[ 8] =-s; res[ 9] = 0; res[10] = c; res[11] = 0; 249 | res[12] = 0; res[13] = 0; res[14] = 0; res[15] = 1; 250 | 251 | return res; 252 | } 253 | 254 | mat4 rotationMatrixZ(f32 angle) 255 | { 256 | mat4 res; 257 | 258 | f32 s = sin_f32(angle); 259 | f32 c = cos_f32(angle); 260 | 261 | res[ 0] = c; res[ 1] =-s; res[ 2] = 0; res[ 3] = 0; 262 | res[ 4] = s; res[ 5] = c; res[ 6] = 0; res[ 7] = 0; 263 | res[ 8] = 0; res[ 9] = 0; res[10] = 1; res[11] = 0; 264 | res[12] = 0; res[13] = 0; res[14] = 0; res[15] = 1; 265 | 266 | return res; 267 | } 268 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Voxelman v2 2 | 3 | ![CI](https://github.com/MrSmith33/voxelman2/workflows/CI/badge.svg?branch=master&event=push) 4 | 5 | Voxel engine focused on: 6 | - Modding via embedded Vox language compiler, which offers quick recompilation 7 | - High performance through the use of ECS, multithreading and Vulkan API, mdbx database 8 | - Client/Server architecture 9 | 10 | ## Status 11 | 12 | WIP rewrite of voxelman 13 | 14 | Currently following [Vulkan tutorial](https://vulkan-tutorial.com) 15 | 16 | ## Profiling 17 | 18 | Pass `--tracy` flag to the executable to enable tracy. Run the voxelman application as an administrator to get more profiling information. Start Tracy profiler and connect to the application. Tracy is disabled by default as it affects startup time. 19 | 20 | ## Links 21 | 22 | * [Voxelman v1](https://github.com/MrSmith33/voxelman) 23 | * [Vox programming language](https://github.com/MrSmith33/vox) 24 | 25 | ## Conventions 26 | 27 | * Right-handed coordinate system 28 | * Column vectors that are multiplied as `P⋅V⋅M⋅v` 29 | 30 | ## Getting deps 31 | 32 | `.dll` files must be placed into `bin/` directory\ 33 | `.lib` files must be placed into `lib/` directory 34 | 35 | Download pre-built dependencies from: 36 | * https://github.com/MrSmith33/voxelman2/releases/tag/deps 37 | 38 | Or build/download them yourself: 39 | 40 |
41 | Instructions 42 | 43 | * GLFW3 v3.3.8 44 | * [glfw-3.3.8.bin.WIN64.zip](https://github.com/glfw/glfw/releases/download/3.3.8/glfw-3.3.8.bin.WIN64.zip)`/glfw-3.3.8.bin.WIN64/lib-vc2019/glfw3.lib` 45 | * Enet v1.3.17 46 | * [enet-1.3.17.tar.gz](http://enet.bespin.org/download/enet-1.3.17.tar.gz)`/enet-1.3.17/enet64.lib` 47 | * LZ4 v1.9.4: [lz4-1.9.4.zip](https://github.com/lz4/lz4/archive/refs/tags/v1.9.4.zip) 48 | * The file from the release causes `liblz4_static.lib(lz4.o) : error LNK2001: unresolved external symbol ___chkstk_ms` when building with `dmd`, so we build from sources. 49 | * Open `lz4-1.9.4/build/VS2017/lz4.sln` with VS2019 (Release x64 config) 50 | * Optionally disable debug info (`Debug Information format`: `/Zi` -> `None`). Reduces static lib size. 51 | * Build `liblz4` project 52 | * Copy `lz4-1.9.4/build/VS2017/bin/x64_Release/liblz4_static.lib` 53 | * libmdbx v0.10.2 54 | * Needs `cmake` to be installed. 55 | * Create `build.cmd` inside `libmdbx/` unpacked from [libmdbx-amalgamated-0_10_2.zip](https://github.com/erthink/libmdbx/releases/download/v0.10.2/libmdbx-amalgamated-0_10_2.zip): 56 | ```batch 57 | mkdir build 58 | cd build 59 | cmake -G "Visual Studio 16 2019" -A x64 -D CMAKE_CONFIGURATION_TYPES="Debug;Release;RelWithDebInfo" -D MDBX_AVOID_CRT:BOOL=ON -D MDBX_BUILD_SHARED_LIBRARY:BOOL=OFF -D INTERPROCEDURAL_OPTIMIZATION:BOOL=FALSE .. 60 | ``` 61 | * Run `build.cmd`. 62 | * Change inlining option (Properties->C/C++->Optimization->Inline function expansion) in the `Release` config of `mdbx-static` project to `/Ob1`. Otherwise compile freezes. 63 | * `cmake --build . --config Release` or press `Build` for `mdbx-static` project. 64 | * Copy `libmdbx/build/Release/mdbx.lib` 65 | * mimalloc v2.0.7 66 | * https://github.com/microsoft/mimalloc/archive/refs/tags/v2.0.7.zip 67 | * Open `mimalloc-2.0.7/ide/vs2019/mimalloc.sln` 68 | * Select Release build 69 | * In vs2019 modify `mimalloc` project settings: 70 | * Disable debug info (`Debug Information format`: `/Zi` -> `None`) 71 | * Compile as C language to reduce .lib size (from 452KiB to 341KiB) (`C/C++ -> Advanced -> Compile As`: `/TP` -> `/TC`) 72 | * Copy `mimalloc-2.0.7/out/msvc-x64/Release/mimalloc-static.lib` 73 | * Tracy v0.7.8 74 | * https://github.com/wolfpld/tracy/archive/refs/tags/v0.7.8.zip 75 | * Open `/library/win32/TracyProfiler.sln` 76 | * Select Release build 77 | * ~~Build as dll~~ 78 | * `Whole program optimization`: `/GL` -> `No` 79 | * `Debug Information format`: `/Zi` -> `None` 80 | * ~~Copy `tracy/library/win32/x64/Release/TracyProfiler.dll`~~ 81 | * ~~Linking with `TracyProfiler.lib` caused D host to not generate proper stack traces, which is important when debugging compiler and other stuff. Loading master version of tracy dll with LoadLibraryA is super slow (like 30-40s).~~ 82 | * Define `TRACY_DELAYED_INIT` and `TRACY_MANUAL_LIFETIME` preprocessor definitions in `C/C++` -> `Preprocessor` -> `Preprocessor Definitions` 83 | * Add this code to `TracyC.h` before `___tracy_init_thread` definition: 84 | ```C 85 | #if defined(TRACY_DELAYED_INIT) && defined(TRACY_MANUAL_LIFETIME) 86 | TRACY_API void ___tracy_startup_profiler(void); 87 | TRACY_API void ___tracy_shutdown_profiler(void); 88 | #endif 89 | ``` 90 | * Add this code to `client/TracyProfiler.cpp` after `___tracy_init_thread` declaration: 91 | ```C 92 | #if defined(TRACY_DELAYED_INIT) && defined(TRACY_MANUAL_LIFETIME) 93 | TRACY_API void ___tracy_startup_profiler(void) { tracy::StartupProfiler(); } 94 | TRACY_API void ___tracy_shutdown_profiler(void) { tracy::ShutdownProfiler(); } 95 | #endif 96 | ``` 97 | * Build as static lib 98 | * Copy `tracy/library/win32/x64/Release/TracyProfiler.lib` 99 | * shaderc from VulkanSDK v1.3.236.0 100 | * Download from [VulkanSDK](https://vulkan.lunarg.com/sdk/home) or from releases of https://github.com/google/shaderc 101 | * https://sdk.lunarg.com/sdk/download/1.3.236.0/windows/VulkanSDK-1.3.236.0-Installer.exe 102 | * No need to install, can be opened as archive 103 | * ~~Shared lib `/Lib/shaderc_shared.lib` & `/Bin/shaderc_shared.dll`~~ 104 | * Copy `VulkanSDK-1.3.236.0-Installer.exe/Lib/shaderc_combined.lib` 105 | * zstd v1.5.2 106 | * Download https://github.com/facebook/zstd/releases/download/v1.5.2/zstd-1.5.2.tar.gz 107 | * Unpack into `zstd-1.5.2/` 108 | * Go to `zstd-1.5.2/build/cmake` 109 | * Execute 110 | ``` 111 | mkdir build 112 | cd build 113 | cmake .. 114 | ``` 115 | * Open `zstd-1.5.2/build/cmake/build/zstd.sln` 116 | * Select Release build and build `libzstd_static` project 117 | * Copy `zstd-1.5.2/build/cmake/build/lib/Release/zstd_static.lib` 118 | * Vulkan Memory Allocator v3.0.0 119 | * Download [source code](https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator/archive/refs/tags/v3.0.0.zip) 120 | * Go to `VulkanMemoryAllocator-3.0.0/` 121 | * Execute in terminal 122 | ``` 123 | mkdir build 124 | cd build 125 | cmake .. 126 | ``` 127 | * Open `VulkanMemoryAllocator-3.0.0/build/VulkanMemoryAllocator.sln` 128 | * Set preprocessor directives as: 129 | ```C 130 | VMA_STATIC_VULKAN_FUNCTIONS=0 131 | VMA_DYNAMIC_VULKAN_FUNCTIONS=1 132 | VMA_MEMORY_BUDGET=1 133 | VMA_BIND_MEMORY2=1 134 | VMA_DEDICATED_ALLOCATION=1 135 | VMA_EXTERNAL_MEMORY=1 136 | VMA_STATIC_VULKAN_FUNCTIONS=0 137 | ``` 138 | * Switch to Vulkan 1.3 in `VulkanMemoryAllocator-3.0.0/src/VmaUsage.h` (uncomment `#define VMA_VULKAN_VERSION 1003000`) 139 | * Build release version 140 | * Copy `VulkanMemoryAllocator-3.0.0/build/src/Release/VulkanMemoryAllocator.lib` 141 | * GameNetworkingSockets v1.4.1 142 | * `git clone https://github.com/microsoft/vcpkg` 143 | * In `x64 Native Tools Command Prompt for VS 2019` 144 | * `./vcpkg/bootstrap-vcpkg.bat` 145 | * Apply [this patch](https://github.com/eddiejames/vcpkg/commit/420290091e82288e461473e3447e6e4901f0c8df) to `ports/gamenetworkingsockets/portfile.cmake` and `ports/gamenetworkingsockets/vcpkg.json` 146 | * `vcpkg install gamenetworkingsockets:x64-windows-static-md` 147 | * Copy `vcpkg/packages/gamenetworkingsockets_x64-windows-static-md/lib/GameNetworkingSockets_s.lib` 148 | * Copy `vcpkg/packages/protobuf_x64-windows-static-md/lib/libprotobuf.lib` 149 | * Copy `vcpkg/packages/openssl_x64-windows-static-md/lib/libcrypto.lib` 150 | 151 |
152 | -------------------------------------------------------------------------------- /host/deps/glfw3.d: -------------------------------------------------------------------------------- 1 | /// Copyright Michael D. Parker 2018. 2 | /// https://github.com/BindBC/bindbc-glfw 3 | module deps.glfw3; 4 | 5 | extern(C) @nogc nothrow { 6 | alias GLFWglproc = void function(); 7 | alias GLFWvkproc = void function(); 8 | } 9 | 10 | struct GLFWmonitor; 11 | struct GLFWwindow; 12 | struct GLFWcursor; 13 | struct GLFWvidmode; 14 | struct GLFWgammaramp; 15 | struct GLFWimage; 16 | struct GLFWgamepadstate; 17 | 18 | extern(C) nothrow { 19 | alias GLFWerrorfun = void function(int,const(char)*); 20 | alias GLFWwindowposfun = void function(GLFWwindow*,int,int); 21 | alias GLFWwindowsizefun = void function(GLFWwindow*,int,int); 22 | alias GLFWwindowclosefun = void function(GLFWwindow*); 23 | alias GLFWwindowrefreshfun = void function(GLFWwindow*); 24 | alias GLFWwindowfocusfun = void function(GLFWwindow*,int); 25 | alias GLFWwindowiconifyfun = void function(GLFWwindow*,int); 26 | alias GLFWwindowmaximizefun = void function(GLFWwindow*,int); 27 | alias GLFWframebuffersizefun = void function(GLFWwindow*,int,int); 28 | alias GLFWwindowcontentscalefun = void function(GLFWwindow*,float,float); 29 | alias GLFWmousebuttonfun = void function(GLFWwindow*,int,int,int); 30 | alias GLFWcursorposfun = void function(GLFWwindow*,double,double); 31 | alias GLFWcursorenterfun = void function(GLFWwindow*,int); 32 | alias GLFWscrollfun = void function(GLFWwindow*,double,double); 33 | alias GLFWkeyfun = void function(GLFWwindow*,int,int,int,int); 34 | alias GLFWcharfun = void function(GLFWwindow*,uint); 35 | alias GLFWcharmodsfun = void function(GLFWwindow*,uint,int); 36 | alias GLFWdropfun = void function(GLFWwindow*,int,const(char*)*); 37 | alias GLFWmonitorfun = void function(GLFWmonitor*,int); 38 | alias GLFWjoystickfun = void function(int,int); 39 | } 40 | 41 | extern(C) @nogc nothrow: 42 | // 3.0 43 | int glfwInit(); 44 | void glfwTerminate(); 45 | void glfwGetVersion(int*,int*,int*); 46 | const(char)* glfwGetVersionString(); 47 | GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun); 48 | GLFWmonitor** glfwGetMonitors(int*); 49 | GLFWmonitor* glfwGetPrimaryMonitor(); 50 | void glfwGetMonitorPos(GLFWmonitor*,int*,int*); 51 | void glfwGetMonitorPhysicalSize(GLFWmonitor*,int*,int*); 52 | const(char)* glfwGetMonitorName(GLFWmonitor*); 53 | GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun); 54 | const(GLFWvidmode)* glfwGetVideoModes(GLFWmonitor*,int*); 55 | const(GLFWvidmode)* glfwGetVideoMode(GLFWmonitor*); 56 | void glfwSetGamma(GLFWmonitor*,float); 57 | const(GLFWgammaramp*) glfwGetGammaRamp(GLFWmonitor*); 58 | void glfwSetGammaRamp(GLFWmonitor*,const(GLFWgammaramp)*); 59 | void glfwDefaultWindowHints(); 60 | void glfwWindowHint(int,int); 61 | GLFWwindow* glfwCreateWindow(int,int,const(char)*,GLFWmonitor*,GLFWwindow*); 62 | void glfwDestroyWindow(GLFWwindow*); 63 | int glfwWindowShouldClose(GLFWwindow*); 64 | void glfwSetWindowShouldClose(GLFWwindow*,int); 65 | void glfwSetWindowTitle(GLFWwindow*,const(char)*); 66 | void glfwGetWindowPos(GLFWwindow*,int*,int*); 67 | void glfwSetWindowPos(GLFWwindow*,int,int); 68 | void glfwGetWindowSize(GLFWwindow*,int*,int*); 69 | void glfwSetWindowSize(GLFWwindow*,int,int); 70 | void glfwGetFramebufferSize(GLFWwindow*,int*,int*); 71 | void glfwIconifyWindow(GLFWwindow*); 72 | void glfwRestoreWindow(GLFWwindow*); 73 | void glfwShowWindow(GLFWwindow*); 74 | void glfwHideWindow(GLFWwindow*); 75 | GLFWmonitor* glfwGetWindowMonitor(GLFWwindow*); 76 | int glfwGetWindowAttrib(GLFWwindow*,int); 77 | void glfwSetWindowUserPointer(GLFWwindow*,void*); 78 | void* glfwGetWindowUserPointer(GLFWwindow*); 79 | GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow*,GLFWwindowposfun); 80 | GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow*,GLFWwindowsizefun); 81 | GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow*,GLFWwindowclosefun); 82 | GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow*,GLFWwindowrefreshfun); 83 | GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow*,GLFWwindowfocusfun); 84 | GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow*,GLFWwindowiconifyfun); 85 | GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow*,GLFWframebuffersizefun); 86 | void glfwPollEvents(); 87 | void glfwWaitEvents(); 88 | int glfwGetInputMode(GLFWwindow*,int); 89 | void glfwSetInputMode(GLFWwindow*,int,int); 90 | int glfwGetKey(GLFWwindow*,int); 91 | int glfwGetMouseButton(GLFWwindow*,int); 92 | void glfwGetCursorPos(GLFWwindow*,double*,double*); 93 | void glfwSetCursorPos(GLFWwindow*,double,double); 94 | GLFWkeyfun glfwSetKeyCallback(GLFWwindow*,GLFWkeyfun); 95 | GLFWcharfun glfwSetCharCallback(GLFWwindow*,GLFWcharfun); 96 | GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow*,GLFWmousebuttonfun); 97 | GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow*,GLFWcursorposfun); 98 | GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow*,GLFWcursorenterfun); 99 | GLFWscrollfun glfwSetScrollCallback(GLFWwindow*,GLFWscrollfun); 100 | int glfwJoystickPresent(int); 101 | float* glfwGetJoystickAxes(int,int*); 102 | ubyte* glfwGetJoystickButtons(int,int*); 103 | const(char)* glfwGetJoystickName(int); 104 | void glfwSetClipboardString(GLFWwindow*,const(char)*); 105 | const(char)* glfwGetClipboardString(GLFWwindow*); 106 | double glfwGetTime(); 107 | void glfwSetTime(double); 108 | void glfwMakeContextCurrent(GLFWwindow*); 109 | GLFWwindow* glfwGetCurrentContext(); 110 | void glfwSwapBuffers(GLFWwindow*); 111 | void glfwSwapInterval(int); 112 | int glfwExtensionSupported(const(char)*); 113 | GLFWglproc glfwGetProcAddress(const(char)*); 114 | 115 | // 3.1 116 | void glfwGetWindowFrameSize(GLFWwindow*,int*,int*,int*,int*); 117 | void glfwPostEmptyEvent(); 118 | GLFWcursor* glfwCreateCursor(const(GLFWimage)*,int,int); 119 | GLFWcursor* glfwCreateStandardCursor(int); 120 | void glfwDestroyCursor(GLFWcursor*); 121 | void glfwSetCursor(GLFWwindow*,GLFWcursor*); 122 | GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow*,GLFWcharmodsfun); 123 | GLFWdropfun glfwSetDropCallback(GLFWwindow*,GLFWdropfun); 124 | 125 | // 3.2 126 | void glfwSetWindowIcon(GLFWwindow*,int,const(GLFWimage)*); 127 | void glfwSetWindowSizeLimits(GLFWwindow*,int,int,int,int); 128 | void glfwSetWindowAspectRatio(GLFWwindow*,int,int); 129 | void glfwMaximizeWindow(GLFWwindow*); 130 | void glfwFocusWindow(GLFWwindow*); 131 | void glfwSetWindowMonitor(GLFWwindow*,GLFWmonitor*,int,int,int,int,int); 132 | void glfwWaitEventsTimeout(double); 133 | const(char)* glfwGetKeyName(int,int); 134 | long glfwGetTimerValue(); 135 | long glfwGetTimerFrequency(); 136 | int glfwVulkanSupported(); 137 | GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun); 138 | 139 | // 3.3 140 | void glfwInitHint(int,int); 141 | int glfwGetError(const(char)**); 142 | void glfwGetMonitorWorkarea(GLFWmonitor*,int*,int*,int*,int*); 143 | void glfwGetMonitorContentScale(GLFWmonitor*,float*,float*); 144 | void glfwSetMonitorUserPointer(GLFWmonitor*,void*); 145 | void* glfwGetMonitorUserPointer(GLFWmonitor*); 146 | void glfwWindowHintString(int,const(char)*); 147 | void glfwGetWindowContentScale(GLFWwindow*,float*,float*); 148 | float glfwGetWindowOpacity(GLFWwindow*); 149 | void glfwSetWindowOpacity(GLFWwindow*,float); 150 | void glfwRequestWindowAttention(GLFWwindow*); 151 | void glfwSetWindowAttrib(GLFWwindow*,int,int); 152 | GLFWwindowmaximizefun glfwSetWindowMaximizeCallback(GLFWwindow*,GLFWwindowmaximizefun); 153 | GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow*,GLFWwindowcontentscalefun); 154 | int glfwGetKeyScancode(int); 155 | const(ubyte)* glfwGetJoystickHats(int,int*); 156 | const(char)* glfwGetJoystickGUID(int); 157 | void glfwSetJoystickUserPointer(int,void*); 158 | void* glfwGetJoystickUserPointer(int); 159 | int glfwJoystickIsGamepad(int); 160 | int glfwUpdateGamepadMappings(const(char)*); 161 | const(char)* glfwGetGamepadName(int); 162 | int glfwGetGamepadState(int,GLFWgamepadstate*); 163 | 164 | // Vulkan 165 | alias VkInstance = void*; 166 | alias VkPhysicalDevice = void*; 167 | alias VkResult = int; 168 | struct VkAllocationCallbacks; 169 | struct VkSurfaceKHR; 170 | const(char)** glfwGetRequiredInstanceExtensions(uint*); 171 | GLFWvkproc glfwGetInstanceProcAddress(VkInstance,const(char)*); 172 | int glfwGetPhysicalDevicePresentationSupport(VkInstance,VkPhysicalDevice,uint); 173 | VkResult glfwCreateWindowSurface(VkInstance,GLFWwindow*,const(VkAllocationCallbacks)*,VkSurfaceKHR*); 174 | -------------------------------------------------------------------------------- /host/qoi.d: -------------------------------------------------------------------------------- 1 | /// QOI - The "Quite OK Image" format for fast, lossless image compression 2 | /// Dominic Szablewski - https://phoboslab.org 3 | /// -- LICENSE: The MIT License(MIT) 4 | /// Copyright(c) 2021 Dominic Szablewski - https://phoboslab.org 5 | /// Copyright(c) 2022 Andrey Penechko - D port 6 | module qoi; 7 | 8 | enum QOI_COLORSPACE : ubyte { 9 | SRGB = 0, 10 | LINEAR = 1, 11 | } 12 | 13 | struct qoi_desc { 14 | uint width; 15 | uint height; 16 | ubyte channels; 17 | QOI_COLORSPACE colorspace; 18 | } 19 | 20 | alias QOI_MALLOC = extern(C) @nogc nothrow void* function(size_t size); 21 | 22 | private: 23 | enum QOI_OP_INDEX = 0x00; // 00xxxxxx 24 | enum QOI_OP_DIFF = 0x40; // 01xxxxxx 25 | enum QOI_OP_LUMA = 0x80; // 10xxxxxx 26 | enum QOI_OP_RUN = 0xc0; // 11xxxxxx 27 | enum QOI_OP_RGB = 0xfe; // 11111110 28 | enum QOI_OP_RGBA = 0xff; // 11111111 29 | 30 | enum QOI_MASK_2 = 0xc0; // 11000000 31 | 32 | uint QOI_COLOR_HASH(qoi_rgba_t c) @nogc nothrow { return c.r*3 + c.g*5 + c.b*7 + c.a*11; }; 33 | enum QOI_MAGIC = (uint('q') << 24) | (uint('o') << 16) | (uint('i') << 8) | uint('f'); 34 | enum QOI_HEADER_SIZE = 14; 35 | 36 | /* 2GB is the max file size that this implementation can safely handle. We guard 37 | against anything larger than that, assuming the worst case with 5 bytes per 38 | pixel, rounded down to a nice clean value. 400 million pixels ought to be 39 | enough for anybody. */ 40 | enum uint QOI_PIXELS_MAX = 400000000; 41 | 42 | union qoi_rgba_t { 43 | struct { ubyte r, g, b, a; }; 44 | uint v; 45 | } 46 | 47 | immutable ubyte[8] qoi_padding = [0,0,0,0,0,0,0,1]; 48 | 49 | void qoi_write_32(ubyte* bytes, int* pos, uint v) @nogc nothrow { 50 | bytes[(*pos)++] = (0xff000000 & v) >> 24; 51 | bytes[(*pos)++] = (0x00ff0000 & v) >> 16; 52 | bytes[(*pos)++] = (0x0000ff00 & v) >> 8; 53 | bytes[(*pos)++] = (0x000000ff & v); 54 | } 55 | 56 | uint qoi_read_32(const(ubyte)* bytes, int* pos) @nogc nothrow { 57 | uint a = bytes[(*pos)++]; 58 | uint b = bytes[(*pos)++]; 59 | uint c = bytes[(*pos)++]; 60 | uint d = bytes[(*pos)++]; 61 | return (a << 24) | (b << 16) | (c << 8) | d; 62 | } 63 | 64 | 65 | /// Encode raw RGB or RGBA pixels into a QOI image in memory. 66 | /// The function either returns null on failure (invalid parameters or malloc 67 | /// failed) or a pointer to the encoded data on success. On success the out_len 68 | /// is set to the size in bytes of the encoded data. 69 | /// The returned qoi data should be free()d after use. 70 | extern(C) export void* qoi_encode(const(void)* data, const(qoi_desc)* desc, int* out_len, QOI_MALLOC malloc) @nogc nothrow { 71 | if (data == null) return null; 72 | if (out_len == null) return null; 73 | if (desc == null) return null; 74 | if (desc.width == 0) return null; 75 | if (desc.height == 0) return null; 76 | if (desc.channels < 3) return null; 77 | if (desc.channels > 4) return null; 78 | if (desc.colorspace > 1) return null; 79 | if (desc.height >= QOI_PIXELS_MAX / desc.width) return null; 80 | 81 | const int max_size = 82 | desc.width * desc.height * (desc.channels + 1) + 83 | QOI_HEADER_SIZE + cast(int)qoi_padding.sizeof; 84 | 85 | int p = 0; 86 | ubyte* bytes = cast(ubyte*)malloc(max_size); 87 | if (!bytes) return null; 88 | 89 | qoi_write_32(bytes, &p, QOI_MAGIC); 90 | qoi_write_32(bytes, &p, desc.width); 91 | qoi_write_32(bytes, &p, desc.height); 92 | bytes[p++] = desc.channels; 93 | bytes[p++] = desc.colorspace; 94 | 95 | const(ubyte)* pixels = cast(const(ubyte)*)data; 96 | 97 | int run = 0; 98 | qoi_rgba_t px_prev; 99 | px_prev.r = 0; 100 | px_prev.g = 0; 101 | px_prev.b = 0; 102 | px_prev.a = 255; 103 | qoi_rgba_t px = px_prev; 104 | 105 | int px_len = desc.width * desc.height * desc.channels; 106 | int px_end = px_len - desc.channels; 107 | int channels = desc.channels; 108 | qoi_rgba_t[64] index; 109 | 110 | for (int px_pos = 0; px_pos < px_len; px_pos += channels) { 111 | px.r = pixels[px_pos + 0]; 112 | px.g = pixels[px_pos + 1]; 113 | px.b = pixels[px_pos + 2]; 114 | 115 | if (channels == 4) { 116 | px.a = pixels[px_pos + 3]; 117 | } 118 | 119 | if (px.v == px_prev.v) { 120 | run++; 121 | if (run == 62 || px_pos == px_end) { 122 | bytes[p++] = cast(ubyte)(QOI_OP_RUN | (run - 1)); 123 | run = 0; 124 | } 125 | } 126 | else { 127 | int index_pos; 128 | 129 | if (run > 0) { 130 | bytes[p++] = cast(ubyte)(QOI_OP_RUN | (run - 1)); 131 | run = 0; 132 | } 133 | 134 | index_pos = QOI_COLOR_HASH(px) % 64; 135 | 136 | if (index[index_pos].v == px.v) { 137 | bytes[p++] = cast(ubyte)(QOI_OP_INDEX | index_pos); 138 | } 139 | else { 140 | index[index_pos] = px; 141 | 142 | if (px.a == px_prev.a) { 143 | byte vr = cast(byte)(px.r - px_prev.r); 144 | byte vg = cast(byte)(px.g - px_prev.g); 145 | byte vb = cast(byte)(px.b - px_prev.b); 146 | 147 | byte vg_r = cast(byte)(vr - vg); 148 | byte vg_b = cast(byte)(vb - vg); 149 | 150 | if ( 151 | vr > -3 && vr < 2 && 152 | vg > -3 && vg < 2 && 153 | vb > -3 && vb < 2 154 | ) { 155 | bytes[p++] = cast(ubyte)(QOI_OP_DIFF | (vr + 2) << 4 | (vg + 2) << 2 | (vb + 2)); 156 | } 157 | else if ( 158 | vg_r > -9 && vg_r < 8 && 159 | vg > -33 && vg < 32 && 160 | vg_b > -9 && vg_b < 8 161 | ) { 162 | bytes[p++] = cast(ubyte)(QOI_OP_LUMA | (vg + 32)); 163 | bytes[p++] = cast(ubyte)((vg_r + 8) << 4 | (vg_b + 8)); 164 | } 165 | else { 166 | bytes[p++] = QOI_OP_RGB; 167 | bytes[p++] = px.r; 168 | bytes[p++] = px.g; 169 | bytes[p++] = px.b; 170 | } 171 | } 172 | else { 173 | bytes[p++] = QOI_OP_RGBA; 174 | bytes[p++] = px.r; 175 | bytes[p++] = px.g; 176 | bytes[p++] = px.b; 177 | bytes[p++] = px.a; 178 | } 179 | } 180 | } 181 | px_prev = px; 182 | } 183 | 184 | for (size_t i = 0; i < qoi_padding.sizeof; i++) { 185 | bytes[p++] = qoi_padding[i]; 186 | } 187 | 188 | *out_len = p; 189 | return bytes; 190 | } 191 | 192 | /// Decode a QOI image from memory. 193 | /// The function either returns null on failure (invalid parameters or malloc 194 | /// failed) or a pointer to the decoded pixels. On success, the qoi_desc struct 195 | /// is filled with the description from the file header. 196 | /// The returned pixel data should be free()d after use. 197 | extern(C) export void* qoi_decode(const void* data, int size, qoi_desc* desc, int channels, QOI_MALLOC malloc) @nogc nothrow { 198 | if (data == null) return null; 199 | if (desc == null) return null; 200 | if (channels != 0 && channels != 3 && channels != 4) return null; 201 | if (size < QOI_HEADER_SIZE + cast(int)qoi_padding.sizeof) return null; 202 | if (malloc == null) return null; 203 | 204 | const(ubyte)* bytes = cast(const(ubyte)*)data; 205 | int p = 0; 206 | 207 | uint header_magic = qoi_read_32(bytes, &p); 208 | desc.width = qoi_read_32(bytes, &p); 209 | desc.height = qoi_read_32(bytes, &p); 210 | desc.channels = bytes[p++]; 211 | desc.colorspace = cast(QOI_COLORSPACE)bytes[p++]; 212 | 213 | if (desc.width == 0) return null; 214 | if (desc.height == 0) return null; 215 | if (desc.channels < 3) return null; 216 | if (desc.channels > 4) return null; 217 | if (desc.colorspace > 1) return null; 218 | if (header_magic != QOI_MAGIC) return null; 219 | if (desc.height >= QOI_PIXELS_MAX / desc.width) return null; 220 | 221 | if (channels == 0) channels = desc.channels; 222 | 223 | int px_len = desc.width * desc.height * channels; 224 | ubyte* pixels = cast(ubyte*)malloc(px_len); 225 | 226 | if (!pixels) return null; 227 | 228 | qoi_rgba_t[64] index; 229 | qoi_rgba_t px; 230 | px.r = 0; 231 | px.g = 0; 232 | px.b = 0; 233 | px.a = 255; 234 | 235 | int run = 0; 236 | 237 | int chunks_len = size - cast(int)qoi_padding.sizeof; 238 | for (int px_pos = 0; px_pos < px_len; px_pos += channels) { 239 | if (run > 0) { 240 | run--; 241 | } 242 | else if (p < chunks_len) { 243 | int b1 = bytes[p++]; 244 | 245 | if (b1 == QOI_OP_RGB) { 246 | px.r = bytes[p++]; 247 | px.g = bytes[p++]; 248 | px.b = bytes[p++]; 249 | } 250 | else if (b1 == QOI_OP_RGBA) { 251 | px.r = bytes[p++]; 252 | px.g = bytes[p++]; 253 | px.b = bytes[p++]; 254 | px.a = bytes[p++]; 255 | } 256 | else if ((b1 & QOI_MASK_2) == QOI_OP_INDEX) { 257 | px = index[b1]; 258 | } 259 | else if ((b1 & QOI_MASK_2) == QOI_OP_DIFF) { 260 | px.r += ((b1 >> 4) & 0x03) - 2; 261 | px.g += ((b1 >> 2) & 0x03) - 2; 262 | px.b += ( b1 & 0x03) - 2; 263 | } 264 | else if ((b1 & QOI_MASK_2) == QOI_OP_LUMA) { 265 | int b2 = bytes[p++]; 266 | int vg = (b1 & 0x3f) - 32; 267 | px.r += vg - 8 + ((b2 >> 4) & 0x0f); 268 | px.g += vg; 269 | px.b += vg - 8 + (b2 & 0x0f); 270 | } 271 | else if ((b1 & QOI_MASK_2) == QOI_OP_RUN) { 272 | run = (b1 & 0x3f); 273 | } 274 | 275 | index[QOI_COLOR_HASH(px) % 64] = px; 276 | } 277 | 278 | pixels[px_pos + 0] = px.r; 279 | pixels[px_pos + 1] = px.g; 280 | pixels[px_pos + 2] = px.b; 281 | 282 | if (channels == 4) { 283 | pixels[px_pos + 3] = px.a; 284 | } 285 | } 286 | 287 | return pixels; 288 | } 289 | -------------------------------------------------------------------------------- /plugins/core/src/core/utils.vx: -------------------------------------------------------------------------------- 1 | module core.utils; 2 | 3 | import core.kernel32; 4 | import core.mimalloc; 5 | import core.lz4; 6 | import core.host; 7 | import core.format; 8 | 9 | void __init_utils() { 10 | QueryPerformanceFrequency(&_ticksPerSecond); 11 | } 12 | 13 | u8[] fromStringz(u8* cString) { 14 | if (cString == null) return null; 15 | u8* cursor = cString; 16 | while(*cursor) ++cursor; 17 | u64 length = cast(u64)(cursor - cString); 18 | return cString[0..length]; 19 | } 20 | 21 | bool equal[T](T a, T b) #inline { 22 | #if($isSlice(T)) { 23 | alias Base = $baseOf(T); 24 | return are_arrays_equal[Base](a, b); 25 | } else { 26 | return a == b; 27 | } 28 | } 29 | 30 | bool are_arrays_equal[T](T[] a, T[] b) { 31 | if (a.length != b.length) return false; 32 | for (u64 i; i < a.length; ++i) { 33 | if (!equal[T](a[i], b[i])) return false; 34 | } 35 | return true; 36 | } 37 | 38 | bool contains[T](T[] array, T needle) { 39 | for (u64 i; i < array.length; ++i) { 40 | if (equal[T](array[i], needle)) return true; 41 | } 42 | return false; 43 | } 44 | 45 | struct MonoTime { 46 | i64 ticks; 47 | 48 | Duration sub(MonoTime other) { 49 | return Duration(ticks - other.ticks); 50 | } 51 | 52 | /*Duration opBinary[Operator op](MonoTime other) { 53 | #assert(op == Operator.sub); 54 | return Duration(ticks - other.ticks); 55 | }*/ 56 | } 57 | 58 | MonoTime currTime() { 59 | i64 counter; 60 | QueryPerformanceCounter(&counter); 61 | return MonoTime(counter); 62 | } 63 | 64 | Duration subTime(MonoTime a, MonoTime b) { 65 | return Duration(a.ticks - b.ticks); 66 | } 67 | 68 | struct Duration 69 | { 70 | i64 ticks; 71 | 72 | f64 seconds() { 73 | return ticks / cast(f64)(_ticksPerSecond); 74 | } 75 | } 76 | 77 | i64 _ticksPerSecond; 78 | 79 | T min[T](T a, T b) #inline { 80 | if (a < b) return a; 81 | return b; 82 | } 83 | 84 | T max[T](T a, T b) #inline { 85 | if (a > b) return a; 86 | return b; 87 | } 88 | 89 | T clamp[T](T num, T min, T max) #inline { 90 | if (num < min) return min; 91 | if (num > max) return max; 92 | return num; 93 | } 94 | 95 | i32 abs(i32 a) #inline { 96 | if (a < 0) return -a; 97 | return a; 98 | } 99 | 100 | enum Status : u8 { 101 | OK = 0, 102 | ERR = 1, 103 | } 104 | enum ERR = Status.ERR; 105 | enum OK = Status.OK; 106 | 107 | // TODO: almost no error handling being done here 108 | Status readFile(u8[] filename, u8[]* result) { 109 | void* hFile = CreateFileA( 110 | filename.ptr, // file to open 111 | GENERIC_READ, // open for reading 112 | FILE_SHARE_READ, // share for reading 113 | null, // default security 114 | OPEN_EXISTING, // existing file only 115 | FILE_ATTRIBUTE_NORMAL, // normal file 116 | null); // no attr. template 117 | 118 | if (hFile == INVALID_HANDLE_VALUE) { 119 | u8* message = getLastErrorMsg(); 120 | write("[ERROR] Failed to read `", filename, "` ", message.fromStringz); 121 | freeLastErrorMsg(message); 122 | return Status.ERR; 123 | } 124 | 125 | i64 size; 126 | if (!GetFileSizeEx(hFile, &size)) 127 | { 128 | CloseHandle(hFile); 129 | return Status.ERR; // error condition, could call GetLastError to find out more 130 | } 131 | 132 | 133 | if (size == 0) { 134 | CloseHandle(hFile); 135 | return Status.ERR; // empty file 136 | } 137 | 138 | *result = makeVoidArray[u8](cast(u64)size); 139 | u32 bytesRead; 140 | if (!ReadFile(hFile, (*result).ptr, cast(u32)size, &bytesRead, null)) 141 | { 142 | u8* message = getLastErrorMsg(); 143 | write("Failed to read ", filename, " ", message.fromStringz); 144 | freeLastErrorMsg(message); 145 | 146 | freeArray[u8](*result); 147 | CloseHandle(hFile); 148 | return Status.ERR; // error condition, could call GetLastError to find out more 149 | } 150 | CloseHandle(hFile); 151 | return Status.OK; 152 | } 153 | 154 | u8* getLastErrorMsg() { 155 | u32 code = GetLastError(); 156 | u8* message; 157 | FormatMessageA( 158 | FORMAT_MESSAGE_FROM_SYSTEM | 159 | FORMAT_MESSAGE_ALLOCATE_BUFFER | 160 | FORMAT_MESSAGE_IGNORE_INSERTS, 161 | null, 162 | code 163 | 0, 164 | &message, 165 | 0, 166 | null); 167 | return message; 168 | } 169 | void freeLastErrorMsg(u8* msg) { 170 | LocalFree(msg); 171 | } 172 | 173 | T[] makeVoidArray[T](u64 length) 174 | { 175 | if (length == 0) return null; 176 | T* ptr = cast(T*)mi_malloc(length * T.sizeof); 177 | return ptr[0..length]; 178 | } 179 | 180 | T[] makeArray[T](u64 length) 181 | { 182 | if (length == 0) return null; 183 | T* ptr = cast(T*)mi_calloc(length, T.sizeof); 184 | return ptr[0..length]; 185 | } 186 | 187 | T[] resizeArray[T](T[] array, u64 newLength) 188 | { 189 | if (newLength == 0) { 190 | mi_free(array.ptr); 191 | return null; 192 | } 193 | T* ptr = cast(T*)mi_recalloc(array.ptr, newLength, T.sizeof); 194 | return ptr[0..newLength]; 195 | } 196 | 197 | T[] freeArray[T](T[] array) 198 | { 199 | mi_free(array.ptr); 200 | return null; 201 | } 202 | 203 | #if(0) 204 | { 205 | void memcopy(u8[] dst, u8[] src) 206 | { 207 | u64 len = min[u64](dst.length, src.length); 208 | if (len == 0) return; 209 | u8* dst_ptr = dst.ptr; 210 | u8* src_ptr = src.ptr; 211 | for (u64 i = 0; i < len; ++i) 212 | dst_ptr[i] = src_ptr[i]; 213 | } 214 | } 215 | else 216 | { 217 | void memcopy(u8[] dst, u8[] src) 218 | { 219 | u64 len = min[u64](dst.length, src.length); 220 | if (len == 0) return; 221 | RtlCopyMemory(cast(void*)dst.ptr, cast(void*)src.ptr, len); 222 | } 223 | void memcpy(void* dst, void* src, u64 length) { 224 | if (length == 0) return; 225 | RtlCopyMemory(dst, src, length); 226 | } 227 | } 228 | 229 | struct Array[T] 230 | { 231 | T* ptr; 232 | u32 length; 233 | u32 capacity; 234 | 235 | u64 byteLength() { return length * T.sizeof; } 236 | 237 | void free() 238 | { 239 | mi_free(ptr); 240 | length = 0; 241 | capacity = 0; 242 | ptr = null; 243 | } 244 | 245 | void clear() 246 | { 247 | length = 0; 248 | } 249 | 250 | bool empty() { return length == 0; } 251 | 252 | T* get(u64 index) { 253 | return &ptr[index]; 254 | } 255 | 256 | T pop() { 257 | --length; 258 | return ptr[length]; 259 | } 260 | 261 | T[] data() 262 | { 263 | return ptr[0..length]; 264 | } 265 | 266 | void putArray(T[] items) 267 | { 268 | if (length + items.length > capacity) extend(cast(u32)items.length); 269 | for (u32 i = length; i < items.length; ++i) 270 | ptr[length+i] = items[i]; 271 | length += cast(u32)items.length; 272 | } 273 | 274 | void put(T item) 275 | { 276 | if (length == capacity) extend(1); 277 | ptr[length] = item; 278 | ++length; 279 | } 280 | 281 | T* putVoid(u32 numItems) 282 | { 283 | if (length + numItems > capacity) extend(numItems); 284 | T* result = &ptr[length]; 285 | length += numItems; 286 | return result; 287 | } 288 | 289 | void extend(u32 items) 290 | { 291 | enum u32 MIN_CAPACITY = T.sizeof * 4; 292 | u64 bytesNeeded = (length + items) * T.sizeof; 293 | u32 capacityNeeded = cast(u32)nextPOT[u32](cast(u32)bytesNeeded); 294 | capacityNeeded = max[u32](capacityNeeded, MIN_CAPACITY); 295 | ptr = cast(T*)mi_realloc(ptr, capacityNeeded); 296 | capacity = cast(u32)(capacityNeeded / T.sizeof); 297 | } 298 | } 299 | 300 | T nextPOT[T](T x) 301 | { 302 | --x; 303 | x |= x >> 1; // handle 2 bit numbers 304 | x |= x >> 2; // handle 4 bit numbers 305 | x |= x >> 4; // handle 8 bit numbers 306 | #if (T.sizeof >= 2) x |= x >> 8; // handle 16 bit numbers 307 | #if (T.sizeof >= 4) x |= x >> 16; // handle 32 bit numbers 308 | #if (T.sizeof >= 8) x |= x >> 32; // handle 64 bit numbers 309 | ++x; 310 | 311 | return x; 312 | } 313 | 314 | @extern(module, "host") u8[] format_f32(u8[64]* buf, f32 f); 315 | @extern(module, "host") u8[] format_f64(u8[64]* buf, f64 f); 316 | 317 | i64 cstrlen(u8* str) { 318 | if (str == null) return 0; 319 | 320 | u8* start = str; 321 | while(*str) 322 | { 323 | ++str; 324 | } 325 | return str - start; 326 | } 327 | 328 | // 329 | u64 rotl(u64 x, u32 k) #inline { 330 | return (x << k) | (x >> (64 - k)); 331 | } 332 | 333 | void init_rand_state(u64[2]* state) { 334 | state[0][0] = GetTickCount64(); 335 | state[0][1] = 0xac32_ee10_a135_0e00; 336 | xoroshiro128ss_next(state); 337 | state[0][1] = GetTickCount64(); 338 | } 339 | 340 | // xoroshiro128** 341 | // init state to random values before starting 342 | u64 xoroshiro128ss_next(u64[2]* state) { 343 | u64 s0 = (*state)[0]; 344 | u64 s1 = (*state)[1]; 345 | u64 result = rotl(s0 * 5, 7) * 9; 346 | 347 | s1 ^= s0; 348 | (*state)[0] = rotl(s0, 24) ^ s1 ^ (s1 << 16); // a, b 349 | (*state)[1] = rotl(s1, 37); // c 350 | 351 | return result; 352 | } 353 | 354 | i64 uniform(i64 a, i64 b, u64[2]* state) // inclusive interval [] 355 | { 356 | i64 distance = b - a; 357 | u64 rand_num = xoroshiro128ss_next(state); 358 | i64 interval_pos = cast(i64)(rand_num % cast(u64)distance); 359 | return a + interval_pos; 360 | } 361 | 362 | u8[] compress(u8[] data, u8[] outBuffer) 363 | { 364 | i32 res = LZ4_compress_default(data.ptr, outBuffer.ptr, cast(i32)data.length, cast(i32)outBuffer.length); 365 | return outBuffer[0..res]; 366 | } 367 | u8[] decompress(u8[] data, u8[] outBuffer) 368 | { 369 | i32 res = LZ4_decompress_safe(data.ptr, outBuffer.ptr, cast(i32)data.length, cast(i32)outBuffer.length); 370 | //if (res < 0) 371 | //{ 372 | // //println("decompress failed with result ", res, " in ", cast(i64)data.length, " buf ", cast(i64)outBuffer.length); 373 | // return null; 374 | //} 375 | return outBuffer[0..res]; 376 | } 377 | -------------------------------------------------------------------------------- /plugins/core/src/core/format.vx: -------------------------------------------------------------------------------- 1 | module core.format; 2 | 3 | import core.kernel32; 4 | 5 | void write[Args...](Args... args) { 6 | FormatSpec spec; 7 | #foreach(i, arg; args) { 8 | alias func = selectPrintFunc(Args[i]); 9 | func(&writeString, arg, spec); 10 | } 11 | } 12 | 13 | void writeln[Args...](Args... args) { 14 | FormatSpec spec; 15 | #foreach(i, arg; args) { 16 | alias func = selectPrintFunc(Args[i]); 17 | func(&writeString, arg, spec); 18 | } 19 | writeString("\n"); 20 | } 21 | 22 | void writefln[Args...](u8[] fmt, Args... args) { 23 | formattedWrite(&writeString, fmt, args); 24 | writeString("\n"); 25 | } 26 | 27 | void writef[Args...](u8[] fmt, Args... args) { 28 | formattedWrite(&writeString, fmt, args); 29 | } 30 | 31 | noreturn panic[Args...](u8[] fmt, Args... args, u64 line = __LINE__, u8[] file = __FILE__) { 32 | panicImpl(line, file, fmt, args); 33 | } 34 | noreturn panicImpl[Args...](u64 line, u8[] file, u8[] fmt, Args... args) { 35 | writefln("Panic at %s:%s", file, line); 36 | writefln(fmt, args); 37 | ExitProcess(1); 38 | } 39 | 40 | alias SinkDelegate = void function(u8[]); 41 | 42 | void formattedWriteln[Args...](SinkDelegate sink, u8[] fmt, Args... args) { 43 | formattedWrite(sink, fmt, args); 44 | sink("\n"); 45 | } 46 | 47 | void formattedWrite[Args...](SinkDelegate sink, u8[] fmt, Args... args) { 48 | u32 cursor = 0; 49 | #foreach(i, arg; args) { 50 | writeLiteral(sink, fmt, &cursor); 51 | FormatSpec spec = consumeSpec(cast(u32)i, fmt, &cursor); 52 | alias func = selectPrintFunc(Args[i]); 53 | func(sink, arg, spec); 54 | } 55 | writeLiteral(sink, fmt, &cursor); 56 | } 57 | 58 | void writeLiteral(SinkDelegate sink, u8[] fmt, u32* cursorPtr) { 59 | u32 start = (*cursorPtr); 60 | while (true) 61 | { 62 | if (*cursorPtr >= fmt.length) 63 | break; 64 | if (fmt[*cursorPtr] == '%') 65 | { 66 | if (*cursorPtr + 1 >= fmt.length) 67 | panic("Invalid format string. End of string after %%"); 68 | // peek char after % 69 | if (fmt[*cursorPtr + 1] != '%') 70 | break; // this is a format item 71 | // consume first % to write it 72 | ++(*cursorPtr); 73 | // write literal including first % 74 | sink(fmt[start .. *cursorPtr]); 75 | // start after second % 76 | start = *cursorPtr + 1; 77 | // cursor is incremented after if 78 | } 79 | ++(*cursorPtr); // skip literal 80 | } 81 | if (*cursorPtr - start) 82 | sink(fmt[start .. *cursorPtr]); 83 | } 84 | 85 | FormatSpec consumeSpec(u32 argIndex, u8[] fmt, u32* cursorPtr) { 86 | FormatSpec spec; 87 | 88 | if ((*cursorPtr) >= fmt.length) 89 | panic("Invalid format string. Missing %%"); 90 | 91 | ++(*cursorPtr); // skip % 92 | 93 | if ((*cursorPtr) >= fmt.length) 94 | panic("Invalid format string. End of input after %%"); 95 | 96 | // flags 97 | while (true) { 98 | if ((*cursorPtr) >= fmt.length) 99 | panic("Invalid format string. Format item ended with end of string"); 100 | 101 | switch(fmt[(*cursorPtr)]) { 102 | '-' { spec.flags |= FormatSpecFlags.dash; } 103 | '+' { spec.flags |= FormatSpecFlags.plus; } 104 | '#' { spec.flags |= FormatSpecFlags.hash; } 105 | '0' { spec.flags |= FormatSpecFlags.zero; } 106 | ' ' { spec.flags |= FormatSpecFlags.space; } 107 | else { break; } // while 108 | } 109 | 110 | ++(*cursorPtr); 111 | } 112 | 113 | u32 width; 114 | while ('0' <= fmt[(*cursorPtr)] && fmt[(*cursorPtr)] <= '9') { 115 | if ((*cursorPtr) >= fmt.length) 116 | panic("Invalid format string. Format item ended with end of string"); 117 | 118 | width = width * 10 + (fmt[(*cursorPtr)] - '0'); 119 | 120 | if (width > 64) 121 | panic("Invalid format string. Max width is 64"); 122 | 123 | ++(*cursorPtr); 124 | } 125 | spec.width = cast(u8)width; 126 | 127 | // format char 128 | if ((*cursorPtr) >= fmt.length) 129 | panic("Invalid format string. Format item ended with end of string"); 130 | 131 | u8 c = fmt[(*cursorPtr)]; 132 | if ('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z') { 133 | spec.spec = c; 134 | ++(*cursorPtr); 135 | } else { 136 | panic("Invalid format string. Expected format char at the end. Got `%s`", c); 137 | } 138 | 139 | return spec; 140 | } 141 | 142 | void formatValue[T](SinkDelegate sink, T val, FormatSpec spec = FormatSpec()) { 143 | selectFormatter[T](sink, val, spec); 144 | } 145 | 146 | $alias selectPrintFunc($type T) { 147 | if ($isInteger(T)) { 148 | if (T == u8 || T == u16 || T == u32 || T == u64) return format_u64; 149 | return format_i64; 150 | } 151 | if (T == f32) return format_f32; 152 | if (T == f64) return format_f64; 153 | if ($isSlice(T)) return formatString; 154 | if ($isPointer(T)) return formatPointer; 155 | if (T == bool) return formatBool; 156 | $compileError("selectPrintFunc: Invalid type"); 157 | } 158 | 159 | void formatNull(SinkDelegate sink, FormatSpec spec) #inline { 160 | sink("null"); 161 | } 162 | 163 | void formatString(SinkDelegate sink, u8[] val, FormatSpec spec) { 164 | sink(val); 165 | } 166 | 167 | void formatChar(SinkDelegate sink, u8 val, FormatSpec spec) { 168 | u8[1] buf; 169 | buf[0] = val; 170 | sink(buf); 171 | } 172 | 173 | void formatArray[T](SinkDelegate sink, T val, FormatSpec spec) { 174 | sink("["); 175 | for(u64 i = 0; i < val.length; ++i) 176 | { 177 | if (i > 0) sink(", "); 178 | formatValue(sink, val[i]); 179 | } 180 | sink("]"); 181 | } 182 | 183 | void formatBool(SinkDelegate sink, bool val, FormatSpec spec) #inline { 184 | if (val) sink("true"); 185 | else sink("false"); 186 | } 187 | 188 | enum u64 INT_BUF_SIZE = 66; 189 | enum u64 FLT_BUF_SIZE = INT_BUF_SIZE*2+1; 190 | 191 | struct FormatSpec { 192 | u8 spec = 's'; 193 | u8 width; 194 | u8 flags; 195 | u8 pad; 196 | 197 | bool hasDash() { return cast(bool)(flags & FormatSpecFlags.dash); } 198 | bool hasZero() { return cast(bool)(flags & FormatSpecFlags.zero); } 199 | bool hasSpace() { return cast(bool)(flags & FormatSpecFlags.space); } 200 | bool hasPlus() { return cast(bool)(flags & FormatSpecFlags.plus); } 201 | bool hasHash() { return cast(bool)(flags & FormatSpecFlags.hash); } 202 | } 203 | 204 | enum FormatSpecFlags : u8 { 205 | dash = 1 << 0, 206 | zero = 1 << 1, 207 | space = 1 << 2, 208 | plus = 1 << 3, 209 | hash = 1 << 4, 210 | } 211 | 212 | u8[] hexDigitsLower = "0123456789abcdef"; 213 | u8[] hexDigitsUpper = "0123456789ABCDEF"; 214 | u8[] maxNegative_i64 = "9223372036854775808"; 215 | 216 | void formatPointer(SinkDelegate sink, void* ptr, FormatSpec spec) { 217 | if (ptr == null) { 218 | sink("null"); 219 | return; 220 | } 221 | sink("0x"); 222 | u8[INT_BUF_SIZE] buf; 223 | u32 numDigits = formatHex(buf.ptr, cast(u64)ptr, hexDigitsUpper.ptr); 224 | sink(buf[buf.length-numDigits..buf.length]); 225 | } 226 | 227 | void format_i64(SinkDelegate sink, i64 i, FormatSpec spec) { 228 | format_i64_impl(sink, cast(u64)i, spec, true); 229 | } 230 | 231 | void format_u64(SinkDelegate sink, u64 i, FormatSpec spec) { 232 | format_i64_impl(sink, i, spec, false); 233 | } 234 | 235 | void format_i64_impl(SinkDelegate sink, u64 i, FormatSpec spec, bool signed) { 236 | u8[INT_BUF_SIZE] buf; 237 | u32 numDigits; 238 | 239 | u8 padding = ' '; 240 | 241 | if (spec.hasSpace) padding = ' '; 242 | if (spec.hasZero) padding = '0'; 243 | 244 | if (i == 0) { 245 | buf[buf.length-1] = '0'; 246 | numDigits = 1; 247 | } else switch (spec.spec) { 248 | 'b' { numDigits = formatBinary(buf.ptr, i); } 249 | 'x' { numDigits = formatHex(buf.ptr, i, hexDigitsLower.ptr); } 250 | 'X' { numDigits = formatHex(buf.ptr, i, hexDigitsUpper.ptr); } 251 | else { numDigits = formatDecimal(buf.ptr, cast(i64)i, signed); } 252 | } 253 | 254 | while (spec.width > numDigits) { 255 | buf[buf.length - ++numDigits] = padding; 256 | } 257 | 258 | sink(buf[buf.length-numDigits..buf.length]); 259 | } 260 | 261 | void format_f32(SinkDelegate sink, f32 f, FormatSpec spec) { 262 | u8[FLT_BUF_SIZE] buf; 263 | u32 numDigits = formatFloat(buf.ptr, f); 264 | sink(buf[buf.length-numDigits..buf.length]); 265 | } 266 | 267 | void format_f64(SinkDelegate sink, f64 f, FormatSpec spec) { 268 | u8[FLT_BUF_SIZE] buf; 269 | u32 numDigits = formatFloat(buf.ptr, f); 270 | sink(buf[buf.length-numDigits..buf.length]); 271 | } 272 | 273 | // nonzero 274 | u32 formatHex(u8* /*INT_BUF_SIZE*/ sink, u64 i, u8* /*u8[16]*/ chars) { 275 | u32 numDigits = 0; 276 | while (i) { 277 | sink[INT_BUF_SIZE - ++numDigits] = chars[i & 0xF]; 278 | i >>= 4; 279 | } 280 | return numDigits; 281 | } 282 | 283 | // nonzero 284 | u32 formatBinary(u8* /*INT_BUF_SIZE*/ sink, u64 u) { 285 | u32 numDigits = 0; 286 | while (true) { 287 | u8 c = cast(u8)('0' + (u & 1)); 288 | sink[INT_BUF_SIZE - ++numDigits] = c; 289 | u >>= 1; 290 | if (u == 0) break; 291 | } 292 | return numDigits; 293 | } 294 | 295 | u32 formatDecimalUnsigned(u8* /*INT_BUF_SIZE*/ sink, u64 u) { 296 | u32 numDigits = 0; 297 | while (true) { 298 | u8 c = cast(u8)('0' + (u % 10)); 299 | sink[INT_BUF_SIZE - ++numDigits] = c; 300 | u /= 10; 301 | if (u == 0) break; 302 | } 303 | return numDigits; 304 | } 305 | 306 | u32 formatDecimal(u8* /*INT_BUF_SIZE*/ sink, i64 i, bool signed) { 307 | u32 numDigits = 0; 308 | u64 u = cast(u64)i; 309 | if (signed && i < 0) { u = cast(u64)(-i); } 310 | while (true) { 311 | u8 c = cast(u8)('0' + (u % 10)); 312 | sink[INT_BUF_SIZE - ++numDigits] = c; 313 | u /= 10; 314 | if (u == 0) break; 315 | } 316 | if (signed && i < 0) { sink[INT_BUF_SIZE - ++numDigits] = '-'; } 317 | return numDigits; 318 | } 319 | 320 | enum FP_PRECISION = 6; 321 | 322 | u32 formatFloat(u8* /*FLT_BUF_SIZE*/ sink, f64 originalFloat) { 323 | f64 f = originalFloat; 324 | if (originalFloat < 0) f = -f; 325 | i64 ipart = cast(i64)(f + 0.00000001); 326 | f64 frac = f - ipart; 327 | if (frac < 0) frac = -frac; 328 | 329 | i64 ndigits = 0; 330 | i64 nzeroes = -1; 331 | 332 | while (frac - cast(i64)(frac) >= 0.0000001 && frac - cast(i64)(frac) <= 0.9999999 && ndigits < FP_PRECISION) { 333 | if (cast(i64)(frac) == 0) nzeroes++; 334 | ndigits++; 335 | frac *= 10; 336 | } 337 | if (frac - cast(i64)(frac) > 0.9999999) frac++; 338 | 339 | u8* bufPtr = sink + INT_BUF_SIZE + 1; 340 | u32 numDigits = formatDecimalUnsigned(bufPtr, cast(u64)(frac)); 341 | while (nzeroes) { 342 | sink[FLT_BUF_SIZE - ++numDigits] = '0'; 343 | --nzeroes; 344 | } 345 | 346 | sink[FLT_BUF_SIZE - ++numDigits] = '.'; 347 | 348 | u8* bufPtr2 = sink + (FLT_BUF_SIZE - numDigits - INT_BUF_SIZE); 349 | numDigits += formatDecimalUnsigned(bufPtr2, cast(u64)ipart); 350 | 351 | if (originalFloat < 0) { 352 | sink[FLT_BUF_SIZE - ++numDigits] = '-'; 353 | } 354 | 355 | return numDigits; 356 | } 357 | 358 | void writeString(u8[] str) { 359 | void* handle = GetStdHandle(STD_OUTPUT_HANDLE); 360 | u32 numWritten; 361 | WriteFile( 362 | handle, 363 | cast(u8*)str.ptr, 364 | cast(u32)str.length, 365 | &numWritten, 366 | null); 367 | } 368 | -------------------------------------------------------------------------------- /host/main.d: -------------------------------------------------------------------------------- 1 | import std.string : toStringz; 2 | import std.stdio; 3 | import std.getopt; 4 | import std.traits : isFunction, isFunctionPointer, isType; 5 | import std.conv : text; 6 | import vox.all; 7 | 8 | 9 | void main(string[] args) { 10 | static import deps.tracy_lib; 11 | import deps.tracy_ptr; 12 | bool enable_tracy = false; 13 | string entryPoint = "default"; 14 | 15 | import deps.kernel32 : GetCurrentThread, SetThreadPriority, SetThreadAffinityMask; 16 | SetThreadPriority(GetCurrentThread(), 2); 17 | SetThreadAffinityMask(GetCurrentThread(), 1); 18 | 19 | GetoptResult optResult = getopt( 20 | args, 21 | "tracy", "Enable tracy profiling", &enable_tracy, 22 | "entry", `Plugin to start ["default"]`, &entryPoint, 23 | ); 24 | 25 | auto startTime = currTime; 26 | import deps.kernel32 : SetConsoleOutputCP; 27 | SetConsoleOutputCP(65001); 28 | 29 | load_tracy(enable_tracy); 30 | 31 | tracy_startup_profiler(); 32 | scope(exit) tracy_shutdown_profiler(); 33 | 34 | tracy_set_thread_name("main"); 35 | 36 | auto startCompileTime = currTime; 37 | Driver driver; 38 | driver.initialize(jitPasses); 39 | driver.context.buildType = BuildType.jit; 40 | version(Windows) driver.context.targetOs = TargetOs.windows; 41 | else version(linux) driver.context.targetOs = TargetOs.linux; 42 | else static assert(false, "Unhandled OS"); 43 | 44 | //driver.context.validateIr = true; 45 | //driver.context.printIr = true; 46 | //driver.context.printLirRA = true; 47 | //driver.context.printCodeHex = true; 48 | driver.context.printTraceOnError = true; 49 | driver.context.useFramePointer = true; 50 | 51 | driver.beginCompilation(); 52 | 53 | //driver.context.setDumpFilter("createInstance"); 54 | 55 | // add files 56 | registerHostSymbols(&driver.context); 57 | Identifier mainModule = registerPackages(driver, entryPoint); 58 | 59 | auto times = PerPassTimeMeasurements(1, driver.passes); 60 | 61 | static loc = TracyLoc("Compile Vox", __FILE__, __FILE__, __LINE__, 0xFF00FF); 62 | auto tracy_ctx = tracy_emit_zone_begin(&loc, 1); 63 | // compile 64 | try { 65 | driver.compile(); 66 | } catch(CompilationException e) { 67 | writefln("Compile error:"); 68 | writeln(driver.context.errorSink.text); 69 | if (e.isICE) throw e; 70 | return; 71 | } catch(Throwable e) { 72 | writeln(driver.context.errorSink.text); 73 | throw e; 74 | } 75 | driver.markCodeAsExecutable(); 76 | auto endCompileTime = currTime; 77 | tracy_emit_zone_end(tracy_ctx); 78 | //writefln("RO: %s", driver.context.roStaticDataBuffer.bufPtr); 79 | 80 | auto endTime = currTime; 81 | 82 | auto duration = endCompileTime - startCompileTime; 83 | times.onIteration(0, duration); 84 | //times.print; 85 | //writefln("Tracy load %ss", scaledNumberFmt(startCompileTime - startTime)); 86 | writefln("Compiled in %ss", scaledNumberFmt(endCompileTime - startCompileTime)); 87 | //writefln("Total %ss", scaledNumberFmt(endTime - startTime)); 88 | stdout.flush; 89 | 90 | Identifier main_id = driver.context.idMap.getOrReg(&driver.context, "main"); 91 | Identifier funcId = driver.context.idMap.getOrRegFqn(&driver.context, FullyQualifiedName(mainModule, main_id)); 92 | try { 93 | FunctionDeclNode* func = driver.context.findFunction(funcId); 94 | auto mainFunc = driver.context.getFunctionPtr!void(func); 95 | mainFunc(); 96 | } catch(CompilationException e) { 97 | writeln(driver.context.errorSink.text); 98 | } 99 | } 100 | 101 | struct RawPluginInfo 102 | { 103 | string name; 104 | string[] dependencies; // plugin names found in plugin/deps.txt 105 | string[] sourceFiles; // .vx files inside plugin/src/ dir 106 | string[] resFiles; // resource files inside plugin/res/ dir (currently .frag and .vert) 107 | Identifier mainModule; 108 | string mainFile; 109 | bool isOnStack; 110 | bool isSelected; 111 | } 112 | 113 | // Returns name of the entry function 114 | Identifier registerPackages(ref Driver driver, string rootPluginName) 115 | { 116 | import std.file : dirEntries, SpanMode, DirEntry; 117 | import std.path : buildPath, pathSplitter, extension, baseName, stripExtension; 118 | import std.range : back; 119 | 120 | auto startTime = currTime; 121 | RawPluginInfo[] detectedPlugins; 122 | uint[string] pluginMap; 123 | bool foundRootPlugin; 124 | uint rootPluginIndex; 125 | 126 | static void onPluginDepsFile(ref RawPluginInfo info, string depsFilename) 127 | { 128 | import std.file : read; 129 | import std.string : lineSplitter; 130 | import std.algorithm : filter; 131 | import std.range : empty; 132 | import std.array : array; 133 | string data = cast(string)read(depsFilename); 134 | info.dependencies = cast(string[])data.lineSplitter.filter!(line => !line.empty).array; 135 | } 136 | 137 | static void onPluginSrcDir(ref Driver driver, ref RawPluginInfo info, string srcDir) 138 | { 139 | //writefln("-d src"); 140 | bool foundMainFile = false; 141 | 142 | void visitDir(string dir, Identifier parentId) { 143 | foreach (DirEntry srcEntry; dirEntries(dir, SpanMode.shallow, false)) 144 | { 145 | Identifier entryId = driver.context.idMap.getOrReg(&driver.context, srcEntry.name.baseName.stripExtension); 146 | Identifier fullEntryId = driver.context.idMap.getOrRegFqn(&driver.context, FullyQualifiedName(parentId, entryId)); 147 | 148 | if (srcEntry.isDir) { 149 | visitDir(srcEntry.name, fullEntryId); 150 | continue; 151 | } 152 | 153 | if (!srcEntry.isFile) continue; 154 | if (srcEntry.name.extension != ".vx") continue; 155 | 156 | if (srcEntry.name.baseName == "main.vx") 157 | { 158 | if (foundMainFile) { 159 | stderr.writeln("Plugin %s has multiple main.vx files:", info.name); 160 | stderr.writeln("- ", srcEntry.name); 161 | stderr.writeln("- ", info.mainFile); 162 | assert(false); 163 | } 164 | 165 | foundMainFile = true; 166 | info.mainModule = fullEntryId; 167 | info.mainFile = srcEntry.name; 168 | } 169 | 170 | //writeln("-s ", srcEntry.name); 171 | info.sourceFiles ~= srcEntry.name; 172 | } 173 | } 174 | 175 | visitDir(srcDir, Identifier()); 176 | } 177 | 178 | void onPluginDir(string dir) 179 | { 180 | RawPluginInfo info; 181 | info.name = dir.pathSplitter.back; 182 | 183 | //writefln("Plugin: %s in %s", info.name, dir); 184 | foreach (DirEntry entry; dirEntries(dir, SpanMode.shallow, false)) 185 | { 186 | string base = entry.name.pathSplitter.back; 187 | if (entry.isDir) { 188 | switch(base) { 189 | case "src": 190 | onPluginSrcDir(driver, info, entry.name); 191 | break; 192 | case "res": 193 | //writefln("-d res"); 194 | break; 195 | default: break; 196 | } 197 | } else if (entry.isFile) { 198 | switch(base) { 199 | case "deps.txt": 200 | onPluginDepsFile(info, entry.name); 201 | break; 202 | default: break; 203 | } 204 | } 205 | } 206 | 207 | uint pluginIndex = cast(uint)detectedPlugins.length; 208 | 209 | if (info.name in pluginMap) { 210 | assert(false, text("Found multiple plugins named ", info.name)); 211 | } 212 | 213 | pluginMap[info.name] = pluginIndex; 214 | 215 | if (info.name == rootPluginName) { 216 | foundRootPlugin = true; 217 | rootPluginIndex = pluginIndex; 218 | } 219 | 220 | detectedPlugins ~= info; 221 | } 222 | 223 | // Gather available plugins 224 | foreach (DirEntry entry; dirEntries("../plugins", SpanMode.shallow, false)) 225 | { 226 | if (entry.isDir) onPluginDir(entry.name); 227 | } 228 | 229 | assert(foundRootPlugin, text("Cannot find root plugin ", rootPluginName)); 230 | 231 | uint[] stack; 232 | uint[] selectedPlugins; 233 | 234 | void walkDependencies(uint index) { 235 | import std.algorithm : countUntil; 236 | 237 | // Already loaded by some other plugin 238 | if (detectedPlugins[index].isSelected) return; 239 | 240 | stack ~= index; 241 | 242 | if (detectedPlugins[index].isOnStack) { 243 | stderr.writefln("Detected loop of plugin dependencies:"); 244 | ptrdiff_t from = countUntil(stack, index); 245 | foreach(i; stack[from..$]) 246 | { 247 | if (i == index) stderr.writeln("> ", detectedPlugins[i].name); 248 | else stderr.writeln("- ", detectedPlugins[i].name); 249 | } 250 | assert(false); 251 | } 252 | 253 | selectedPlugins ~= index; 254 | detectedPlugins[index].isOnStack = true; 255 | detectedPlugins[index].isSelected = true; 256 | 257 | foreach(string depName; detectedPlugins[index].dependencies) 258 | { 259 | if (auto depIndex = depName in pluginMap) { 260 | walkDependencies(*depIndex); 261 | } else { 262 | assert(false, format("Cannot find dependency `%s` of `%s`", depName, detectedPlugins[index].name)); 263 | } 264 | } 265 | 266 | detectedPlugins[index].isOnStack = false; 267 | stack.length--; 268 | } 269 | 270 | // Gather all dependencies and detect cyclic dependencies 271 | walkDependencies(rootPluginIndex); 272 | 273 | uint numSourceFilesLoaded = 0; 274 | bool loadedMainFile = false; 275 | size_t mainPlugin; 276 | 277 | foreach (i; selectedPlugins) 278 | { 279 | RawPluginInfo* info = &detectedPlugins[i]; 280 | 281 | foreach (string file; info.sourceFiles) { 282 | driver.addModule(SourceFileInfo(file)); 283 | ++numSourceFilesLoaded; 284 | } 285 | 286 | if (info.mainFile) { 287 | if (loadedMainFile) { 288 | stderr.writeln("Multiple plugins define main.vx file:"); 289 | stderr.writeln("- ", info.name, " ", info.mainFile); 290 | stderr.writeln("- ", detectedPlugins[mainPlugin].name, " ", detectedPlugins[mainPlugin].mainFile); 291 | assert(false); 292 | } 293 | 294 | loadedMainFile = true; 295 | mainPlugin = i; 296 | } 297 | } 298 | 299 | auto endTime = currTime; 300 | stdout.flush; 301 | //stderr.writefln("Plugins scan time %ss", scaledNumberFmt(endTime - startTime)); 302 | //stderr.writefln("Detected %s plugins in ../plugins", detectedPlugins.length); 303 | //stderr.writefln("Selected %s plugins starting from %s", selectedPlugins.length, rootPluginName); 304 | //stderr.writefln("Loaded %s source files", numSourceFilesLoaded); 305 | 306 | if (!loadedMainFile) { 307 | stderr.writeln("Cannot find main.vx"); 308 | return Identifier(); 309 | } 310 | 311 | return detectedPlugins[mainPlugin].mainModule; 312 | } 313 | 314 | void registerHostSymbols(CompilationContext* context) 315 | { 316 | void regHostSymbol(alias member)(string symName, Identifier modId, LinkIndex hostModuleIndex) 317 | { 318 | //writefln("reg %s %s", hostModuleName, symName); 319 | Identifier symId = context.idMap.getOrReg(context, symName); 320 | static if (isFunction!member) { // pickup functions 321 | context.addHostSymbol(hostModuleIndex, symId, cast(void*)&member); 322 | } else static if (isFunctionPointer!member && !isType!member) { // pickup function pointers 323 | context.addHostSymbol(hostModuleIndex, symId, cast(void*)member); 324 | } 325 | } 326 | 327 | void regHostModule(alias Module)(string hostModuleName) 328 | { 329 | Identifier modId = context.idMap.getOrReg(context, hostModuleName); 330 | LinkIndex hostModuleIndex = context.getOrCreateExternalModule(modId, ObjectModuleKind.isHost); 331 | 332 | foreach(m; __traits(allMembers, Module)) 333 | { 334 | alias member = __traits(getMember, Module, m); 335 | regHostSymbol!member(m, modId, hostModuleIndex); 336 | } 337 | } 338 | 339 | import deps.enet; 340 | import deps.game_networking_sockets; 341 | import deps.glfw3; 342 | import deps.kernel32; 343 | import deps.lz4; 344 | import deps.mdbx; 345 | import deps.mimalloc; 346 | import deps.shaderc; 347 | import deps.tracy_ptr; 348 | import deps.vma; 349 | import deps.zstd; 350 | import qoi; 351 | 352 | regHostModule!(deps.enet)("enet"); 353 | regHostModule!(deps.game_networking_sockets)("game_networking_sockets"); 354 | regHostModule!(deps.glfw3)("glfw3"); 355 | regHostModule!(deps.kernel32)("kernel32"); 356 | regHostModule!(deps.lz4)("lz4"); 357 | regHostModule!(deps.mdbx)("mdbx"); 358 | regHostModule!(deps.mimalloc)("mimalloc"); 359 | regHostModule!(deps.shaderc)("shaderc"); 360 | regHostModule!(deps.tracy_ptr)("tracy"); 361 | regHostModule!(deps.vma)("vma"); 362 | regHostModule!(deps.zstd)("zstd"); 363 | 364 | // host 365 | { 366 | Identifier modId = context.idMap.getOrReg(context, "host"); 367 | LinkIndex hostModuleIndex = context.getOrCreateExternalModule(modId, ObjectModuleKind.isHost); 368 | regHostSymbol!host_print("host_print", modId, hostModuleIndex); 369 | regHostSymbol!(sin!float)("sin_f32", modId, hostModuleIndex); 370 | regHostSymbol!(sin!double)("sin_f64", modId, hostModuleIndex); 371 | regHostSymbol!(cos!float)("cos_f32", modId, hostModuleIndex); 372 | regHostSymbol!(cos!double)("cos_f64", modId, hostModuleIndex); 373 | regHostSymbol!(sqrt!float)("sqrt_f32", modId, hostModuleIndex); 374 | regHostSymbol!(sqrt!double)("sqrt_f64", modId, hostModuleIndex); 375 | regHostSymbol!__debugbreak("__debugbreak", modId, hostModuleIndex); 376 | regHostSymbol!(format_val!float)("format_f32", modId, hostModuleIndex); 377 | regHostSymbol!(format_val!double)("format_f64", modId, hostModuleIndex); 378 | } 379 | 380 | // QOI 381 | { 382 | Identifier modId = context.idMap.getOrReg(context, "qoi"); 383 | LinkIndex hostModuleIndex = context.getOrCreateExternalModule(modId, ObjectModuleKind.isHost); 384 | regHostSymbol!qoi_encode("qoi_encode", modId, hostModuleIndex); 385 | regHostSymbol!qoi_decode("qoi_decode", modId, hostModuleIndex); 386 | } 387 | } 388 | 389 | void load_dll(alias Module)(string dllFile) { 390 | import core.sys.windows.windows : LoadLibraryA, GetProcAddress; 391 | void* lib = LoadLibraryA(dllFile.toStringz); 392 | enforce(lib !is null, format("Cannot load %s", dllFile)); 393 | //writefln("lib %X %s", lib, dllFile); 394 | 395 | foreach(m; __traits(allMembers, Module)) 396 | { 397 | alias member = __traits(getMember, Module, m); 398 | static if (isFunctionPointer!member && !isType!member) { // only pickup function pointers 399 | void* symPtr = GetProcAddress(lib, m); 400 | //writefln(" sym %X %s", symPtr, m); 401 | enforce(symPtr !is null, format("Cannot find `%s` in %s", m, dllFile)); 402 | member = cast(typeof(member))symPtr; 403 | } 404 | } 405 | } 406 | 407 | void load_tracy(bool enable_tracy) { 408 | import deps.tracy_ptr; 409 | import deps.tracy_lib; 410 | import deps.tracy_stub; 411 | 412 | tracy_startup_profiler = enable_tracy ? &___tracy_startup_profiler : &stub_tracy_startup_profiler; 413 | tracy_shutdown_profiler = enable_tracy ? &___tracy_shutdown_profiler : &stub_tracy_shutdown_profiler; 414 | tracy_emit_zone_begin = enable_tracy ? &___tracy_emit_zone_begin : &stub_tracy_emit_zone_begin; 415 | tracy_emit_zone_begin_callstack = enable_tracy ? &___tracy_emit_zone_begin_callstack : &stub_tracy_emit_zone_begin_callstack; 416 | tracy_emit_zone_end = enable_tracy ? &___tracy_emit_zone_end : &stub_tracy_emit_zone_end; 417 | tracy_emit_frame_mark = enable_tracy ? &___tracy_emit_frame_mark : &stub_tracy_emit_frame_mark; 418 | tracy_emit_frame_mark_start = enable_tracy ? &___tracy_emit_frame_mark_start : &stub_tracy_emit_frame_mark_start; 419 | tracy_emit_frame_mark_end = enable_tracy ? &___tracy_emit_frame_mark_end : &stub_tracy_emit_frame_mark_end; 420 | tracy_set_thread_name = enable_tracy ? &___tracy_set_thread_name : &stub_tracy_set_thread_name; 421 | tracy_emit_plot = enable_tracy ? &___tracy_emit_plot : &stub_tracy_emit_plot; 422 | tracy_emit_message_appinfo = enable_tracy ? &___tracy_emit_message_appinfo : &stub_tracy_emit_message_appinfo; 423 | tracy_emit_message = enable_tracy ? &___tracy_emit_message : &stub_tracy_emit_message; 424 | tracy_emit_messageL = enable_tracy ? &___tracy_emit_messageL : &stub_tracy_emit_messageL; 425 | tracy_emit_messageC = enable_tracy ? &___tracy_emit_messageC : &stub_tracy_emit_messageC; 426 | tracy_emit_messageLC = enable_tracy ? &___tracy_emit_messageLC : &stub_tracy_emit_messageLC; 427 | } 428 | 429 | extern(C) void host_print(SliceString str) { 430 | write(str.slice); 431 | } 432 | static import core.math; 433 | extern(C) T sin(T)(T x) @safe pure nothrow @nogc { return core.math.sin(x); } 434 | extern(C) T cos(T)(T x) @safe pure nothrow @nogc { return core.math.cos(x); } 435 | extern(C) T sqrt(T)(T x) @safe pure nothrow @nogc { return core.math.sqrt(x); } 436 | extern(C) void __debugbreak() { 437 | asm { int 3; } 438 | } 439 | 440 | extern(C) SliceString format_val(T)(char[64]* buf, T val) { 441 | import std.format; 442 | auto spec = singleSpec("%s"); 443 | char[] bufSlice = (*buf)[]; 444 | formatValue(bufSlice, val, spec); 445 | return SliceString((*buf)[0..64-bufSlice.length]); 446 | } 447 | -------------------------------------------------------------------------------- /plugins/core/src/core/glfw3.vx: -------------------------------------------------------------------------------- 1 | /// Port of https://github.com/BindBC/bindbc-glfw to Vox 2 | /// bindbc-glfw copyright Michael D. Parker 2018. 3 | module core.glfw3; 4 | 5 | @extern(module, "glfw3"): 6 | 7 | import core.vulkan.types; 8 | 9 | enum { 10 | GLFW_RELEASE = 0, 11 | GLFW_PRESS = 1, 12 | GLFW_REPEAT = 2, 13 | } 14 | 15 | enum { 16 | GLFW_HAT_CENTERED = 0, 17 | GLFW_HAT_UP = 1, 18 | GLFW_HAT_RIGHT = 2, 19 | GLFW_HAT_DOWN = 4, 20 | GLFW_HAT_LEFT = 8, 21 | GLFW_HAT_RIGHT_UP = (GLFW_HAT_RIGHT | GLFW_HAT_UP), 22 | GLFW_HAT_RIGHT_DOWN = (GLFW_HAT_RIGHT | GLFW_HAT_DOWN), 23 | GLFW_HAT_LEFT_UP = (GLFW_HAT_LEFT | GLFW_HAT_UP), 24 | GLFW_HAT_LEFT_DOWN = (GLFW_HAT_LEFT | GLFW_HAT_DOWN), 25 | } 26 | 27 | enum { 28 | GLFW_KEY_UNKNOWN = -1, 29 | GLFW_KEY_SPACE = 32, 30 | GLFW_KEY_APOSTROPHE = 39, 31 | GLFW_KEY_COMMA = 44, 32 | GLFW_KEY_MINUS = 45, 33 | GLFW_KEY_PERIOD = 46, 34 | GLFW_KEY_SLASH = 47, 35 | GLFW_KEY_0 = 48, 36 | GLFW_KEY_1 = 49, 37 | GLFW_KEY_2 = 50, 38 | GLFW_KEY_3 = 51, 39 | GLFW_KEY_4 = 52, 40 | GLFW_KEY_5 = 53, 41 | GLFW_KEY_6 = 54, 42 | GLFW_KEY_7 = 55, 43 | GLFW_KEY_8 = 56, 44 | GLFW_KEY_9 = 57, 45 | GLFW_KEY_SEMICOLON = 59, 46 | GLFW_KEY_EQUAL = 61, 47 | GLFW_KEY_A = 65, 48 | GLFW_KEY_B = 66, 49 | GLFW_KEY_C = 67, 50 | GLFW_KEY_D = 68, 51 | GLFW_KEY_E = 69, 52 | GLFW_KEY_F = 70, 53 | GLFW_KEY_G = 71, 54 | GLFW_KEY_H = 72, 55 | GLFW_KEY_I = 73, 56 | GLFW_KEY_J = 74, 57 | GLFW_KEY_K = 75, 58 | GLFW_KEY_L = 76, 59 | GLFW_KEY_M = 77, 60 | GLFW_KEY_N = 78, 61 | GLFW_KEY_O = 79, 62 | GLFW_KEY_P = 80, 63 | GLFW_KEY_Q = 81, 64 | GLFW_KEY_R = 82, 65 | GLFW_KEY_S = 83, 66 | GLFW_KEY_T = 84, 67 | GLFW_KEY_U = 85, 68 | GLFW_KEY_V = 86, 69 | GLFW_KEY_W = 87, 70 | GLFW_KEY_X = 88, 71 | GLFW_KEY_Y = 89, 72 | GLFW_KEY_Z = 90, 73 | GLFW_KEY_LEFT_BRACKET = 91, 74 | GLFW_KEY_BACKSLASH = 92, 75 | GLFW_KEY_RIGHT_BRACKET = 93, 76 | GLFW_KEY_GRAVE_ACCENT = 96, 77 | GLFW_KEY_WORLD_1 = 161, 78 | GLFW_KEY_WORLD_2 = 162, 79 | 80 | GLFW_KEY_ESCAPE = 256, 81 | GLFW_KEY_ENTER = 257, 82 | GLFW_KEY_TAB = 258, 83 | GLFW_KEY_BACKSPACE = 259, 84 | GLFW_KEY_INSERT = 260, 85 | GLFW_KEY_DELETE = 261, 86 | GLFW_KEY_RIGHT = 262, 87 | GLFW_KEY_LEFT = 263, 88 | GLFW_KEY_DOWN = 264, 89 | GLFW_KEY_UP = 265, 90 | GLFW_KEY_PAGE_UP = 266, 91 | GLFW_KEY_PAGE_DOWN = 267, 92 | GLFW_KEY_HOME = 268, 93 | GLFW_KEY_END = 269, 94 | GLFW_KEY_CAPS_LOCK = 280, 95 | GLFW_KEY_SCROLL_LOCK = 281, 96 | GLFW_KEY_NUM_LOCK = 282, 97 | GLFW_KEY_PRINT_SCREEN = 283, 98 | GLFW_KEY_PAUSE = 284, 99 | GLFW_KEY_F1 = 290, 100 | GLFW_KEY_F2 = 291, 101 | GLFW_KEY_F3 = 292, 102 | GLFW_KEY_F4 = 293, 103 | GLFW_KEY_F5 = 294, 104 | GLFW_KEY_F6 = 295, 105 | GLFW_KEY_F7 = 296, 106 | GLFW_KEY_F8 = 297, 107 | GLFW_KEY_F9 = 298, 108 | GLFW_KEY_F10 = 299, 109 | GLFW_KEY_F11 = 300, 110 | GLFW_KEY_F12 = 301, 111 | GLFW_KEY_F13 = 302, 112 | GLFW_KEY_F14 = 303, 113 | GLFW_KEY_F15 = 304, 114 | GLFW_KEY_F16 = 305, 115 | GLFW_KEY_F17 = 306, 116 | GLFW_KEY_F18 = 307, 117 | GLFW_KEY_F19 = 308, 118 | GLFW_KEY_F20 = 309, 119 | GLFW_KEY_F21 = 310, 120 | GLFW_KEY_F22 = 311, 121 | GLFW_KEY_F23 = 312, 122 | GLFW_KEY_F24 = 313, 123 | GLFW_KEY_F25 = 314, 124 | GLFW_KEY_KP_0 = 320, 125 | GLFW_KEY_KP_1 = 321, 126 | GLFW_KEY_KP_2 = 322, 127 | GLFW_KEY_KP_3 = 323, 128 | GLFW_KEY_KP_4 = 324, 129 | GLFW_KEY_KP_5 = 325, 130 | GLFW_KEY_KP_6 = 326, 131 | GLFW_KEY_KP_7 = 327, 132 | GLFW_KEY_KP_8 = 328, 133 | GLFW_KEY_KP_9 = 329, 134 | GLFW_KEY_KP_DECIMAL = 330, 135 | GLFW_KEY_KP_DIVIDE = 331, 136 | GLFW_KEY_KP_MULTIPLY = 332, 137 | GLFW_KEY_KP_SUBTRACT = 333, 138 | GLFW_KEY_KP_ADD = 334, 139 | GLFW_KEY_KP_ENTER = 335, 140 | GLFW_KEY_KP_EQUAL = 336, 141 | GLFW_KEY_LEFT_SHIFT = 340, 142 | GLFW_KEY_LEFT_CONTROL = 341, 143 | GLFW_KEY_LEFT_ALT = 342, 144 | GLFW_KEY_LEFT_SUPER = 343, 145 | GLFW_KEY_RIGHT_SHIFT = 344, 146 | GLFW_KEY_RIGHT_CONTROL = 345, 147 | GLFW_KEY_RIGHT_ALT = 346, 148 | GLFW_KEY_RIGHT_SUPER = 347, 149 | GLFW_KEY_MENU = 348, 150 | GLFW_KEY_LAST = GLFW_KEY_MENU, 151 | 152 | GLFW_KEY_ESC = GLFW_KEY_ESCAPE, 153 | GLFW_KEY_DEL = GLFW_KEY_DELETE, 154 | GLFW_KEY_PAGEUP = GLFW_KEY_PAGE_UP, 155 | GLFW_KEY_PAGEDOWN = GLFW_KEY_PAGE_DOWN, 156 | GLFW_KEY_KP_NUM_LOCK = GLFW_KEY_NUM_LOCK, 157 | GLFW_KEY_LCTRL = GLFW_KEY_LEFT_CONTROL, 158 | GLFW_KEY_LSHIFT = GLFW_KEY_LEFT_SHIFT, 159 | GLFW_KEY_LALT = GLFW_KEY_LEFT_ALT, 160 | GLFW_KEY_LSUPER = GLFW_KEY_LEFT_SUPER, 161 | GLFW_KEY_RCTRL = GLFW_KEY_RIGHT_CONTROL, 162 | GLFW_KEY_RSHIFT = GLFW_KEY_RIGHT_SHIFT, 163 | GLFW_KEY_RALT = GLFW_KEY_RIGHT_ALT, 164 | GLFW_KEY_RSUPER = GLFW_KEY_RIGHT_SUPER, 165 | } 166 | 167 | enum { 168 | GLFW_MOD_SHIFT = 0x0001, 169 | GLFW_MOD_CONTROL = 0x0002, 170 | GLFW_MOD_ALT = 0x0004, 171 | GLFW_MOD_SUPER = 0x0008, 172 | GLFW_MOD_CAPS_LOCK = 0x0010, // Added in GLFW 3.3 173 | GLFW_MOD_NUM_LOCK = 0x0020, // ditto 174 | } 175 | 176 | enum { 177 | GLFW_MOUSE_BUTTON_1 = 0, 178 | GLFW_MOUSE_BUTTON_2 = 1, 179 | GLFW_MOUSE_BUTTON_3 = 2, 180 | GLFW_MOUSE_BUTTON_4 = 3, 181 | GLFW_MOUSE_BUTTON_5 = 4, 182 | GLFW_MOUSE_BUTTON_6 = 5, 183 | GLFW_MOUSE_BUTTON_7 = 6, 184 | GLFW_MOUSE_BUTTON_8 = 7, 185 | GLFW_MOUSE_BUTTON_LAST = GLFW_MOUSE_BUTTON_8, 186 | GLFW_MOUSE_BUTTON_LEFT = GLFW_MOUSE_BUTTON_1, 187 | GLFW_MOUSE_BUTTON_RIGHT = GLFW_MOUSE_BUTTON_2, 188 | GLFW_MOUSE_BUTTON_MIDDLE = GLFW_MOUSE_BUTTON_3, 189 | } 190 | 191 | enum { 192 | GLFW_JOYSTICK_1 = 0, 193 | GLFW_JOYSTICK_2 = 1, 194 | GLFW_JOYSTICK_3 = 2, 195 | GLFW_JOYSTICK_4 = 3, 196 | GLFW_JOYSTICK_5 = 4, 197 | GLFW_JOYSTICK_6 = 5, 198 | GLFW_JOYSTICK_7 = 6, 199 | GLFW_JOYSTICK_8 = 7, 200 | GLFW_JOYSTICK_9 = 8, 201 | GLFW_JOYSTICK_10 = 9, 202 | GLFW_JOYSTICK_11 = 10, 203 | GLFW_JOYSTICK_12 = 11, 204 | GLFW_JOYSTICK_13 = 12, 205 | GLFW_JOYSTICK_14 = 13, 206 | GLFW_JOYSTICK_15 = 14, 207 | GLFW_JOYSTICK_16 = 15, 208 | GLFW_JOYSTICK_LAST = GLFW_JOYSTICK_16, 209 | } 210 | 211 | // Added in GLFW 3.3 212 | enum { 213 | GLFW_GAMEPAD_BUTTON_A = 0, 214 | GLFW_GAMEPAD_BUTTON_B = 1, 215 | GLFW_GAMEPAD_BUTTON_X = 2, 216 | GLFW_GAMEPAD_BUTTON_Y = 3, 217 | GLFW_GAMEPAD_BUTTON_LEFT_BUMPER = 4, 218 | GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER = 5, 219 | GLFW_GAMEPAD_BUTTON_BACK = 6, 220 | GLFW_GAMEPAD_BUTTON_START = 7, 221 | GLFW_GAMEPAD_BUTTON_GUIDE = 8, 222 | GLFW_GAMEPAD_BUTTON_LEFT_THUMB = 9, 223 | GLFW_GAMEPAD_BUTTON_RIGHT_THUMB = 10, 224 | GLFW_GAMEPAD_BUTTON_DPAD_UP = 11, 225 | GLFW_GAMEPAD_BUTTON_DPAD_RIGHT = 12, 226 | GLFW_GAMEPAD_BUTTON_DPAD_DOWN = 13, 227 | GLFW_GAMEPAD_BUTTON_DPAD_LEFT = 14, 228 | GLFW_GAMEPAD_BUTTON_LAST = GLFW_GAMEPAD_BUTTON_DPAD_LEFT, 229 | 230 | GLFW_GAMEPAD_BUTTON_CROSS = GLFW_GAMEPAD_BUTTON_A, 231 | GLFW_GAMEPAD_BUTTON_CIRCLE = GLFW_GAMEPAD_BUTTON_B, 232 | GLFW_GAMEPAD_BUTTON_SQUARE = GLFW_GAMEPAD_BUTTON_X, 233 | GLFW_GAMEPAD_BUTTON_TRIANGLE = GLFW_GAMEPAD_BUTTON_Y, 234 | } 235 | 236 | // Added in GLFW 3.3 237 | enum { 238 | GLFW_GAMEPAD_AXIS_LEFT_X = 0, 239 | GLFW_GAMEPAD_AXIS_LEFT_Y = 1, 240 | GLFW_GAMEPAD_AXIS_RIGHT_X = 2, 241 | GLFW_GAMEPAD_AXIS_RIGHT_Y = 3, 242 | GLFW_GAMEPAD_AXIS_LEFT_TRIGGER = 4, 243 | GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER = 5, 244 | GLFW_GAMEPAD_AXIS_LAST = GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER, 245 | } 246 | 247 | enum { 248 | GLFW_NO_ERROR = 0, // Added in GLFW 3.3 249 | GLFW_NOT_INITIALIZED = 0x00010001, 250 | GLFW_NO_CURRENT_CONTEXT = 0x00010002, 251 | GLFW_INVALID_ENUM = 0x00010003, 252 | GLFW_INVALID_VALUE = 0x00010004, 253 | GLFW_OUT_OF_MEMORY = 0x00010005, 254 | GLFW_API_UNAVAILABLE = 0x00010006, 255 | GLFW_VERSION_UNAVAILABLE = 0x00010007, 256 | GLFW_PLATFORM_ERROR = 0x00010008, 257 | GLFW_FORMAT_UNAVAILABLE = 0x00010009, 258 | GLFW_NO_WINDOW_CONTEXT = 0x0001000A, // Added in GLFW 3.2 259 | } 260 | 261 | enum { 262 | GLFW_FOCUSED = 0x00020001, 263 | GLFW_ICONIFIED = 0x00020002, 264 | GLFW_RESIZABLE = 0x00020003, 265 | GLFW_VISIBLE = 0x00020004, 266 | GLFW_DECORATED = 0x00020005, 267 | GLFW_AUTO_ICONIFY = 0x00020006, // Added in GLFW 3.1 268 | GLFW_FLOATING = 0x00020007, // ditto 269 | GLFW_MAXIMIZED = 0x00020008, // Added in GLFW 3.2 270 | GLFW_CENTER_CURSOR = 0x00020009, // Added in GLFW 3.3 271 | GLFW_TRANSPARENT_FRAMEBUFFER = 0x0002000A, // ditto 272 | GLFW_HOVERED = 0x0002000B, // ditto 273 | GLFW_FOCUS_ON_SHOW = 0x0002000C, // ditto 274 | } 275 | 276 | enum { 277 | GLFW_RED_BITS = 0x00021001, 278 | GLFW_GREEN_BITS = 0x00021002, 279 | GLFW_BLUE_BITS = 0x00021003, 280 | GLFW_ALPHA_BITS = 0x00021004, 281 | GLFW_DEPTH_BITS = 0x00021005, 282 | GLFW_STENCIL_BITS = 0x00021006, 283 | GLFW_ACCUM_RED_BITS = 0x00021007, 284 | GLFW_ACCUM_GREEN_BITS = 0x00021008, 285 | GLFW_ACCUM_BLUE_BITS = 0x00021009, 286 | GLFW_ACCUM_ALPHA_BITS = 0x0002100A, 287 | GLFW_AUX_BUFFERS = 0x0002100B, 288 | GLFW_STEREO = 0x0002100C, 289 | GLFW_SAMPLES = 0x0002100D, 290 | GLFW_SRGB_CAPABLE = 0x0002100E, 291 | GLFW_REFRESH_RATE = 0x0002100F, 292 | GLFW_DOUBLEBUFFER = 0x00021010, // Added in GLFW 3.1 293 | } 294 | 295 | enum { 296 | GLFW_CLIENT_API = 0x00022001, 297 | GLFW_CONTEXT_VERSION_MAJOR = 0x00022002, 298 | GLFW_CONTEXT_VERSION_MINOR = 0x00022003, 299 | GLFW_CONTEXT_REVISION = 0x00022004, 300 | GLFW_CONTEXT_ROBUSTNESS = 0x00022005, 301 | GLFW_OPENGL_FORWARD_COMPAT = 0x00022006, 302 | GLFW_OPENGL_DEBUG_CONTEXT = 0x00022007, 303 | GLFW_OPENGL_PROFILE = 0x00022008, 304 | GLFW_CONTEXT_RELEASE_BEHAVIOR = 0x00022009, // Added in GLFW 3.1 305 | GLFW_CONTEXT_NO_ERROR = 0x0002200A, // Added in GLFW 3.2 306 | GLFW_CONTEXT_CREATION_API = 0x0002200B, // ditto 307 | GLFW_SCALE_TO_MONITOR = 0x0002200C, // Added in GLFW 3.3 308 | GLFW_COCOA_RETINA_FRAMEBUFFER = 0x00023001, // ditto 309 | GLFW_COCOA_FRAME_NAME = 0x00023002, // ditto 310 | GLFW_COCOA_GRAPHICS_SWITCHING = 0x00023003, // ditto 311 | GLFW_X11_CLASS_NAME = 0x00024001, // ditto 312 | GLFW_X11_INSTANCE_NAME = 0x00024002, // ditto 313 | } 314 | 315 | enum { 316 | GLFW_NO_API = 0, // Added in GLFW 3.2 317 | GLFW_OPENGL_API = 0x00030001, 318 | GLFW_OPENGL_ES_API = 0x00030002, 319 | 320 | GLFW_NO_ROBUSTNESS = 0, 321 | GLFW_NO_RESET_NOTIFICATION = 0x00031001, 322 | GLFW_LOSE_CONTEXT_ON_RESET = 0x00031002, 323 | 324 | GLFW_OPENGL_ANY_PROFILE = 0, 325 | GLFW_OPENGL_CORE_PROFILE = 0x00032001, 326 | GLFW_OPENGL_COMPAT_PROFILE = 0x00032002, 327 | 328 | GLFW_CURSOR = 0x00033001, 329 | GLFW_STICKY_KEYS = 0x00033002, 330 | GLFW_STICKY_MOUSE_BUTTONS = 0x00033003, 331 | GLFW_LOCK_KEY_MODS = 0x00033004, // Added in GLFW 3.3 332 | GLFW_RAW_MOUSE_MOTION = 0x00033005, // ditto 333 | 334 | GLFW_CURSOR_NORMAL = 0x00034001, 335 | GLFW_CURSOR_HIDDEN = 0x00034002, 336 | GLFW_CURSOR_DISABLED = 0x00034003, 337 | 338 | GLFW_ANY_RELEASE_BEHAVIOR = 0, // Added in GLFW 3.1 339 | GLFW_RELEASE_BEHAVIOR_FLUSH = 0x00035001, // ditto 340 | GLFW_RELEASE_BEHAVIOR_NONE = 0x00035002, // ditto 341 | 342 | GLFW_NATIVE_CONTEXT_API = 0x00036001, // Added in GLFW 3.1 343 | GLFW_EGL_CONTEXT_API = 0x00036002, // ditto 344 | GLFW_OSMESA_CONTEXT_API = 0x00036003, // Added in GLFW 3.3 345 | 346 | GLFW_ARROW_CURSOR = 0x00036001, // Added in GLFW 3.1 347 | GLFW_IBEAM_CURSOR = 0x00036002, // ditto 348 | GLFW_CROSSHAIR_CURSOR = 0x00036003, // ditto 349 | GLFW_HAND_CURSOR = 0x00036004, // ditto 350 | GLFW_HRESIZE_CURSOR = 0x00036005, // ditto 351 | GLFW_VRESIZE_CURSOR = 0x00036006, // ditto 352 | 353 | GLFW_CONNECTED = 0x00040001, 354 | GLFW_DISCONNECTED = 0x00040002, 355 | 356 | GLFW_JOYSTICK_HAT_BUTTONS = 0x00050001, // Added in GLFW 3.3 357 | GLFW_COCOA_CHDIR_RESOURCES = 0x00051001, // ditto 358 | GLFW_COCOA_MENUBAR = 0x00051002, // ditto 359 | } 360 | 361 | enum GLFW_DONT_CARE = -1; // Added in GLFW 3.1 362 | 363 | alias GLFWglproc = void function(); 364 | alias GLFWvkproc = void function(); 365 | alias GLFWerrorfun = void function(i32,u8*); 366 | alias GLFWwindowposfun = void function(GLFWwindow*,i32,i32); 367 | alias GLFWwindowsizefun = void function(GLFWwindow*,i32,i32); 368 | alias GLFWwindowclosefun = void function(GLFWwindow*); 369 | alias GLFWwindowrefreshfun = void function(GLFWwindow*); 370 | alias GLFWwindowfocusfun = void function(GLFWwindow*,i32); 371 | alias GLFWwindowiconifyfun = void function(GLFWwindow*,i32); 372 | alias GLFWwindowmaximizefun = void function(GLFWwindow*,i32); 373 | alias GLFWframebuffersizefun = void function(GLFWwindow*,i32,i32); 374 | alias GLFWwindowcontentscalefun = void function(GLFWwindow*,f32,f32); 375 | alias GLFWmousebuttonfun = void function(GLFWwindow*,i32,i32,i32); 376 | alias GLFWcursorposfun = void function(GLFWwindow*,f64,f64); 377 | alias GLFWcursorenterfun = void function(GLFWwindow*,i32); 378 | alias GLFWscrollfun = void function(GLFWwindow*,f64,f64); 379 | alias GLFWkeyfun = void function(GLFWwindow*,i32,i32,i32,i32); 380 | alias GLFWcharfun = void function(GLFWwindow*,u32); 381 | alias GLFWcharmodsfun = void function(GLFWwindow*,u32,i32); 382 | alias GLFWdropfun = void function(GLFWwindow*,i32,u8**); 383 | alias GLFWmonitorfun = void function(GLFWmonitor*,i32); 384 | alias GLFWjoystickfun = void function(i32,i32); 385 | 386 | struct GLFWmonitor; 387 | struct GLFWwindow; 388 | struct GLFWcursor; 389 | 390 | struct GLFWvidmode { 391 | i32 width; 392 | i32 height; 393 | i32 redBits; 394 | i32 greenBits; 395 | i32 blueBits; 396 | i32 refreshRate; 397 | } 398 | 399 | struct GLFWgammaramp { 400 | u16* red; 401 | u16* green; 402 | u16* blue; 403 | u32 size; 404 | } 405 | 406 | struct GLFWimage { 407 | i32 width; 408 | i32 height; 409 | u8* pixels; 410 | } 411 | 412 | struct GLFWgamepadstate { 413 | u8[15] buttons; 414 | f32[6] axes; 415 | } 416 | 417 | // 3.0 418 | i32 glfwInit(); 419 | void glfwTerminate(); 420 | void glfwGetVersion(i32*,i32*,i32*); 421 | u8* glfwGetVersionString(); 422 | GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun); 423 | GLFWmonitor** glfwGetMonitors(i32*); 424 | GLFWmonitor* glfwGetPrimaryMonitor(); 425 | void glfwGetMonitorPos(GLFWmonitor*,i32*,i32*); 426 | void glfwGetMonitorPhysicalSize(GLFWmonitor*,i32*,i32*); 427 | u8* glfwGetMonitorName(GLFWmonitor*); 428 | GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun); 429 | GLFWvidmode* glfwGetVideoModes(GLFWmonitor*,i32*); 430 | GLFWvidmode* glfwGetVideoMode(GLFWmonitor*); 431 | void glfwSetGamma(GLFWmonitor*,f32); 432 | GLFWgammaramp glfwGetGammaRamp(GLFWmonitor*); 433 | void glfwSetGammaRamp(GLFWmonitor*,GLFWgammaramp*); 434 | void glfwDefaultWindowHints(); 435 | void glfwWindowHint(i32,i32); 436 | GLFWwindow* glfwCreateWindow(i32,i32,u8*,GLFWmonitor*,GLFWwindow*); 437 | void glfwDestroyWindow(GLFWwindow*); 438 | i32 glfwWindowShouldClose(GLFWwindow*); 439 | void glfwSetWindowShouldClose(GLFWwindow*,i32); 440 | void glfwSetWindowTitle(GLFWwindow*,u8*); 441 | void glfwGetWindowPos(GLFWwindow*,i32*,i32*); 442 | void glfwSetWindowPos(GLFWwindow*,i32,i32); 443 | void glfwGetWindowSize(GLFWwindow*,i32*,i32*); 444 | void glfwSetWindowSize(GLFWwindow*,i32,i32); 445 | void glfwGetFramebufferSize(GLFWwindow*,i32*,i32*); 446 | void glfwIconifyWindow(GLFWwindow*); 447 | void glfwRestoreWindow(GLFWwindow*); 448 | void glfwShowWindow(GLFWwindow*); 449 | void glfwHideWindow(GLFWwindow*); 450 | GLFWmonitor* glfwGetWindowMonitor(GLFWwindow*); 451 | i32 glfwGetWindowAttrib(GLFWwindow*,i32); 452 | GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow*,GLFWwindowposfun); 453 | GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow*,GLFWwindowsizefun); 454 | GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow*,GLFWwindowclosefun); 455 | GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow*,GLFWwindowrefreshfun); 456 | GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow*,GLFWwindowfocusfun); 457 | GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow*,GLFWwindowiconifyfun); 458 | GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow*,GLFWframebuffersizefun); 459 | void glfwPollEvents(); 460 | void glfwWaitEvents(); 461 | i32 glfwGetInputMode(GLFWwindow*,i32); 462 | void glfwSetInputMode(GLFWwindow*,i32,i32); 463 | i32 glfwGetKey(GLFWwindow*,i32); 464 | i32 glfwGetMouseButton(GLFWwindow*,i32); 465 | void glfwGetCursorPos(GLFWwindow*,f64*,f64*); 466 | void glfwSetCursorPos(GLFWwindow*,f64,f64); 467 | GLFWkeyfun glfwSetKeyCallback(GLFWwindow*,GLFWkeyfun); 468 | GLFWcharfun glfwSetCharCallback(GLFWwindow*,GLFWcharfun); 469 | GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow*,GLFWmousebuttonfun); 470 | GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow*,GLFWcursorposfun); 471 | GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow*,GLFWcursorenterfun); 472 | GLFWscrollfun glfwSetScrollCallback(GLFWwindow*,GLFWscrollfun); 473 | void glfwSetWindowUserPointer(GLFWwindow* window, void* pointer); 474 | void* glfwGetWindowUserPointer(GLFWwindow* window); 475 | i32 glfwJoystickPresent(i32); 476 | f32* glfwGetJoystickAxes(i32,i32*); 477 | u8* glfwGetJoystickButtons(i32,i32*); 478 | u8* glfwGetJoystickName(i32); 479 | void glfwSetClipboardString(GLFWwindow*,u8*); 480 | u8* glfwGetClipboardString(GLFWwindow*); 481 | f64 glfwGetTime(); 482 | void glfwSetTime(f64); 483 | void glfwMakeContextCurrent(GLFWwindow*); 484 | GLFWwindow* glfwGetCurrentContext(); 485 | void glfwSwapBuffers(GLFWwindow*); 486 | i32 glfwExtensionSupported(u8*); 487 | GLFWglproc glfwGetProcAddress(u8*); 488 | 489 | // 3.1 490 | void glfwGetWindowFrameSize(GLFWwindow*,i32*,i32*,i32*,i32*); 491 | void glfwPostEmptyEvent(); 492 | GLFWcursor* glfwCreateCursor(GLFWimage*,i32,i32); 493 | GLFWcursor* glfwCreateStandardCursor(i32); 494 | void glfwDestroyCursor(GLFWcursor*); 495 | void glfwSetCursor(GLFWwindow*,GLFWcursor*); 496 | GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow*,GLFWcharmodsfun); 497 | GLFWdropfun glfwSetDropCallback(GLFWwindow*,GLFWdropfun); 498 | 499 | // 3.2 500 | void glfwSetWindowIcon(GLFWwindow*,i32,GLFWimage*); 501 | void glfwSetWindowSizeLimits(GLFWwindow*,i32,i32,i32,i32); 502 | void glfwSetWindowAspectRatio(GLFWwindow*,i32,i32); 503 | void glfwMaximizeWindow(GLFWwindow*); 504 | void glfwFocusWindow(GLFWwindow*); 505 | void glfwSetWindowMonitor(GLFWwindow*,GLFWmonitor*,i32,i32,i32,i32,i32); 506 | void glfwWaitEventsTimeout(f64); 507 | u8* glfwGetKeyName(i32,i32); 508 | i64 glfwGetTimerValue(); 509 | i64 glfwGetTimerFrequency(); 510 | i32 glfwVulkanSupported(); 511 | GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun); 512 | 513 | // 3.3 514 | i32 glfwGetError(u8**); 515 | void glfwGetMonitorWorkarea(GLFWmonitor*,i32*,i32*,i32*,i32*); 516 | void glfwGetMonitorContentScale(GLFWmonitor*,f32*,f32*); 517 | void glfwGetWindowContentScale(GLFWwindow*,f32*,f32*); 518 | f32 glfwGetWindowOpacity(GLFWwindow*); 519 | void glfwSetWindowOpacity(GLFWwindow*,f32); 520 | void glfwRequestWindowAttention(GLFWwindow*); 521 | void glfwSetWindowAttrib(GLFWwindow*,i32,i32); 522 | GLFWwindowmaximizefun glfwSetWindowMaximizeCallback(GLFWwindow*,GLFWwindowmaximizefun); 523 | GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow*,GLFWwindowcontentscalefun); 524 | i32 glfwGetKeyScancode(i32); 525 | u8* glfwGetJoystickHats(i32,i32*); 526 | u8* glfwGetJoystickGUID(i32); 527 | i32 glfwJoystickIsGamepad(i32); 528 | i32 glfwUpdateGamepadMappings(u8*); 529 | u8* glfwGetGamepadName(i32); 530 | i32 glfwGetGamepadState(i32,GLFWgamepadstate*); 531 | 532 | // Vulkan 533 | u8** glfwGetRequiredInstanceExtensions(u32*); 534 | GLFWvkproc glfwGetInstanceProcAddress(VkInstance,u8*); 535 | i32 glfwGetPhysicalDevicePresentationSupport(VkInstance,VkPhysicalDevice,u32); 536 | VkResult glfwCreateWindowSurface(VkInstance,GLFWwindow*,VkAllocationCallbacks*,VkSurfaceKHR*); 537 | -------------------------------------------------------------------------------- /plugins/core/src/core/vulkan/vma.vx: -------------------------------------------------------------------------------- 1 | /// Original license: 2 | /// Copyright (c) 2017-2022 Advanced Micro Devices, Inc. All rights reserved. 3 | /// License: MIT 4 | 5 | module core.vulkan.vma; 6 | 7 | import core.vulkan.types; 8 | import core.vulkan.functions; 9 | 10 | @extern(module, "vma"): 11 | 12 | /// Flags for created #VmaAllocator. 13 | enum VmaAllocatorCreateFlagBits : u32 14 | { 15 | VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT = 0x00000001, 16 | VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT = 0x00000002, 17 | VMA_ALLOCATOR_CREATE_KHR_BIND_MEMORY2_BIT = 0x00000004, 18 | VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT = 0x00000008, 19 | VMA_ALLOCATOR_CREATE_AMD_DEVICE_COHERENT_MEMORY_BIT = 0x00000010, 20 | VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT = 0x00000020, 21 | VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT = 0x00000040, 22 | 23 | VMA_ALLOCATOR_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF 24 | } 25 | 26 | /// See VmaAllocatorCreateFlagBits 27 | alias VmaAllocatorCreateFlags = VkFlags; 28 | 29 | 30 | /// Intended usage of the allocated memory. 31 | enum VmaMemoryUsage : u32 32 | { 33 | VMA_MEMORY_USAGE_UNKNOWN = 0, 34 | VMA_MEMORY_USAGE_GPU_ONLY = 1, 35 | VMA_MEMORY_USAGE_CPU_ONLY = 2, 36 | VMA_MEMORY_USAGE_CPU_TO_GPU = 3, 37 | VMA_MEMORY_USAGE_GPU_TO_CPU = 4, 38 | VMA_MEMORY_USAGE_CPU_COPY = 5, 39 | VMA_MEMORY_USAGE_GPU_LAZILY_ALLOCATED = 6, 40 | VMA_MEMORY_USAGE_AUTO = 7, 41 | VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE = 8, 42 | VMA_MEMORY_USAGE_AUTO_PREFER_HOST = 9, 43 | 44 | VMA_MEMORY_USAGE_MAX_ENUM = 0x7FFFFFFF 45 | } 46 | 47 | /// Flags to be passed as VmaAllocationCreateInfo::flags. 48 | enum VmaAllocationCreateFlagBits : u32 49 | { 50 | VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT = 0x00000001, 51 | VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT = 0x00000002, 52 | VMA_ALLOCATION_CREATE_MAPPED_BIT = 0x00000004, 53 | VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT = 0x00000020, 54 | VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT = 0x00000040, 55 | VMA_ALLOCATION_CREATE_DONT_BIND_BIT = 0x00000080, 56 | VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT = 0x00000100, 57 | VMA_ALLOCATION_CREATE_CAN_ALIAS_BIT = 0x00000200, 58 | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT = 0x00000400, 59 | VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT = 0x00000800, 60 | VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT = 0x00001000, 61 | VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT = 0x00010000, 62 | VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT = 0x00020000, 63 | VMA_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT = 0x00040000, 64 | VMA_ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT = VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT, 65 | VMA_ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT = VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT, 66 | VMA_ALLOCATION_CREATE_STRATEGY_MASK = 67 | VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT | 68 | VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT | 69 | VMA_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT, 70 | 71 | VMA_ALLOCATION_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF 72 | } 73 | 74 | /// See #VmaAllocationCreateFlagBits. 75 | alias VmaAllocationCreateFlags = VkFlags; 76 | 77 | /// Flags to be passed as VmaPoolCreateInfo::flags. 78 | enum VmaPoolCreateFlagBits : u32 79 | { 80 | VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT = 0x00000002, 81 | VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT = 0x00000004, 82 | VMA_POOL_CREATE_ALGORITHM_MASK = 83 | VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT, 84 | 85 | VMA_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF 86 | } 87 | 88 | /// Flags to be passed as VmaPoolCreateInfo::flags. See #VmaPoolCreateFlagBits. 89 | alias VmaPoolCreateFlags = VkFlags; 90 | 91 | /// Flags to be passed as VmaDefragmentationInfo::flags. 92 | enum VmaDefragmentationFlagBits : u32 93 | { 94 | VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FAST_BIT = 0x1, 95 | VMA_DEFRAGMENTATION_FLAG_ALGORITHM_BALANCED_BIT = 0x2, 96 | VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FULL_BIT = 0x4, 97 | VMA_DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT = 0x8, 98 | 99 | /// A bit mask to extract only `ALGORITHM` bits from entire set of flags. 100 | VMA_DEFRAGMENTATION_FLAG_ALGORITHM_MASK = 101 | VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FAST_BIT | 102 | VMA_DEFRAGMENTATION_FLAG_ALGORITHM_BALANCED_BIT | 103 | VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FULL_BIT | 104 | VMA_DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT, 105 | 106 | VMA_DEFRAGMENTATION_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF 107 | } 108 | 109 | /// See #VmaDefragmentationFlagBits. 110 | alias VmaDefragmentationFlags = VkFlags; 111 | 112 | /// Operation performed on single defragmentation move. See structure #VmaDefragmentationMove. 113 | enum VmaDefragmentationMoveOperation : u32 114 | { 115 | /// Buffer/image has been recreated at `dstTmpAllocation`, data has been copied, old buffer/image has been destroyed. `srcAllocation` should be changed to point to the new place. This is the default value set by vmaBeginDefragmentationPass(). 116 | VMA_DEFRAGMENTATION_MOVE_OPERATION_COPY = 0, 117 | /// Set this value if you cannot move the allocation. New place reserved at `dstTmpAllocation` will be freed. `srcAllocation` will remain unchanged. 118 | VMA_DEFRAGMENTATION_MOVE_OPERATION_IGNORE = 1, 119 | /// Set this value if you decide to abandon the allocation and you destroyed the buffer/image. New place reserved at `dstTmpAllocation` will be freed, along with `srcAllocation`, which will be destroyed. 120 | VMA_DEFRAGMENTATION_MOVE_OPERATION_DESTROY = 2, 121 | } 122 | 123 | 124 | /// Flags to be passed as VmaVirtualBlockCreateInfo::flags. 125 | enum VmaVirtualBlockCreateFlagBits : u32 126 | { 127 | VMA_VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT = 0x00000001, 128 | VMA_VIRTUAL_BLOCK_CREATE_ALGORITHM_MASK = 129 | VMA_VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT, 130 | 131 | VMA_VIRTUAL_BLOCK_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF 132 | } 133 | 134 | /// Flags to be passed as VmaVirtualBlockCreateInfo::flags. See #VmaVirtualBlockCreateFlagBits. 135 | alias VmaVirtualBlockCreateFlags = VkFlags; 136 | 137 | /// Flags to be passed as VmaVirtualAllocationCreateInfo::flags. 138 | enum VmaVirtualAllocationCreateFlagBits : u32 139 | { 140 | VMA_VIRTUAL_ALLOCATION_CREATE_UPPER_ADDRESS_BIT = VmaAllocationCreateFlagBits.VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT, 141 | VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT = VmaAllocationCreateFlagBits.VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT, 142 | VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT = VmaAllocationCreateFlagBits.VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT, 143 | VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT = VmaAllocationCreateFlagBits.VMA_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT, 144 | VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MASK = VmaAllocationCreateFlagBits.VMA_ALLOCATION_CREATE_STRATEGY_MASK, 145 | 146 | VMA_VIRTUAL_ALLOCATION_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF 147 | } 148 | 149 | /// Flags to be passed as VmaVirtualAllocationCreateInfo::flags. See #VmaVirtualAllocationCreateFlagBits. 150 | alias VmaVirtualAllocationCreateFlags = VkFlags; 151 | 152 | struct VmaAllocator_handle; alias VmaAllocator = VmaAllocator_handle*; 153 | struct VmaPool_handle; alias VmaPool = VmaPool_handle*; 154 | struct VmaAllocation_handle; alias VmaAllocation = VmaAllocation_handle*; 155 | struct VmaDefragmentationContext_handle; alias VmaDefragmentationContext = VmaDefragmentationContext_handle*; 156 | struct VmaVirtualBlock_handle; alias VmaVirtualBlock = VmaVirtualBlock_handle*; 157 | struct VmaVirtualAllocation_handle; alias VmaVirtualAllocation = VmaVirtualAllocation_handle*; 158 | struct VmaAllocHandle_handle; alias VmaAllocHandle = VmaAllocHandle_handle*; 159 | 160 | VkResult vmaCreateAllocator(VmaAllocatorCreateInfo* pCreateInfo, VmaAllocator* pAllocator); 161 | void vmaDestroyAllocator(VmaAllocator allocator); 162 | void vmaGetAllocatorInfo(VmaAllocator allocator, VmaAllocatorInfo* pAllocatorInfo); 163 | void vmaGetPhysicalDeviceProperties(VmaAllocator allocator, VkPhysicalDeviceProperties** ppPhysicalDeviceProperties); 164 | void vmaGetMemoryProperties(VmaAllocator allocator, VkPhysicalDeviceMemoryProperties** ppPhysicalDeviceMemoryProperties); 165 | void vmaGetMemoryTypeProperties(VmaAllocator allocator, u32 memoryTypeIndex, VkMemoryPropertyFlags* pFlags); 166 | void vmaSetCurrentFrameIndex(VmaAllocator allocator, u32 frameIndex); 167 | void vmaCalculateStatistics(VmaAllocator allocator, VmaTotalStatistics* pStats); 168 | void vmaGetHeapBudgets(VmaAllocator allocator, VmaBudget* pBudgets); 169 | VkResult vmaFindMemoryTypeIndex(VmaAllocator allocator, u32 memoryTypeBits, VmaAllocationCreateInfo* pAllocationCreateInfo, u32* pMemoryTypeIndex); 170 | VkResult vmaFindMemoryTypeIndexForBufferInfo(VmaAllocator allocator, VkBufferCreateInfo* pBufferCreateInfo, VmaAllocationCreateInfo* pAllocationCreateInfo, u32* pMemoryTypeIndex); 171 | VkResult vmaFindMemoryTypeIndexForImageInfo(VmaAllocator allocator, VkImageCreateInfo* pImageCreateInfo, VmaAllocationCreateInfo* pAllocationCreateInfo, u32* pMemoryTypeIndex); 172 | VkResult vmaCreatePool(VmaAllocator allocator, VmaPoolCreateInfo* pCreateInfo, VmaPool* pPool); 173 | void vmaDestroyPool(VmaAllocator allocator, VmaPool pool); 174 | void vmaGetPoolStatistics(VmaAllocator allocator, VmaPool pool, VmaStatistics* pPoolStats); 175 | void vmaCalculatePoolStatistics(VmaAllocator allocator, VmaPool pool, VmaDetailedStatistics* pPoolStats); 176 | VkResult vmaCheckPoolCorruption(VmaAllocator allocator, VmaPool pool); 177 | void vmaGetPoolName(VmaAllocator allocator, VmaPool pool, u8** ppName); 178 | void vmaSetPoolName(VmaAllocator allocator, VmaPool pool, u8* pName); 179 | VkResult vmaAllocateMemory(VmaAllocator allocator, VkMemoryRequirements* pVkMemoryRequirements, VmaAllocationCreateInfo* pCreateInfo, VmaAllocation* pAllocation, VmaAllocationInfo* pAllocationInfo); 180 | VkResult vmaAllocateMemoryPages(VmaAllocator allocator, VkMemoryRequirements* pVkMemoryRequirements, VmaAllocationCreateInfo* pCreateInfo, u64 allocationCount, VmaAllocation* pAllocations, VmaAllocationInfo* pAllocationInfo); 181 | VkResult vmaAllocateMemoryForBuffer(VmaAllocator allocator, VkBuffer buffer, VmaAllocationCreateInfo* pCreateInfo, VmaAllocation* pAllocation, VmaAllocationInfo* pAllocationInfo); 182 | VkResult vmaAllocateMemoryForImage(VmaAllocator allocator, VkImage image, VmaAllocationCreateInfo* pCreateInfo, VmaAllocation* pAllocation, VmaAllocationInfo* pAllocationInfo); 183 | void vmaFreeMemory(VmaAllocator allocator, VmaAllocation allocation); 184 | void vmaFreeMemoryPages(VmaAllocator allocator, u64 allocationCount, VmaAllocation* pAllocations); 185 | void vmaGetAllocationInfo(VmaAllocator allocator, VmaAllocation allocation, VmaAllocationInfo* pAllocationInfo); 186 | void vmaSetAllocationUserData(VmaAllocator allocator, VmaAllocation allocation, void* pUserData); 187 | void vmaSetAllocationName(VmaAllocator allocator, VmaAllocation allocation, u8* pName); 188 | void vmaGetAllocationMemoryProperties(VmaAllocator allocator, VmaAllocation allocation, VkMemoryPropertyFlags* pFlags); 189 | VkResult vmaMapMemory(VmaAllocator allocator, VmaAllocation allocation, void** ppData); 190 | void vmaUnmapMemory(VmaAllocator allocator, VmaAllocation allocation); 191 | VkResult vmaFlushAllocation(VmaAllocator allocator, VmaAllocation allocation, VkDeviceSize offset, VkDeviceSize size); 192 | VkResult vmaInvalidateAllocation(VmaAllocator allocator, VmaAllocation allocation, VkDeviceSize offset, VkDeviceSize size); 193 | VkResult vmaFlushAllocations(VmaAllocator allocator, u32 allocationCount, VmaAllocation* allocations, VkDeviceSize* offsets, VkDeviceSize* sizes); 194 | VkResult vmaInvalidateAllocations(VmaAllocator allocator, u32 allocationCount, VmaAllocation* allocations, VkDeviceSize* offsets, VkDeviceSize* sizes); 195 | VkResult vmaCheckCorruption(VmaAllocator allocator, u32 memoryTypeBits); 196 | VkResult vmaBeginDefragmentation(VmaAllocator allocator, VmaDefragmentationInfo* pInfo, VmaDefragmentationContext* pContext); 197 | void vmaEndDefragmentation(VmaAllocator allocator, VmaDefragmentationContext context, VmaDefragmentationStats* pStats); 198 | VkResult vmaBeginDefragmentationPass(VmaAllocator allocator, VmaDefragmentationContext context, VmaDefragmentationPassMoveInfo* pPassInfo); 199 | VkResult vmaEndDefragmentationPass(VmaAllocator allocator, VmaDefragmentationContext context, VmaDefragmentationPassMoveInfo* pPassInfo); 200 | VkResult vmaBindBufferMemory(VmaAllocator allocator, VmaAllocation allocation, VkBuffer buffer); 201 | VkResult vmaBindBufferMemory2(VmaAllocator allocator, VmaAllocation allocation, VkDeviceSize allocationLocalOffset, VkBuffer buffer, void* pNext); 202 | VkResult vmaBindImageMemory(VmaAllocator allocator, VmaAllocation allocation, VkImage image); 203 | VkResult vmaBindImageMemory2(VmaAllocator allocator, VmaAllocation allocation, VkDeviceSize allocationLocalOffset, VkImage image, void* pNext); 204 | VkResult vmaCreateBuffer(VmaAllocator allocator, VkBufferCreateInfo* pBufferCreateInfo, VmaAllocationCreateInfo* pAllocationCreateInfo, VkBuffer* pBuffer, VmaAllocation* pAllocation, VmaAllocationInfo* pAllocationInfo); 205 | VkResult vmaCreateBufferWithAlignment(VmaAllocator allocator, VkBufferCreateInfo* pBufferCreateInfo, VmaAllocationCreateInfo* pAllocationCreateInfo, VkDeviceSize minAlignment, VkBuffer* pBuffer, VmaAllocation* pAllocation, VmaAllocationInfo* pAllocationInfo); 206 | VkResult vmaCreateAliasingBuffer(VmaAllocator allocator, VmaAllocation allocation, VkBufferCreateInfo* pBufferCreateInfo, VkBuffer* pBuffer); 207 | void vmaDestroyBuffer(VmaAllocator allocator, VkBuffer buffer, VmaAllocation allocation); 208 | VkResult vmaCreateImage(VmaAllocator allocator, VkImageCreateInfo* pImageCreateInfo, VmaAllocationCreateInfo* pAllocationCreateInfo, VkImage* pImage, VmaAllocation* pAllocation, VmaAllocationInfo* pAllocationInfo); 209 | VkResult vmaCreateAliasingImage(VmaAllocator allocator, VmaAllocation allocation, VkImageCreateInfo* pImageCreateInfo, VkImage* pImage); 210 | void vmaDestroyImage(VmaAllocator allocator, VkImage image, VmaAllocation allocation); 211 | VkResult vmaCreateVirtualBlock(VmaVirtualBlockCreateInfo* pCreateInfo, VmaVirtualBlock* pVirtualBlock); 212 | void vmaDestroyVirtualBlock(VmaVirtualBlock virtualBlock); 213 | VkBool32 vmaIsVirtualBlockEmpty(VmaVirtualBlock virtualBlock); 214 | void vmaGetVirtualAllocationInfo(VmaVirtualBlock virtualBlock, VmaVirtualAllocation allocation, VmaVirtualAllocationInfo* pVirtualAllocInfo); 215 | VkResult vmaVirtualAllocate(VmaVirtualBlock virtualBlock, VmaVirtualAllocationCreateInfo* pCreateInfo, VmaVirtualAllocation* pAllocation, VkDeviceSize* pOffset); 216 | void vmaVirtualFree(VmaVirtualBlock virtualBlock, VmaVirtualAllocation allocation); 217 | void vmaClearVirtualBlock(VmaVirtualBlock virtualBlock); 218 | void vmaSetVirtualAllocationUserData(VmaVirtualBlock virtualBlock, VmaVirtualAllocation allocation, void* pUserData); 219 | void vmaGetVirtualBlockStatistics(VmaVirtualBlock virtualBlock, VmaStatistics* pStats); 220 | void vmaCalculateVirtualBlockStatistics(VmaVirtualBlock virtualBlock, VmaDetailedStatistics* pStats); 221 | 222 | 223 | /// Callback function called after successful vkAllocateMemory. 224 | alias PFN_vmaAllocateDeviceMemoryFunction = void function( 225 | VmaAllocator allocator, 226 | u32 memoryType, 227 | VkDeviceMemory memory, 228 | VkDeviceSize size, 229 | void* pUserData); 230 | 231 | /// Callback function called before vkFreeMemory. 232 | alias PFN_vmaFreeDeviceMemoryFunction = void function ( 233 | VmaAllocator allocator, 234 | u32 memoryType, 235 | VkDeviceMemory memory, 236 | VkDeviceSize size, 237 | void* pUserData); 238 | 239 | struct VmaDeviceMemoryCallbacks 240 | { 241 | /// Optional, can be null. 242 | PFN_vmaAllocateDeviceMemoryFunction pfnAllocate; 243 | /// Optional, can be null. 244 | PFN_vmaFreeDeviceMemoryFunction pfnFree; 245 | /// Optional, can be null. 246 | void* pUserData; 247 | } 248 | 249 | struct VmaVulkanFunctions 250 | { 251 | /// Required when using VMA_DYNAMIC_VULKAN_FUNCTIONS. 252 | PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr; 253 | /// Required when using VMA_DYNAMIC_VULKAN_FUNCTIONS. 254 | PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr; 255 | PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties; 256 | PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties; 257 | PFN_vkAllocateMemory vkAllocateMemory; 258 | PFN_vkFreeMemory vkFreeMemory; 259 | PFN_vkMapMemory vkMapMemory; 260 | PFN_vkUnmapMemory vkUnmapMemory; 261 | PFN_vkFlushMappedMemoryRanges vkFlushMappedMemoryRanges; 262 | PFN_vkInvalidateMappedMemoryRanges vkInvalidateMappedMemoryRanges; 263 | PFN_vkBindBufferMemory vkBindBufferMemory; 264 | PFN_vkBindImageMemory vkBindImageMemory; 265 | PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements; 266 | PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements; 267 | PFN_vkCreateBuffer vkCreateBuffer; 268 | PFN_vkDestroyBuffer vkDestroyBuffer; 269 | PFN_vkCreateImage vkCreateImage; 270 | PFN_vkDestroyImage vkDestroyImage; 271 | PFN_vkCmdCopyBuffer vkCmdCopyBuffer; 272 | /// Fetch "vkGetBufferMemoryRequirements2" on Vulkan >= 1.1, fetch "vkGetBufferMemoryRequirements2KHR" when using VK_KHR_dedicated_allocation extension. 273 | PFN_vkGetBufferMemoryRequirements2 vkGetBufferMemoryRequirements2KHR; 274 | /// Fetch "vkGetImageMemoryRequirements 2" on Vulkan >= 1.1, fetch "vkGetImageMemoryRequirements2KHR" when using VK_KHR_dedicated_allocation extension. 275 | PFN_vkGetImageMemoryRequirements2 vkGetImageMemoryRequirements2KHR; 276 | /// Fetch "vkBindBufferMemory2" on Vulkan >= 1.1, fetch "vkBindBufferMemory2KHR" when using VK_KHR_bind_memory2 extension. 277 | PFN_vkBindBufferMemory2 vkBindBufferMemory2KHR; 278 | /// Fetch "vkBindImageMemory2" on Vulkan >= 1.1, fetch "vkBindImageMemory2KHR" when using VK_KHR_bind_memory2 extension. 279 | PFN_vkBindImageMemory2 vkBindImageMemory2KHR; 280 | PFN_vkGetPhysicalDeviceMemoryProperties2 vkGetPhysicalDeviceMemoryProperties2KHR; 281 | /// Fetch from "vkGetDeviceBufferMemoryRequirements" on Vulkan >= 1.3, but you can also fetch it from "vkGetDeviceBufferMemoryRequirementsKHR" if you enabled extension VK_KHR_maintenance4. 282 | PFN_vkGetDeviceBufferMemoryRequirements vkGetDeviceBufferMemoryRequirements; 283 | /// Fetch from "vkGetDeviceImageMemoryRequirements" on Vulkan >= 1.3, but you can also fetch it from "vkGetDeviceImageMemoryRequirementsKHR" if you enabled extension VK_KHR_maintenance4. 284 | PFN_vkGetDeviceImageMemoryRequirements vkGetDeviceImageMemoryRequirements; 285 | } 286 | 287 | struct VmaAllocatorInfo 288 | { 289 | VkInstance instance; 290 | VkPhysicalDevice physicalDevice; 291 | VkDevice device; 292 | } 293 | 294 | struct VmaStatistics 295 | { 296 | u32 blockCount; 297 | u32 allocationCount; 298 | VkDeviceSize blockBytes; 299 | VkDeviceSize allocationBytes; 300 | } 301 | 302 | struct VmaDetailedStatistics 303 | { 304 | VmaStatistics statistics; 305 | u32 unusedRangeCount; 306 | VkDeviceSize allocationSizeMin; 307 | VkDeviceSize allocationSizeMax; 308 | VkDeviceSize unusedRangeSizeMin; 309 | VkDeviceSize unusedRangeSizeMax; 310 | } 311 | 312 | struct VmaTotalStatistics 313 | { 314 | VmaDetailedStatistics[VK_MAX_MEMORY_TYPES] memoryType; 315 | VmaDetailedStatistics[VK_MAX_MEMORY_HEAPS] memoryHeap; 316 | VmaDetailedStatistics total; 317 | } 318 | 319 | struct VmaBudget 320 | { 321 | VmaStatistics statistics; 322 | VkDeviceSize usage; 323 | VkDeviceSize budget; 324 | } 325 | 326 | struct VmaAllocationCreateInfo 327 | { 328 | VmaAllocationCreateFlags flags; 329 | VmaMemoryUsage usage; 330 | VkMemoryPropertyFlags requiredFlags; 331 | VkMemoryPropertyFlags preferredFlags; 332 | u32 memoryTypeBits; 333 | VmaPool pool; 334 | void* pUserData; 335 | float priority; 336 | } 337 | 338 | struct VmaPoolCreateInfo 339 | { 340 | u32 memoryTypeIndex; 341 | VmaPoolCreateFlags flags; 342 | VkDeviceSize blockSize; 343 | u64 minBlockCount; 344 | u64 maxBlockCount; 345 | float priority; 346 | VkDeviceSize minAllocationAlignment; 347 | void* pMemoryAllocateNext; 348 | } 349 | 350 | struct VmaAllocationInfo 351 | { 352 | u32 memoryType; 353 | VkDeviceMemory deviceMemory; 354 | VkDeviceSize offset; 355 | VkDeviceSize size; 356 | void* pMappedData; 357 | void* pUserData; 358 | u8* pName; 359 | } 360 | 361 | struct VmaDefragmentationInfo 362 | { 363 | VmaDefragmentationFlags flags; 364 | VmaPool pool; 365 | VkDeviceSize maxBytesPerPass; 366 | u32 maxAllocationsPerPass; 367 | } 368 | 369 | struct VmaDefragmentationMove 370 | { 371 | VmaDefragmentationMoveOperation operation; 372 | VmaAllocation srcAllocation; 373 | VmaAllocation dstTmpAllocation; 374 | } 375 | 376 | struct VmaDefragmentationPassMoveInfo 377 | { 378 | u32 moveCount; 379 | VmaDefragmentationMove* pMoves; 380 | } 381 | 382 | struct VmaDefragmentationStats 383 | { 384 | VkDeviceSize bytesMoved; 385 | VkDeviceSize bytesFreed; 386 | u32 allocationsMoved; 387 | u32 deviceMemoryBlocksFreed; 388 | } 389 | 390 | struct VmaVirtualBlockCreateInfo 391 | { 392 | VkDeviceSize size; 393 | VmaVirtualBlockCreateFlags flags; 394 | VkAllocationCallbacks* pAllocationCallbacks; 395 | } 396 | 397 | struct VmaVirtualAllocationCreateInfo 398 | { 399 | VkDeviceSize size; 400 | VkDeviceSize alignment; 401 | VmaVirtualAllocationCreateFlags flags; 402 | void* pUserData; 403 | } 404 | 405 | struct VmaVirtualAllocationInfo 406 | { 407 | VkDeviceSize offset; 408 | VkDeviceSize size; 409 | void* pUserData; 410 | } 411 | 412 | struct VmaAllocatorCreateInfo 413 | { 414 | VmaAllocatorCreateFlags flags; 415 | VkPhysicalDevice physicalDevice; 416 | VkDevice device; 417 | VkDeviceSize preferredLargeHeapBlockSize; 418 | VkAllocationCallbacks* pAllocationCallbacks; 419 | VmaDeviceMemoryCallbacks* pDeviceMemoryCallbacks; 420 | VkDeviceSize* pHeapSizeLimit; 421 | VmaVulkanFunctions* pVulkanFunctions; 422 | VkInstance instance; 423 | u32 vulkanApiVersion; 424 | VkExternalMemoryHandleTypeFlagsKHR* pTypeExternalMemoryHandleTypes; 425 | } 426 | -------------------------------------------------------------------------------- /plugins/core/src/core/shaderc.vx: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Shaderc Authors. All rights reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Translated to Vox from https://github.com/google/shaderc 16 | // Copyright: Copyright (c) 2021 Andrey Penechko. 17 | // License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0). 18 | // Authors: Andrey Penechko. 19 | 20 | // https://github.com/google/shaderc/blob/main/libshaderc/include/shaderc/env.h 21 | // https://github.com/google/shaderc/blob/main/libshaderc/include/shaderc/shaderc.h 22 | // https://github.com/google/shaderc/blob/main/libshaderc/include/shaderc/status.h 23 | 24 | module core.shaderc; 25 | @extern(module, "shaderc"): 26 | 27 | alias char = u8; 28 | 29 | // Source language kind. 30 | enum shaderc_source_language { 31 | shaderc_source_language_glsl = 0, 32 | shaderc_source_language_hlsl = 1, 33 | } 34 | 35 | enum shaderc_shader_kind { 36 | // Forced shader kinds. These shader kinds force the compiler to compile the 37 | // source code as the specified kind of shader. 38 | shaderc_vertex_shader = 0, 39 | shaderc_fragment_shader = 1, 40 | shaderc_compute_shader = 2, 41 | shaderc_geometry_shader = 3, 42 | shaderc_tess_control_shader = 4, 43 | shaderc_tess_evaluation_shader = 5, 44 | 45 | shaderc_glsl_vertex_shader = shaderc_vertex_shader, 46 | shaderc_glsl_fragment_shader = shaderc_fragment_shader, 47 | shaderc_glsl_compute_shader = shaderc_compute_shader, 48 | shaderc_glsl_geometry_shader = shaderc_geometry_shader, 49 | shaderc_glsl_tess_control_shader = shaderc_tess_control_shader, 50 | shaderc_glsl_tess_evaluation_shader = shaderc_tess_evaluation_shader, 51 | 52 | // Deduce the shader kind from #pragma annotation in the source code. Compiler 53 | // will emit error if #pragma annotation is not found. 54 | shaderc_glsl_infer_from_source = 6, 55 | // Default shader kinds. Compiler will fall back to compile the source code as 56 | // the specified kind of shader when #pragma annotation is not found in the 57 | // source code. 58 | shaderc_glsl_default_vertex_shader = 7, 59 | shaderc_glsl_default_fragment_shader = 8, 60 | shaderc_glsl_default_compute_shader = 9, 61 | shaderc_glsl_default_geometry_shader = 10, 62 | shaderc_glsl_default_tess_control_shader = 11, 63 | shaderc_glsl_default_tess_evaluation_shader = 12, 64 | shaderc_spirv_assembly = 13, 65 | shaderc_raygen_shader = 14, 66 | shaderc_anyhit_shader = 15, 67 | shaderc_closesthit_shader = 16, 68 | shaderc_miss_shader = 17, 69 | shaderc_intersection_shader = 18, 70 | shaderc_callable_shader = 19, 71 | shaderc_glsl_raygen_shader = shaderc_raygen_shader, 72 | shaderc_glsl_anyhit_shader = shaderc_anyhit_shader, 73 | shaderc_glsl_closesthit_shader = shaderc_closesthit_shader, 74 | shaderc_glsl_miss_shader = shaderc_miss_shader, 75 | shaderc_glsl_intersection_shader = shaderc_intersection_shader, 76 | shaderc_glsl_callable_shader = shaderc_callable_shader, 77 | shaderc_glsl_default_raygen_shader = 20, 78 | shaderc_glsl_default_anyhit_shader = 21, 79 | shaderc_glsl_default_closesthit_shader = 22, 80 | shaderc_glsl_default_miss_shader = 23, 81 | shaderc_glsl_default_intersection_shader = 24, 82 | shaderc_glsl_default_callable_shader = 25, 83 | shaderc_task_shader = 26, 84 | shaderc_mesh_shader = 27, 85 | shaderc_glsl_task_shader = shaderc_task_shader, 86 | shaderc_glsl_mesh_shader = shaderc_mesh_shader, 87 | shaderc_glsl_default_task_shader = 28, 88 | shaderc_glsl_default_mesh_shader = 29, 89 | } 90 | 91 | enum shaderc_profile { 92 | shaderc_profile_none = 0, // Used if and only if GLSL version did not specify 93 | // profiles. 94 | shaderc_profile_core = 1, 95 | shaderc_profile_compatibility = 2, // Disabled. This generates an error 96 | shaderc_profile_es = 3, 97 | } 98 | 99 | // Optimization level. 100 | enum shaderc_optimization_level { 101 | shaderc_optimization_level_zero = 0, // no optimization 102 | shaderc_optimization_level_size = 1, // optimize towards reducing code size 103 | shaderc_optimization_level_performance = 2, // optimize towards performance 104 | } 105 | 106 | // Resource limits. 107 | enum shaderc_limit { 108 | shaderc_limit_max_lights = 0, 109 | shaderc_limit_max_clip_planes = 1, 110 | shaderc_limit_max_texture_units = 2, 111 | shaderc_limit_max_texture_coords = 3, 112 | shaderc_limit_max_vertex_attribs = 4, 113 | shaderc_limit_max_vertex_uniform_components = 5, 114 | shaderc_limit_max_varying_floats = 6, 115 | shaderc_limit_max_vertex_texture_image_units = 7, 116 | shaderc_limit_max_combined_texture_image_units = 8, 117 | shaderc_limit_max_texture_image_units = 9, 118 | shaderc_limit_max_fragment_uniform_components = 10, 119 | shaderc_limit_max_draw_buffers = 11, 120 | shaderc_limit_max_vertex_uniform_vectors = 12, 121 | shaderc_limit_max_varying_vectors = 13, 122 | shaderc_limit_max_fragment_uniform_vectors = 14, 123 | shaderc_limit_max_vertex_output_vectors = 15, 124 | shaderc_limit_max_fragment_input_vectors = 16, 125 | shaderc_limit_min_program_texel_offset = 17, 126 | shaderc_limit_max_program_texel_offset = 18, 127 | shaderc_limit_max_clip_distances = 19, 128 | shaderc_limit_max_compute_work_group_count_x = 20, 129 | shaderc_limit_max_compute_work_group_count_y = 21, 130 | shaderc_limit_max_compute_work_group_count_z = 22, 131 | shaderc_limit_max_compute_work_group_size_x = 23, 132 | shaderc_limit_max_compute_work_group_size_y = 24, 133 | shaderc_limit_max_compute_work_group_size_z = 25, 134 | shaderc_limit_max_compute_uniform_components = 26, 135 | shaderc_limit_max_compute_texture_image_units = 27, 136 | shaderc_limit_max_compute_image_uniforms = 28, 137 | shaderc_limit_max_compute_atomic_counters = 29, 138 | shaderc_limit_max_compute_atomic_counter_buffers = 30, 139 | shaderc_limit_max_varying_components = 31, 140 | shaderc_limit_max_vertex_output_components = 32, 141 | shaderc_limit_max_geometry_input_components = 33, 142 | shaderc_limit_max_geometry_output_components = 34, 143 | shaderc_limit_max_fragment_input_components = 35, 144 | shaderc_limit_max_image_units = 36, 145 | shaderc_limit_max_combined_image_units_and_fragment_outputs = 37, 146 | shaderc_limit_max_combined_shader_output_resources = 38, 147 | shaderc_limit_max_image_samples = 39, 148 | shaderc_limit_max_vertex_image_uniforms = 40, 149 | shaderc_limit_max_tess_control_image_uniforms = 41, 150 | shaderc_limit_max_tess_evaluation_image_uniforms = 42, 151 | shaderc_limit_max_geometry_image_uniforms = 43, 152 | shaderc_limit_max_fragment_image_uniforms = 44, 153 | shaderc_limit_max_combined_image_uniforms = 45, 154 | shaderc_limit_max_geometry_texture_image_units = 46, 155 | shaderc_limit_max_geometry_output_vertices = 47, 156 | shaderc_limit_max_geometry_total_output_components = 48, 157 | shaderc_limit_max_geometry_uniform_components = 49, 158 | shaderc_limit_max_geometry_varying_components = 50, 159 | shaderc_limit_max_tess_control_input_components = 51, 160 | shaderc_limit_max_tess_control_output_components = 52, 161 | shaderc_limit_max_tess_control_texture_image_units = 53, 162 | shaderc_limit_max_tess_control_uniform_components = 54, 163 | shaderc_limit_max_tess_control_total_output_components = 55, 164 | shaderc_limit_max_tess_evaluation_input_components = 56, 165 | shaderc_limit_max_tess_evaluation_output_components = 57, 166 | shaderc_limit_max_tess_evaluation_texture_image_units = 58, 167 | shaderc_limit_max_tess_evaluation_uniform_components = 59, 168 | shaderc_limit_max_tess_patch_components = 60, 169 | shaderc_limit_max_patch_vertices = 61, 170 | shaderc_limit_max_tess_gen_level = 62, 171 | shaderc_limit_max_viewports = 63, 172 | shaderc_limit_max_vertex_atomic_counters = 64, 173 | shaderc_limit_max_tess_control_atomic_counters = 65, 174 | shaderc_limit_max_tess_evaluation_atomic_counters = 66, 175 | shaderc_limit_max_geometry_atomic_counters = 67, 176 | shaderc_limit_max_fragment_atomic_counters = 68, 177 | shaderc_limit_max_combined_atomic_counters = 69, 178 | shaderc_limit_max_atomic_counter_bindings = 70, 179 | shaderc_limit_max_vertex_atomic_counter_buffers = 71, 180 | shaderc_limit_max_tess_control_atomic_counter_buffers = 72, 181 | shaderc_limit_max_tess_evaluation_atomic_counter_buffers = 73, 182 | shaderc_limit_max_geometry_atomic_counter_buffers = 74, 183 | shaderc_limit_max_fragment_atomic_counter_buffers = 75, 184 | shaderc_limit_max_combined_atomic_counter_buffers = 76, 185 | shaderc_limit_max_atomic_counter_buffer_size = 77, 186 | shaderc_limit_max_transform_feedback_buffers = 78, 187 | shaderc_limit_max_transform_feedback_interleaved_components = 79, 188 | shaderc_limit_max_cull_distances = 80, 189 | shaderc_limit_max_combined_clip_and_cull_distances = 81, 190 | shaderc_limit_max_samples = 82, 191 | } 192 | 193 | // Uniform resource kinds. 194 | // In Vulkan, uniform resources are bound to the pipeline via descriptors 195 | // with numbered bindings and sets. 196 | enum shaderc_uniform_kind { 197 | // Image and image buffer. 198 | shaderc_uniform_kind_image = 0, 199 | // Pure sampler. 200 | shaderc_uniform_kind_sampler = 1, 201 | // Sampled texture in GLSL, and Shader Resource View in HLSL. 202 | shaderc_uniform_kind_texture = 2, 203 | // Uniform Buffer Object (UBO) in GLSL. Cbuffer in HLSL. 204 | shaderc_uniform_kind_buffer = 3, 205 | // Shader Storage Buffer Object (SSBO) in GLSL. 206 | shaderc_uniform_kind_storage_buffer = 4, 207 | // Unordered Access View, in HLSL. (Writable storage image or storage 208 | // buffer.) 209 | shaderc_uniform_kind_unordered_access_view = 5, 210 | } 211 | 212 | // Indicate the status of a compilation. 213 | enum shaderc_compilation_status { 214 | shaderc_compilation_status_success = 0, 215 | shaderc_compilation_status_invalid_stage = 1, // error stage deduction 216 | shaderc_compilation_status_compilation_error = 2, 217 | shaderc_compilation_status_internal_error = 3, // unexpected failure 218 | shaderc_compilation_status_null_result_object = 4, 219 | shaderc_compilation_status_invalid_assembly = 5, 220 | shaderc_compilation_status_validation_error = 6, 221 | shaderc_compilation_status_transformation_error = 7, 222 | shaderc_compilation_status_configuration_error = 8, 223 | } 224 | 225 | enum shaderc_target_env { 226 | shaderc_target_env_vulkan = 0, // SPIR-V under Vulkan semantics 227 | shaderc_target_env_opengl = 1, // SPIR-V under OpenGL semantics 228 | // NOTE: SPIR-V code generation is not supported for shaders under OpenGL 229 | // compatibility profile. 230 | shaderc_target_env_opengl_compat = 2, // SPIR-V under OpenGL semantics, 231 | // including compatibility profile 232 | // functions 233 | shaderc_target_env_webgpu = 3, // Deprecated, SPIR-V under WebGPU 234 | // semantics 235 | shaderc_target_env_default = shaderc_target_env_vulkan, 236 | } 237 | 238 | enum shaderc_env_version { 239 | // For Vulkan, use Vulkan's mapping of version numbers to integers. 240 | // See vulkan.h 241 | shaderc_env_version_vulkan_1_0 = ((1 << 22)), 242 | shaderc_env_version_vulkan_1_1 = ((1 << 22) | (1 << 12)), 243 | shaderc_env_version_vulkan_1_2 = ((1 << 22) | (2 << 12)), 244 | // For OpenGL, use the number from #version in shaders. 245 | // TODO(dneto): Currently no difference between OpenGL 4.5 and 4.6. 246 | // See glslang/Standalone/Standalone.cpp 247 | // TODO(dneto): Glslang doesn't accept a OpenGL client version of 460. 248 | shaderc_env_version_opengl_4_5 = 450, 249 | shaderc_env_version_webgpu = 451, // Deprecated, WebGPU env never defined versions 250 | } 251 | 252 | // The known versions of SPIR-V. 253 | enum shaderc_spirv_version { 254 | // Use the values used for word 1 of a SPIR-V binary: 255 | // - bits 24 to 31: zero 256 | // - bits 16 to 23: major version number 257 | // - bits 8 to 15: minor version number 258 | // - bits 0 to 7: zero 259 | shaderc_spirv_version_1_0 = 0x010000, 260 | shaderc_spirv_version_1_1 = 0x010100, 261 | shaderc_spirv_version_1_2 = 0x010200, 262 | shaderc_spirv_version_1_3 = 0x010300, 263 | shaderc_spirv_version_1_4 = 0x010400, 264 | shaderc_spirv_version_1_5 = 0x010500, 265 | } 266 | 267 | // Usage examples: 268 | // 269 | // Aggressively release compiler resources, but spend time in initialization 270 | // for each new use. 271 | // shaderc_compiler_t compiler = shaderc_compiler_initialize(); 272 | // shaderc_compilation_result_t result = shaderc_compile_into_spv( 273 | // compiler, "#version 450\nvoid main() {}", 27, 274 | // shaderc_glsl_vertex_shader, "main.vert", "main", nullptr); 275 | // // Do stuff with compilation results. 276 | // shaderc_result_release(result); 277 | // shaderc_compiler_release(compiler); 278 | // 279 | // Keep the compiler object around for a long time, but pay for extra space 280 | // occupied. 281 | // shaderc_compiler_t compiler = shaderc_compiler_initialize(); 282 | // // On the same, other or multiple simultaneous threads. 283 | // shaderc_compilation_result_t result = shaderc_compile_into_spv( 284 | // compiler, "#version 450\nvoid main() {}", 27, 285 | // shaderc_glsl_vertex_shader, "main.vert", "main", nullptr); 286 | // // Do stuff with compilation results. 287 | // shaderc_result_release(result); 288 | // // Once no more compilations are to happen. 289 | // shaderc_compiler_release(compiler); 290 | 291 | struct shaderc_compiler; 292 | // An opaque handle to an object that manages all compiler state. 293 | alias shaderc_compiler_t = shaderc_compiler*; 294 | 295 | // Returns a shaderc_compiler_t that can be used to compile modules. 296 | // A return of NULL indicates that there was an error initializing the compiler. 297 | // Any function operating on shaderc_compiler_t must offer the basic 298 | // thread-safety guarantee. 299 | // [http://herbsutter.com/2014/01/13/gotw-95-solution-thread-safety-and-synchronization/] 300 | // That is: concurrent invocation of these functions on DIFFERENT objects needs 301 | // no synchronization; concurrent invocation of these functions on the SAME 302 | // object requires synchronization IF AND ONLY IF some of them take a non-const 303 | // argument. 304 | shaderc_compiler_t shaderc_compiler_initialize(); 305 | 306 | // Releases the resources held by the shaderc_compiler_t. 307 | // After this call it is invalid to make any future calls to functions 308 | // involving this shaderc_compiler_t. 309 | void shaderc_compiler_release(shaderc_compiler_t); 310 | 311 | struct shaderc_compile_options; 312 | // An opaque handle to an object that manages options to a single compilation 313 | // result. 314 | alias shaderc_compile_options_t = shaderc_compile_options*; 315 | 316 | // Returns a default-initialized shaderc_compile_options_t that can be used 317 | // to modify the functionality of a compiled module. 318 | // A return of NULL indicates that there was an error initializing the options. 319 | // Any function operating on shaderc_compile_options_t must offer the 320 | // basic thread-safety guarantee. 321 | shaderc_compile_options_t shaderc_compile_options_initialize(); 322 | 323 | // Returns a copy of the given shaderc_compile_options_t. 324 | // If NULL is passed as the parameter the call is the same as 325 | // shaderc_compile_options_init. 326 | shaderc_compile_options_t shaderc_compile_options_clone( 327 | shaderc_compile_options_t options); 328 | 329 | // Releases the compilation options. It is invalid to use the given 330 | // shaderc_compile_options_t object in any future calls. It is safe to pass 331 | // NULL to this function, and doing such will have no effect. 332 | void shaderc_compile_options_release(shaderc_compile_options_t options); 333 | 334 | // Adds a predefined macro to the compilation options. This has the same 335 | // effect as passing -Dname=value to the command-line compiler. If value 336 | // is NULL, it has the same effect as passing -Dname to the command-line 337 | // compiler. If a macro definition with the same name has previously been 338 | // added, the value is replaced with the new value. The macro name and 339 | // value are passed in with char pointers, which point to their data, and 340 | // the lengths of their data. The strings that the name and value pointers 341 | // point to must remain valid for the duration of the call, but can be 342 | // modified or deleted after this function has returned. In case of adding 343 | // a valueless macro, the value argument should be a null pointer or the 344 | // value_length should be 0u. 345 | void shaderc_compile_options_add_macro_definition( 346 | shaderc_compile_options_t options, char* name, u64 name_length, 347 | char* value, u64 value_length); 348 | 349 | // Sets the source language. The default is GLSL. 350 | void shaderc_compile_options_set_source_language( 351 | shaderc_compile_options_t options, shaderc_source_language lang); 352 | 353 | // Sets the compiler mode to generate debug information in the output. 354 | void shaderc_compile_options_set_generate_debug_info( 355 | shaderc_compile_options_t options); 356 | 357 | // Sets the compiler optimization level to the given level. Only the last one 358 | // takes effect if multiple calls of this function exist. 359 | void shaderc_compile_options_set_optimization_level( 360 | shaderc_compile_options_t options, shaderc_optimization_level level); 361 | 362 | // Forces the GLSL language version and profile to a given pair. The version 363 | // number is the same as would appear in the #version annotation in the source. 364 | // Version and profile specified here overrides the #version annotation in the 365 | // source. Use profile: 'shaderc_profile_none' for GLSL versions that do not 366 | // define profiles, e.g. versions below 150. 367 | void shaderc_compile_options_set_forced_version_profile( 368 | shaderc_compile_options_t options, i32 version, shaderc_profile profile); 369 | 370 | // Source text inclusion via #include is supported with a pair of callbacks 371 | // to an "includer" on the client side. The first callback processes an 372 | // inclusion request, and returns an include result. The includer owns 373 | // the contents of the result, and those contents must remain valid until the 374 | // second callback is invoked to release the result. Both callbacks take a 375 | // user_data argument to specify the client context. 376 | // To return an error, set the source_name to an empty string and put your 377 | // error message in content. 378 | 379 | // An include result. 380 | struct shaderc_include_result { 381 | // The name of the source file. The name should be fully resolved 382 | // in the sense that it should be a unique name in the context of the 383 | // includer. For example, if the includer maps source names to files in 384 | // a filesystem, then this name should be the absolute path of the file. 385 | // For a failed inclusion, this string is empty. 386 | char* source_name; 387 | u64 source_name_length; 388 | // The text contents of the source file in the normal case. 389 | // For a failed inclusion, this contains the error message. 390 | char* content; 391 | u64 content_length; 392 | // User data to be passed along with this request. 393 | void* user_data; 394 | } 395 | 396 | // The kinds of include requests. 397 | enum shaderc_include_type { 398 | shaderc_include_type_relative = 0, // E.g. #include "source" 399 | shaderc_include_type_standard = 1, // E.g. #include 400 | } 401 | 402 | // An includer callback type for mapping an #include request to an include 403 | // result. The user_data parameter specifies the client context. The 404 | // requested_source parameter specifies the name of the source being requested. 405 | // The type parameter specifies the kind of inclusion request being made. 406 | // The requesting_source parameter specifies the name of the source containing 407 | // the #include request. The includer owns the result object and its contents, 408 | // and both must remain valid until the release callback is called on the result 409 | // object. 410 | alias shaderc_include_resolve_fn = shaderc_include_result* function( 411 | void* user_data, char* requested_source, i32 type, 412 | char* requesting_source, u64 include_depth); 413 | 414 | // An includer callback type for destroying an include result. 415 | alias shaderc_include_result_release_fn = void function( 416 | void* user_data, shaderc_include_result* include_result); 417 | 418 | // Sets includer callback functions. 419 | void shaderc_compile_options_set_include_callbacks( 420 | shaderc_compile_options_t options, shaderc_include_resolve_fn resolver, 421 | shaderc_include_result_release_fn result_releaser, void* user_data); 422 | 423 | // Sets the compiler mode to suppress warnings, overriding warnings-as-errors 424 | // mode. When both suppress-warnings and warnings-as-errors modes are 425 | // turned on, warning messages will be inhibited, and will not be emitted 426 | // as error messages. 427 | void shaderc_compile_options_set_suppress_warnings( 428 | shaderc_compile_options_t options); 429 | 430 | // Sets the target shader environment, affecting which warnings or errors will 431 | // be issued. The version will be for distinguishing between different versions 432 | // of the target environment. The version value should be either 0 or 433 | // a value listed in shaderc_env_version. The 0 value maps to Vulkan 1.0 if 434 | // |target| is Vulkan, and it maps to OpenGL 4.5 if |target| is OpenGL. 435 | void shaderc_compile_options_set_target_env( 436 | shaderc_compile_options_t options, 437 | shaderc_target_env target, 438 | u32 version); 439 | 440 | // Sets the target SPIR-V version. The generated module will use this version 441 | // of SPIR-V. Each target environment determines what versions of SPIR-V 442 | // it can consume. Defaults to the highest version of SPIR-V 1.0 which is 443 | // required to be supported by the target environment. E.g. Default to SPIR-V 444 | // 1.0 for Vulkan 1.0 and SPIR-V 1.3 for Vulkan 1.1. 445 | void shaderc_compile_options_set_target_spirv( 446 | shaderc_compile_options_t options, shaderc_spirv_version version); 447 | 448 | // Sets the compiler mode to treat all warnings as errors. Note the 449 | // suppress-warnings mode overrides this option, i.e. if both 450 | // warning-as-errors and suppress-warnings modes are set, warnings will not 451 | // be emitted as error messages. 452 | void shaderc_compile_options_set_warnings_as_errors( 453 | shaderc_compile_options_t options); 454 | 455 | // Sets a resource limit. 456 | void shaderc_compile_options_set_limit( 457 | shaderc_compile_options_t options, shaderc_limit limit, i32 value); 458 | 459 | // Sets whether the compiler should automatically assign bindings to uniforms 460 | // that aren't already explicitly bound in the shader source. 461 | void shaderc_compile_options_set_auto_bind_uniforms( 462 | shaderc_compile_options_t options, bool auto_bind); 463 | 464 | // Sets whether the compiler should automatically remove sampler variables 465 | // and convert image variables to combined image-sampler variables. 466 | void shaderc_compile_options_set_auto_combined_image_sampler( 467 | shaderc_compile_options_t options, bool upgrade); 468 | 469 | // Sets whether the compiler should use HLSL IO mapping rules for bindings. 470 | // Defaults to false. 471 | void shaderc_compile_options_set_hlsl_io_mapping( 472 | shaderc_compile_options_t options, bool hlsl_iomap); 473 | 474 | // Sets whether the compiler should determine block member offsets using HLSL 475 | // packing rules instead of standard GLSL rules. Defaults to false. Only 476 | // affects GLSL compilation. HLSL rules are always used when compiling HLSL. 477 | void shaderc_compile_options_set_hlsl_offsets( 478 | shaderc_compile_options_t options, bool hlsl_offsets); 479 | 480 | // Sets the base binding number used for for a uniform resource type when 481 | // automatically assigning bindings. For GLSL compilation, sets the lowest 482 | // automatically assigned number. For HLSL compilation, the regsiter number 483 | // assigned to the resource is added to this specified base. 484 | void shaderc_compile_options_set_binding_base( 485 | shaderc_compile_options_t options, 486 | shaderc_uniform_kind kind, 487 | u32 base); 488 | 489 | // Like shaderc_compile_options_set_binding_base, but only takes effect when 490 | // compiling a given shader stage. The stage is assumed to be one of vertex, 491 | // fragment, tessellation evaluation, tesselation control, geometry, or compute. 492 | void shaderc_compile_options_set_binding_base_for_stage( 493 | shaderc_compile_options_t options, shaderc_shader_kind shader_kind, 494 | shaderc_uniform_kind kind, u32 base); 495 | 496 | // Sets whether the compiler should automatically assign locations to 497 | // uniform variables that don't have explicit locations in the shader source. 498 | void shaderc_compile_options_set_auto_map_locations( 499 | shaderc_compile_options_t options, bool auto_map); 500 | 501 | // Sets a descriptor set and binding for an HLSL register in the given stage. 502 | // This method keeps a copy of the string data. 503 | void shaderc_compile_options_set_hlsl_register_set_and_binding_for_stage( 504 | shaderc_compile_options_t options, shaderc_shader_kind shader_kind, 505 | char* reg, char* set, char* binding); 506 | 507 | // Like shaderc_compile_options_set_hlsl_register_set_and_binding_for_stage, 508 | // but affects all shader stages. 509 | void shaderc_compile_options_set_hlsl_register_set_and_binding( 510 | shaderc_compile_options_t options, char* reg, char* set, 511 | char* binding); 512 | 513 | // Sets whether the compiler should enable extension 514 | // SPV_GOOGLE_hlsl_functionality1. 515 | void shaderc_compile_options_set_hlsl_functionality1( 516 | shaderc_compile_options_t options, bool enable); 517 | 518 | // Sets whether the compiler should invert position.Y output in vertex shader. 519 | void shaderc_compile_options_set_invert_y( 520 | shaderc_compile_options_t options, bool enable); 521 | 522 | // Sets whether the compiler generates code for max and min builtins which, 523 | // if given a NaN operand, will return the other operand. Similarly, the clamp 524 | // builtin will favour the non-NaN operands, as if clamp were implemented 525 | // as a composition of max and min. 526 | void shaderc_compile_options_set_nan_clamp( 527 | shaderc_compile_options_t options, bool enable); 528 | 529 | struct shaderc_compilation_result; 530 | // An opaque handle to the results of a call to any shaderc_compile_into_*() 531 | // function. 532 | alias shaderc_compilation_result_t = shaderc_compilation_result*; 533 | 534 | // Takes a GLSL source string and the associated shader kind, input file 535 | // name, compiles it according to the given additional_options. If the shader 536 | // kind is not set to a specified kind, but shaderc_glslc_infer_from_source, 537 | // the compiler will try to deduce the shader kind from the source 538 | // string and a failure in deducing will generate an error. Currently only 539 | // #pragma annotation is supported. If the shader kind is set to one of the 540 | // default shader kinds, the compiler will fall back to the default shader 541 | // kind in case it failed to deduce the shader kind from source string. 542 | // The input_file_name is a null-termintated string. It is used as a tag to 543 | // identify the source string in cases like emitting error messages. It 544 | // doesn't have to be a 'file name'. 545 | // The source string will be compiled into SPIR-V binary and a 546 | // shaderc_compilation_result will be returned to hold the results. 547 | // The entry_point_name null-terminated string defines the name of the entry 548 | // point to associate with this GLSL source. If the additional_options 549 | // parameter is not null, then the compilation is modified by any options 550 | // present. May be safely called from multiple threads without explicit 551 | // synchronization. If there was failure in allocating the compiler object, 552 | // null will be returned. 553 | shaderc_compilation_result_t shaderc_compile_into_spv( 554 | shaderc_compiler_t compiler, char* source_text, 555 | u64 source_text_size, shaderc_shader_kind shader_kind, 556 | char* input_file_name, char* entry_point_name, 557 | shaderc_compile_options_t additional_options); 558 | 559 | // Like shaderc_compile_into_spv, but the result contains SPIR-V assembly text 560 | // instead of a SPIR-V binary module. The SPIR-V assembly syntax is as defined 561 | // by the SPIRV-Tools open source project. 562 | shaderc_compilation_result_t shaderc_compile_into_spv_assembly( 563 | shaderc_compiler_t compiler, char* source_text, 564 | u64 source_text_size, shaderc_shader_kind shader_kind, 565 | char* input_file_name, char* entry_point_name, 566 | shaderc_compile_options_t additional_options); 567 | 568 | // Like shaderc_compile_into_spv, but the result contains preprocessed source 569 | // code instead of a SPIR-V binary module 570 | shaderc_compilation_result_t shaderc_compile_into_preprocessed_text( 571 | shaderc_compiler_t compiler, char* source_text, 572 | u64 source_text_size, shaderc_shader_kind shader_kind, 573 | char* input_file_name, char* entry_point_name, 574 | shaderc_compile_options_t additional_options); 575 | 576 | // Takes an assembly string of the format defined in the SPIRV-Tools project 577 | // (https://github.com/KhronosGroup/SPIRV-Tools/blob/master/syntax.md), 578 | // assembles it into SPIR-V binary and a shaderc_compilation_result will be 579 | // returned to hold the results. 580 | // The assembling will pick options suitable for assembling specified in the 581 | // additional_options parameter. 582 | // May be safely called from multiple threads without explicit synchronization. 583 | // If there was failure in allocating the compiler object, null will be 584 | // returned. 585 | shaderc_compilation_result_t shaderc_assemble_into_spv( 586 | shaderc_compiler_t compiler, char* source_assembly, 587 | u64 source_assembly_size, 588 | shaderc_compile_options_t additional_options); 589 | 590 | // The following functions, operating on shaderc_compilation_result_t objects, 591 | // offer only the basic thread-safety guarantee. 592 | 593 | // Releases the resources held by the result object. It is invalid to use the 594 | // result object for any further operations. 595 | void shaderc_result_release(shaderc_compilation_result_t result); 596 | 597 | // Returns the number of bytes of the compilation output data in a result 598 | // object. 599 | u64 shaderc_result_get_length(shaderc_compilation_result_t result); 600 | 601 | // Returns the number of warnings generated during the compilation. 602 | u64 shaderc_result_get_num_warnings( 603 | shaderc_compilation_result_t result); 604 | 605 | // Returns the number of errors generated during the compilation. 606 | u64 shaderc_result_get_num_errors(shaderc_compilation_result_t result); 607 | 608 | // Returns the compilation status, indicating whether the compilation succeeded, 609 | // or failed due to some reasons, like invalid shader stage or compilation 610 | // errors. 611 | shaderc_compilation_status shaderc_result_get_compilation_status( 612 | shaderc_compilation_result_t); 613 | 614 | // Returns a pointer to the start of the compilation output data bytes, either 615 | // SPIR-V binary or char string. When the source string is compiled into SPIR-V 616 | // binary, this is guaranteed to be castable to a uint32_t*. If the result 617 | // contains assembly text or preprocessed source text, the pointer will point to 618 | // the resulting array of characters. 619 | u8* shaderc_result_get_bytes(shaderc_compilation_result_t result); 620 | 621 | // Returns a null-terminated string that contains any error messages generated 622 | // during the compilation. 623 | char* shaderc_result_get_error_message( 624 | shaderc_compilation_result_t result); 625 | 626 | // Provides the version & revision of the SPIR-V which will be produced 627 | void shaderc_get_spv_version(u32* version, u32* revision); 628 | 629 | // Parses the version and profile from a given null-terminated string 630 | // containing both version and profile, like: '450core'. Returns false if 631 | // the string can not be parsed. Returns true when the parsing succeeds. The 632 | // parsed version and profile are returned through arguments. 633 | bool shaderc_parse_version_profile(char* str, i32* version, 634 | shaderc_profile* profile); 635 | --------------------------------------------------------------------------------