├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── LICENSE ├── README.md ├── build.bat ├── build.sh ├── run.bat ├── run.sh ├── script ├── colors.lua ├── init.lua ├── test.lua └── tests │ └── vector_test.lua ├── src ├── allocator │ ├── allocator.c │ ├── allocator.h │ ├── arena.c │ └── arena.h ├── assets │ ├── asset_system.c │ ├── asset_system.h │ ├── crate.c │ ├── crate.h │ ├── vfile.c │ └── vfile.h ├── audio │ ├── audio_system.c │ ├── audio_system.h │ ├── midi_system.c │ └── midi_system.h ├── cgltf │ └── cgltf.c ├── common │ ├── atomics.cpp │ ├── atomics.h │ ├── cmd.c │ ├── cmd.h │ ├── console.c │ ├── console.h │ ├── cvar.c │ ├── cvar.h │ ├── cvars.c │ ├── cvars.h │ ├── dbytes.h │ ├── find.c │ ├── find.h │ ├── fnv1a.c │ ├── fnv1a.h │ ├── guid.c │ ├── guid.h │ ├── iid.c │ ├── iid.h │ ├── library.c │ ├── library.h │ ├── macro.h │ ├── nextpow2.h │ ├── profiler.c │ ├── profiler.h │ ├── random.c │ ├── random.h │ ├── serialize.c │ ├── serialize.h │ ├── sort.c │ ├── sort.h │ ├── stringutil.c │ ├── stringutil.h │ ├── time.c │ ├── time.h │ └── unroll.h ├── containers │ ├── dict.c │ ├── dict.h │ ├── genid.h │ ├── graph.c │ ├── graph.h │ ├── hash_set.c │ ├── hash_set.h │ ├── hash_util.h │ ├── idalloc.c │ ├── idalloc.h │ ├── lookup.c │ ├── lookup.h │ ├── ptrqueue.c │ ├── ptrqueue.h │ ├── queue.c │ ├── queue.h │ ├── queue_i32.c │ ├── queue_i32.h │ ├── sdict.c │ ├── sdict.h │ ├── strlist.c │ ├── strlist.h │ ├── table.c │ ├── table.h │ ├── text.c │ └── text.h ├── editor │ ├── editor.c │ ├── editor.h │ ├── menubar.c │ └── menubar.h ├── input │ ├── input_system.c │ └── input_system.h ├── io │ ├── dir.c │ ├── dir.h │ ├── env.c │ ├── env.h │ ├── fd.c │ ├── fd.h │ ├── fmap.c │ ├── fmap.h │ ├── fnd.c │ ├── fnd.h │ ├── fstr.c │ ├── fstr.h │ └── types.h ├── logic │ ├── camera_logic.c │ ├── camera_logic.h │ ├── logic.c │ └── logic.h ├── main.c ├── math │ ├── ambcube.c │ ├── ambcube.h │ ├── area.h │ ├── atmosphere.c │ ├── atmosphere.h │ ├── atomic_float.h │ ├── blending.h │ ├── bool_funcs.h │ ├── box.h │ ├── color.c │ ├── color.h │ ├── color_gen.h │ ├── cubic_fit.c │ ├── cubic_fit.h │ ├── dist1d.c │ ├── dist1d.h │ ├── float2_funcs.h │ ├── float3_funcs.h │ ├── float3x3_funcs.h │ ├── float4_funcs.h │ ├── float4x4_funcs.h │ ├── frustum.h │ ├── grid.h │ ├── int2_funcs.h │ ├── int3_funcs.h │ ├── int4_funcs.h │ ├── lighting.c │ ├── lighting.h │ ├── markov_sampler.c │ ├── markov_sampler.h │ ├── noise.h │ ├── pcg.c │ ├── pcg.h │ ├── quat_funcs.h │ ├── sampling.h │ ├── scalar.h │ ├── sdf.h │ ├── sh.h │ ├── sphgauss.c │ ├── sphgauss.h │ ├── types.h │ ├── uint2_funcs.h │ ├── uint3_funcs.h │ └── uint4_funcs.h ├── os │ ├── socket.c │ └── socket.h ├── rendering │ ├── camera.c │ ├── camera.h │ ├── cubemap.c │ ├── cubemap.h │ ├── denoise.c │ ├── denoise.h │ ├── drawable.c │ ├── drawable.h │ ├── exposure.c │ ├── exposure.h │ ├── framebuffer.c │ ├── framebuffer.h │ ├── gltf_model.c │ ├── gltf_model.h │ ├── librtc.c │ ├── librtc.h │ ├── lightmap.c │ ├── lightmap.h │ ├── lights.c │ ├── lights.h │ ├── material.c │ ├── material.h │ ├── mesh.c │ ├── mesh.h │ ├── path_tracer.c │ ├── path_tracer.h │ ├── r_config.h │ ├── r_constants.c │ ├── r_constants.h │ ├── r_gpu_shared.c │ ├── r_gpu_shared.h │ ├── r_window.c │ ├── r_window.h │ ├── render_system.c │ ├── render_system.h │ ├── resolve_tile.c │ ├── resolve_tile.h │ ├── rtcdraw.c │ ├── rtcdraw.h │ ├── sampler.h │ ├── screenblit.c │ ├── screenblit.h │ ├── texture.c │ ├── texture.h │ ├── tonemap.c │ ├── tonemap.h │ └── vulkan │ │ ├── shaderc_table.c │ │ ├── shaderc_table.h │ │ ├── vk_mem_alloc.cpp │ │ ├── vkr.c │ │ ├── vkr.h │ │ ├── vkr_bindings.c │ │ ├── vkr_bindings.h │ │ ├── vkr_buffer.c │ │ ├── vkr_buffer.h │ │ ├── vkr_cmd.c │ │ ├── vkr_cmd.h │ │ ├── vkr_compile.c │ │ ├── vkr_compile.h │ │ ├── vkr_context.c │ │ ├── vkr_context.h │ │ ├── vkr_debug.c │ │ ├── vkr_debug.h │ │ ├── vkr_depthpass.c │ │ ├── vkr_depthpass.h │ │ ├── vkr_desc.c │ │ ├── vkr_desc.h │ │ ├── vkr_device.c │ │ ├── vkr_device.h │ │ ├── vkr_display.c │ │ ├── vkr_display.h │ │ ├── vkr_exposure.c │ │ ├── vkr_exposure.h │ │ ├── vkr_extension.c │ │ ├── vkr_extension.h │ │ ├── vkr_framebuffer.c │ │ ├── vkr_framebuffer.h │ │ ├── vkr_im.c │ │ ├── vkr_im.h │ │ ├── vkr_image.c │ │ ├── vkr_image.h │ │ ├── vkr_instance.c │ │ ├── vkr_instance.h │ │ ├── vkr_mainpass.c │ │ ├── vkr_mainpass.h │ │ ├── vkr_mem.c │ │ ├── vkr_mem.h │ │ ├── vkr_mesh.c │ │ ├── vkr_mesh.h │ │ ├── vkr_opaquepass.c │ │ ├── vkr_opaquepass.h │ │ ├── vkr_pass.c │ │ ├── vkr_pass.h │ │ ├── vkr_pipeline.c │ │ ├── vkr_pipeline.h │ │ ├── vkr_queue.c │ │ ├── vkr_queue.h │ │ ├── vkr_renderpass.c │ │ ├── vkr_renderpass.h │ │ ├── vkr_sampler.c │ │ ├── vkr_sampler.h │ │ ├── vkr_shader.c │ │ ├── vkr_shader.h │ │ ├── vkr_swapchain.c │ │ ├── vkr_swapchain.h │ │ ├── vkr_sync.c │ │ ├── vkr_sync.h │ │ ├── vkr_targets.c │ │ ├── vkr_targets.h │ │ ├── vkr_textable.c │ │ ├── vkr_textable.h │ │ ├── vkr_texture.c │ │ ├── vkr_texture.h │ │ ├── vkr_uipass.c │ │ └── vkr_uipass.h ├── scriptsys │ ├── scr_cmd.c │ ├── scr_cmd.h │ ├── scr_cvar.c │ ├── scr_cvar.h │ ├── scr_game.c │ ├── scr_game.h │ ├── scr_log.c │ ├── scr_log.h │ ├── scr_time.c │ ├── scr_time.h │ ├── script.c │ └── script.h ├── shaders │ ├── AdaptHistogram.hlsl │ ├── BuildHistogram.hlsl │ ├── ClearHistogram.hlsl │ ├── Color.hlsl │ ├── DepthOnly.hlsl │ ├── Exposure.hlsl │ ├── GI.hlsl │ ├── Lighting.hlsl │ ├── RetroSky.hlsl │ ├── SG.hlsl │ ├── Sampling.hlsl │ ├── bindings.hlsl │ ├── brush.hlsl │ ├── color_gen.h │ ├── common.hlsl │ ├── imgui.hlsl │ ├── post.hlsl │ └── random.hlsl ├── sokol │ ├── sokol_audio.c │ └── sokol_time.c ├── stb │ ├── stb_image.c │ ├── stb_image_write.c │ ├── stb_perlin_fork.h │ └── stb_sprintf.c ├── threading │ ├── barrier.c │ ├── barrier.h │ ├── event.c │ ├── event.h │ ├── intrin.c │ ├── intrin.h │ ├── mutex.c │ ├── mutex.h │ ├── rwlock.c │ ├── rwlock.h │ ├── semaphore.c │ ├── semaphore.h │ ├── sleep.c │ ├── sleep.h │ ├── task.c │ ├── task.h │ ├── taskcpy.c │ ├── taskcpy.h │ ├── thread.c │ └── thread.h ├── tools │ ├── dllcopy.sh │ └── prehash.py └── ui │ ├── cimgui_ext.c │ ├── cimgui_ext.h │ ├── cimgui_impl_glfw.cpp │ ├── cimgui_impl_glfw.h │ ├── ui.c │ └── ui.h └── submodules ├── embree └── embree-3.13.0.x64.vc14.windows │ ├── bin │ ├── embree3.dll │ └── tbb12.dll │ ├── doc │ ├── CHANGELOG.md │ ├── LICENSE.txt │ ├── README.md │ ├── third-party-programs-TBB.txt │ └── third-party-programs.txt │ ├── include │ └── embree3 │ │ ├── rtcore.h │ │ ├── rtcore.isph │ │ ├── rtcore_buffer.h │ │ ├── rtcore_buffer.isph │ │ ├── rtcore_builder.h │ │ ├── rtcore_common.h │ │ ├── rtcore_common.isph │ │ ├── rtcore_config.h │ │ ├── rtcore_device.h │ │ ├── rtcore_device.isph │ │ ├── rtcore_geometry.h │ │ ├── rtcore_geometry.isph │ │ ├── rtcore_quaternion.h │ │ ├── rtcore_quaternion.isph │ │ ├── rtcore_ray.h │ │ ├── rtcore_ray.isph │ │ ├── rtcore_scene.h │ │ └── rtcore_scene.isph │ └── lib │ ├── cmake │ └── embree-3.13.0 │ │ ├── embree-config-version.cmake │ │ ├── embree-config.cmake │ │ ├── embree-targets-release.cmake │ │ └── embree-targets.cmake │ ├── embree3.lib │ └── tbb.lib ├── oidn └── oidn-1.4.0.x64.vc14.windows │ ├── bin │ ├── OpenImageDenoise.dll │ └── tbb12.dll │ ├── doc │ ├── CHANGELOG.md │ ├── LICENSE.txt │ ├── README.md │ ├── third-party-programs-oneDNN.txt │ ├── third-party-programs-oneTBB.txt │ └── third-party-programs.txt │ ├── include │ └── OpenImageDenoise │ │ ├── config.h │ │ ├── oidn.h │ │ └── oidn.hpp │ └── lib │ ├── OpenImageDenoise.lib │ ├── cmake │ └── OpenImageDenoise-1.4.0 │ │ ├── OpenImageDenoiseConfig-release.cmake │ │ ├── OpenImageDenoiseConfig.cmake │ │ └── OpenImageDenoiseConfigVersion.cmake │ └── tbb.lib ├── pcg32 └── pcg32.h ├── stackwalker ├── LICENSE.txt ├── README.md ├── StackWalker.cpp └── StackWalker.h └── update.sh /.gitignore: -------------------------------------------------------------------------------- 1 | .vs/ 2 | .vscode/ 3 | .autosave/ 4 | packs/ 5 | data/ 6 | build/ 7 | screenshots/ 8 | imgui.ini 9 | *.log 10 | __pycache__ 11 | .cache/ 12 | compile_commands.json 13 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "submodules/stb"] 2 | path = submodules/stb 3 | url = https://github.com/nothings/stb.git 4 | [submodule "submodules/tlsf"] 5 | path = submodules/tlsf 6 | url = https://github.com/mattconte/tlsf 7 | [submodule "submodules/volk"] 8 | path = submodules/volk 9 | url = https://github.com/zeux/volk 10 | [submodule "submodules/glfw"] 11 | path = submodules/glfw 12 | url = https://github.com/glfw/glfw 13 | [submodule "submodules/VulkanMemoryAllocator"] 14 | path = submodules/VulkanMemoryAllocator 15 | url = https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator 16 | [submodule "submodules/cJSON"] 17 | path = submodules/cJSON 18 | url = https://github.com/DaveGamble/cJSON.git 19 | [submodule "submodules/SPIRV-Reflect"] 20 | path = submodules/SPIRV-Reflect 21 | url = https://github.com/KhronosGroup/SPIRV-Reflect.git 22 | [submodule "submodules/cgltf"] 23 | path = submodules/cgltf 24 | url = https://github.com/jkuhlmann/cgltf.git 25 | [submodule "submodules/miniz"] 26 | path = submodules/miniz 27 | url = https://github.com/richgel999/miniz 28 | [submodule "submodules/imgui"] 29 | path = submodules/imgui 30 | url = https://github.com/ocornut/imgui 31 | [submodule "submodules/cimgui"] 32 | path = submodules/cimgui 33 | url = https://github.com/cimgui/cimgui 34 | [submodule "submodules/lua"] 35 | path = submodules/lua 36 | url = https://github.com/lua/lua.git 37 | [submodule "submodules/sokol"] 38 | path = submodules/sokol 39 | url = https://github.com/floooh/sokol.git 40 | -------------------------------------------------------------------------------- /build.bat: -------------------------------------------------------------------------------- 1 | mkdir build 2 | cd build 3 | cmake .. -G "Visual Studio 16 2019" 4 | cd .. 5 | cmake --build build --config Debug 6 | cmake --build build --config Release 7 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | mkdir -p build/Debug 4 | mkdir -p build/Release 5 | 6 | pushd build/Debug 7 | cmake -DCMAKE_BUILD_TYPE=DEBUG -DCMAKE_EXPORT_COMPILE_COMMANDS=1 ../../ 8 | ln -f -s build/Debug/compile_commands.json ../../ 9 | popd 10 | 11 | pushd build/Release 12 | cmake -DCMAKE_BUILD_TYPE=RELEASE ../../ 13 | popd 14 | 15 | cmake --build build/Debug 16 | cmake --build build/Release 17 | -------------------------------------------------------------------------------- /run.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | "%~dp0/build/Release/pim.exe" 4 | -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DIR=`dirname $0` 4 | $DIR/build/Release/pim 5 | -------------------------------------------------------------------------------- /script/colors.lua: -------------------------------------------------------------------------------- 1 | local Cvar = require("cvar") 2 | local colors = {} 3 | 4 | local function randf(a, b) 5 | return a + (b - a) * math.random() 6 | end 7 | 8 | local sun_color = { x = 0, y = 0, z = 0, w = 0 } 9 | local dir = { x = 1, y = 1, z = 1, w = 1 } 10 | local vel = { x = randf(.1, .5), y = randf(.1, .5), z = randf(.1, .5), w = randf(.1, .5) } 11 | 12 | function colors:update() 13 | 14 | end 15 | 16 | Game.start_update(colors) 17 | -------------------------------------------------------------------------------- /script/init.lua: -------------------------------------------------------------------------------- 1 | local Cvar = require("cvar") 2 | 3 | local init = {} 4 | 5 | function init:start() 6 | 7 | end 8 | 9 | function init:update() 10 | 11 | end 12 | 13 | function init:stop() 14 | Log.info("Init script completed.") 15 | end 16 | 17 | Game.start_update(init) 18 | -------------------------------------------------------------------------------- /script/test.lua: -------------------------------------------------------------------------------- 1 | local Cmd = require("cmd") 2 | local Cvar = require("cvar") 3 | 4 | local test = {} 5 | 6 | local timer = 1 7 | local repeats = 5 8 | local dir = 1 9 | local fov = 90 10 | local speed = 5 11 | 12 | function test:start() 13 | Log.info("Beginning test...") 14 | fov = Cvar.get("r_fov") 15 | Log.info("Current fov is ", fov) 16 | end 17 | 18 | function test:update() 19 | if timer <= 0 then 20 | repeats = repeats - 1 21 | timer = 1 22 | 23 | dir = -dir 24 | 25 | if repeats <= 0 then 26 | return Game.stop_update(self) 27 | end 28 | end 29 | 30 | Cvar.set("r_fov", fov) 31 | fov = fov + (dir * speed * Time.delta) 32 | 33 | timer = timer - Time.delta 34 | end 35 | 36 | function test:stop() 37 | Log.info("Test script completed.") 38 | end 39 | 40 | Game.start_update(test) -------------------------------------------------------------------------------- /script/tests/vector_test.lua: -------------------------------------------------------------------------------- 1 | local Cvar = require("cvar") 2 | 3 | local vector_test = {} 4 | 5 | function vector_test:update() 6 | 7 | end 8 | 9 | Game.start_update(vector_test) 10 | -------------------------------------------------------------------------------- /src/allocator/allocator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | void MemSys_Init(void); 8 | void MemSys_Update(void); 9 | void MemSys_Shutdown(void); 10 | 11 | void Mem_Free(void* ptr); 12 | void* Mem_Alloc(EAlloc allocator, i32 bytes); 13 | void* Mem_Realloc(EAlloc allocator, void* prev, i32 bytes); 14 | void* Mem_Calloc(EAlloc allocator, i32 bytes); 15 | void* Mem_Dup(EAlloc allocator, const void* src); 16 | void Mem_Zero(void* ptr); 17 | 18 | // alternative to alloca 19 | void* Mem_Push(i32 bytes); 20 | void Mem_Pop(i32 bytes); 21 | 22 | #define Perm_Alloc(bytes) Mem_Alloc(EAlloc_Perm, (bytes)) 23 | #define Perm_Calloc(bytes) Mem_Calloc(EAlloc_Perm, (bytes)) 24 | #define Perm_Realloc(prev, bytes) Mem_Realloc(EAlloc_Perm, (prev), (bytes)) 25 | #define Perm_Dup(prev) Mem_Dup(EAlloc_Perm, (prev)) 26 | 27 | #define Tex_Alloc(bytes) Mem_Alloc(EAlloc_Texture, (bytes)) 28 | #define Tex_Calloc(bytes) Mem_Calloc(EAlloc_Texture, (bytes)) 29 | #define Tex_Realloc(prev, bytes) Mem_Realloc(EAlloc_Texture, (prev), (bytes)) 30 | #define Tex_Dup(prev) Mem_Dup(EAlloc_Texture, (prev)) 31 | 32 | #define Temp_Alloc(bytes) Mem_Alloc(EAlloc_Temp, (bytes)) 33 | #define Temp_Calloc(bytes) Mem_Calloc(EAlloc_Temp, (bytes)) 34 | #define Temp_Realloc(prev, bytes) Mem_Realloc(EAlloc_Temp, (prev), (bytes)) 35 | #define Temp_Dup(prev) Mem_Dup(EAlloc_Temp, (prev)) 36 | 37 | #define ZeroElem(p, i) do { memset((p) + (i), 0, sizeof((p)[0])); } while(0) 38 | #define PopSwap(p, i, l) do { memcpy((p) + (i), (p) + (l) - 1, sizeof((p)[0])); } while(0) 39 | 40 | #define Mem_Reserve(e, p, l) do { (p) = Mem_Realloc((e), (p), sizeof((p)[0]) * (l)); } while(0) 41 | 42 | #define Mem_Grow(e, p, l) do { Mem_Reserve((e), (p), (l)); ZeroElem((p), (l) - 1); } while(0) 43 | 44 | #define Perm_Reserve(p, l) Mem_Reserve(EAlloc_Perm, (p), (l)) 45 | #define Perm_Grow(p, l) Mem_Grow(EAlloc_Perm, (p), (l)) 46 | 47 | #define Temp_Reserve(p, l) Mem_Reserve(EAlloc_Temp, (p), (l)) 48 | #define Temp_Grow(p, l) Mem_Grow(EAlloc_Temp, (p), (l)) 49 | 50 | PIM_C_END 51 | -------------------------------------------------------------------------------- /src/allocator/arena.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | typedef struct ArenaHdl_s 8 | { 9 | u32 seqno; 10 | } ArenaHdl; 11 | 12 | void ArenaSys_Init(void); 13 | void ArenaSys_Shutdown(void); 14 | 15 | bool Arena_Exists(ArenaHdl hdl); 16 | ArenaHdl Arena_Acquire(void); 17 | void Arena_Release(ArenaHdl hdl); 18 | void* Arena_Alloc(ArenaHdl hdl, u32 bytes); 19 | 20 | PIM_C_END 21 | -------------------------------------------------------------------------------- /src/assets/asset_system.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | typedef struct asset_s 8 | { 9 | i32 length; 10 | const void* pData; 11 | } asset_t; 12 | 13 | void AssetSys_Init(void); 14 | void AssetSys_Update(void); 15 | void AssetSys_Shutdown(void); 16 | void AssetSys_Gui(bool* pEnabled); 17 | 18 | bool Asset_Get(const char* name, asset_t* assetOut); 19 | 20 | PIM_C_END 21 | -------------------------------------------------------------------------------- /src/assets/crate.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | #include "common/guid.h" 5 | #include "io/fstr.h" 6 | 7 | PIM_C_BEGIN 8 | 9 | enum 10 | { 11 | kCrateLen = 1024, 12 | }; 13 | 14 | typedef struct Crate_s 15 | { 16 | FStream file; 17 | Guid ids[kCrateLen]; 18 | i32 offsets[kCrateLen]; 19 | i32 sizes[kCrateLen]; 20 | } Crate; 21 | 22 | bool Crate_Open(Crate *const crate, const char* path); 23 | bool Crate_Close(Crate *const crate); 24 | 25 | bool Crate_Get(Crate *const crate, Guid id, void* dst, i32 size); 26 | bool Crate_Set(Crate *const crate, Guid id, const void* src, i32 size); 27 | bool Crate_Rm(Crate *const crate, Guid id); 28 | 29 | bool Crate_Stat( 30 | const Crate *const crate, 31 | Guid id, 32 | i32 *const offsetOut, 33 | i32 *const sizeOut); 34 | 35 | PIM_C_END 36 | -------------------------------------------------------------------------------- /src/assets/vfile.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | #include "io/fd.h" 5 | #include "io/fstr.h" 6 | #include "io/fmap.h" 7 | 8 | PIM_C_BEGIN 9 | 10 | typedef enum 11 | { 12 | VFileType_Null = 0, 13 | VFileType_Descriptor, 14 | VFileType_Stream, 15 | VFileType_Map, 16 | VFileType_SubFile, 17 | } VFileType; 18 | 19 | typedef struct VFileHdl_s 20 | { 21 | u32 version : 8; 22 | u32 index : 24; 23 | } VFileHdl; 24 | 25 | bool VFile_Exists(VFileHdl hdl); 26 | bool VFile_IsOpen(VFileHdl hdl); 27 | VFileHdl VFile_New(const char* path, const char* mode, VFileType type); 28 | bool VFile_Del(VFileHdl hdl); 29 | i32 VFile_Size(VFileHdl hdl); 30 | i32 VFile_Read(VFileHdl hdl, i32 offset, i32 size, void* dst); 31 | i32 VFile_Write(VFileHdl hdl, i32 offset, i32 size, const void* src); 32 | VFileHdl SubFile_New(VFileHdl owner, i32 offset, i32 size, const char* name); 33 | 34 | PIM_C_END 35 | -------------------------------------------------------------------------------- /src/audio/audio_system.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | void AudioSys_Init(void); 8 | void AudioSys_Update(void); 9 | void AudioSys_Shutdown(void); 10 | void AudioSys_Gui(bool* pEnabled); 11 | 12 | PIM_C_END 13 | -------------------------------------------------------------------------------- /src/audio/midi_system.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | typedef struct MidiHdl_s 8 | { 9 | u32 version : 8; 10 | u32 index : 24; 11 | } MidiHdl; 12 | 13 | typedef struct MidiMsg_s 14 | { 15 | i32 port; 16 | u8 command; 17 | u8 param1; 18 | u8 param2; 19 | } MidiMsg; 20 | 21 | typedef void(*OnMidiFn)(const MidiMsg* msg, void* usr); 22 | 23 | void MidiSys_Init(void); 24 | void MidiSys_Update(void); 25 | void MidiSys_Shutdown(void); 26 | 27 | i32 Midi_DeviceCount(void); 28 | bool Midi_Exists(MidiHdl hdl); 29 | MidiHdl Midi_Open(i32 port, OnMidiFn cb, void* usr); 30 | bool Midi_Close(MidiHdl hdl); 31 | 32 | PIM_C_END 33 | -------------------------------------------------------------------------------- /src/cgltf/cgltf.c: -------------------------------------------------------------------------------- 1 | #include "allocator/allocator.h" 2 | 3 | #define CGLTF_MALLOC(size) Perm_Alloc((i32)(size)) 4 | #define CGLTF_FREE(ptr) Mem_Free((ptr)) 5 | 6 | #define CGLTF_VALIDATE_ENABLE_ASSERTS ASSERTS_ENABLED 7 | 8 | #define CGLTF_IMPLEMENTATION 9 | #include "cgltf/cgltf.h" 10 | -------------------------------------------------------------------------------- /src/common/atomics.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | typedef enum 8 | { 9 | MO_Relaxed = 0, 10 | MO_Consume, 11 | MO_Acquire, 12 | MO_Release, 13 | MO_AcqRel, 14 | MO_SeqCst, 15 | } memorder_t; 16 | 17 | void ThreadFenceAcquire(); 18 | void ThreadFenceRelease(); 19 | 20 | #define DECL_ATOMIC(T) \ 21 | T load_##T(const volatile T* atom, memorder_t ord); \ 22 | void store_##T(volatile T* atom, T x, memorder_t ord); \ 23 | i32 cmpex_##T(volatile T* atom, T* expected, T desired, memorder_t ord); \ 24 | T exch_##T(volatile T* atom, T x, memorder_t ord); \ 25 | T inc_##T(volatile T* atom, memorder_t ord); \ 26 | T dec_##T(volatile T* atom, memorder_t ord); \ 27 | T fetch_add_##T(volatile T* atom, T x, memorder_t ord); \ 28 | T fetch_sub_##T(volatile T* atom, T x, memorder_t ord); \ 29 | T fetch_and_##T(volatile T* atom, T x, memorder_t ord); \ 30 | T fetch_or_##T(volatile T* atom, T x, memorder_t ord); \ 31 | T fetch_xor_##T(volatile T* atom, T x, memorder_t ord); 32 | 33 | DECL_ATOMIC(u8) 34 | DECL_ATOMIC(i8) 35 | DECL_ATOMIC(u16) 36 | DECL_ATOMIC(i16) 37 | DECL_ATOMIC(u32) 38 | DECL_ATOMIC(i32) 39 | DECL_ATOMIC(u64) 40 | DECL_ATOMIC(i64) 41 | DECL_ATOMIC(isize) 42 | 43 | #define LoadPtr(T, atom, ord) (T*)load_isize((const volatile isize*)&(atom), ord) 44 | #define StorePtr(T, atom, x, ord) store_isize((volatile isize*)&(atom), (isize)x, ord) 45 | #define CmpExPtr(T, atom, ex, des, ord) cmpex_isize((volatile isize*)&(atom), (isize*)&(ex), (isize)des, ord) 46 | #define ExchPtr(T, atom, x, ord) (T*)exch_isize((volatile isize*)&(atom), (isize)x, ord) 47 | #define IncPtr(T, atom, ord) (T*)fetch_add_isize((volatile isize*)&(atom), sizeof(T), ord) 48 | #define DecPtr(T, atom, ord) (T*)fetch_sub_isize((volatile isize*)&(atom), sizeof(T), ord) 49 | #define FetchAddPtr(T, atom, x, ord) (T*)fetch_add_isize((volatile isize*)&(atom), sizeof(T) * (isize)(x), ord) 50 | #define FetchSubPtr(T, atom, x, ord) (T*)fetch_sub_isize((volatile isize*)&(atom), sizeof(T) * (isize)(x), ord) 51 | 52 | PIM_C_END 53 | -------------------------------------------------------------------------------- /src/common/cmd.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | typedef enum 8 | { 9 | cmdstat_ok, 10 | cmdstat_err, 11 | 12 | cmdstat_COUNT 13 | } cmdstat_t; 14 | 15 | typedef cmdstat_t(*cmd_fn_t)(i32 argc, const char** argv); 16 | 17 | void cmd_sys_init(void); 18 | void cmd_sys_update(void); 19 | void cmd_sys_shutdown(void); 20 | 21 | void cmd_reg(const char* name, const char* argDocs, const char* helpText, cmd_fn_t fn); 22 | bool cmd_exists(const char* name); 23 | const char* cmd_complete(const char* namePart); 24 | 25 | // pushes to back of command queue, then executes queue. 26 | cmdstat_t cmd_enqueue(const char* text); 27 | 28 | // pushes to front of command queue in reverse order, then executes queue. 29 | cmdstat_t cmd_immediate(const char* text); 30 | 31 | const char* cmd_parse(const char* text, char* tokenOut, i32 bufSize); 32 | 33 | // parse an option for your command. 34 | // if user passes "cmd -key=value" or "cmd -key value", returns pointer to value. 35 | // if user passes "cmd -key" or "cmd -key -bar", returns pointer to empty string. 36 | // if user passes "cmd", returns NULL. 37 | const char* cmd_getopt(i32 argc, const char** argv, const char* key); 38 | 39 | PIM_C_END 40 | -------------------------------------------------------------------------------- /src/common/console.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | // AABBGGRR 8 | #define C32_WHITE 0xffffffff 9 | #define C32_GRAY 0xff808080 10 | #define C32_BLACK 0xff000000 11 | #define C32_RED 0xff0000ff 12 | #define C32_ORANGE 0xff0080ff 13 | #define C32_YELLOW 0xff00ffff 14 | #define C32_LIME 0xff00ff80 15 | #define C32_GREEN 0xff00ff00 16 | #define C32_SPRING 0xff80ff00 17 | #define C32_CYAN 0xffffff00 18 | #define C32_AZURE 0xffff8000 19 | #define C32_BLUE 0xffff0000 20 | #define C32_VIOLET 0xffff0080 21 | #define C32_MAGENTA 0xffff00ff 22 | #define C32_ROSE 0xff8000ff 23 | 24 | #if _DEBUG 25 | # define Con_Assertf(x, tag, fmt, ...) do { if (!(x)) { Con_Logf(LogSev_Assert, (tag), (fmt), __VA_ARGS__); } } while(0) 26 | #else 27 | # define Con_Assertf(x, tag, fmt, ...) 28 | #endif // _DEBUG 29 | 30 | typedef enum 31 | { 32 | LogSev_Assert, 33 | LogSev_Error, 34 | LogSev_Warning, 35 | LogSev_Info, 36 | LogSev_Verbose, 37 | 38 | LogSev_COUNT 39 | } LogSev; 40 | 41 | void ConSys_Init(void); 42 | void ConSys_Update(void); 43 | void ConSys_Shutdown(void); 44 | 45 | void Con_Exec(const char* cmdText); 46 | void Con_Clear(void); 47 | void Con_Puts(u32 color, const char* line); 48 | 49 | void Con_Logf(LogSev sev, const char* tag, const char* fmt, ...); 50 | void Con_Logv(LogSev sev, const char* tag, const char* fmt, va_list ap); 51 | 52 | // flush the logfile 53 | void Con_Flush(void); 54 | 55 | PIM_C_END 56 | -------------------------------------------------------------------------------- /src/common/cvar.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | #include "math/types.h" 5 | 6 | PIM_C_BEGIN 7 | 8 | typedef enum 9 | { 10 | cvart_text = 0, 11 | cvart_float, 12 | cvart_int, 13 | cvart_bool, 14 | cvart_vector, // unit direction 15 | cvart_point, // position 16 | cvart_color, // color 17 | } cvar_type; 18 | 19 | typedef struct ConVar_s 20 | { 21 | cvar_type type; 22 | u32 flag_logarithmic : 1; 23 | u32 flag_hdr : 1; 24 | u32 flag_save : 1; 25 | const char* name; 26 | char value[64]; 27 | const char* desc; 28 | union 29 | { 30 | i32 minInt; 31 | float minFloat; 32 | }; 33 | union 34 | { 35 | i32 maxInt; 36 | float maxFloat; 37 | }; 38 | union 39 | { 40 | float4 asVector; 41 | float asFloat; 42 | i32 asInt; 43 | bool asBool; 44 | }; 45 | u32 version; 46 | bool registered; 47 | } ConVar; 48 | 49 | // registers your cvar to the cvar system 50 | void ConVar_Reg(ConVar* var); 51 | 52 | // attempts to find a cvar with matching name 53 | ConVar* ConVar_Find(const char* name); 54 | 55 | // attempts to auto-complete namePart to a cvar name 56 | const char* ConVar_Complete(const char* namePart); 57 | 58 | bool ConVars_Save(const char* path); 59 | bool ConVars_Load(const char* path); 60 | 61 | // updates string and float value, sets dirty flag 62 | void ConVar_SetStr(ConVar* ptr, const char* value); 63 | void ConVar_SetFloat(ConVar* ptr, float value); 64 | void ConVar_SetInt(ConVar* ptr, i32 value); 65 | void ConVar_SetVec(ConVar* ptr, float4 value); 66 | void ConVar_SetBool(ConVar* ptr, bool value); 67 | 68 | bool ConVar_IsVec(const ConVar* ptr); 69 | 70 | const char* ConVar_GetStr(const ConVar* ptr); 71 | float ConVar_GetFloat(const ConVar* ptr); 72 | i32 ConVar_GetInt(const ConVar* ptr); 73 | float4 ConVar_GetVec(const ConVar* ptr); 74 | bool ConVar_GetBool(const ConVar* ptr); 75 | 76 | void ConVar_Toggle(ConVar* ptr); 77 | 78 | bool ConVar_CheckDirty(const ConVar* ptr, u32* pUserVersion); 79 | 80 | // displays the cvar gui 81 | void ConVar_Gui(bool* pEnabled); 82 | 83 | 84 | PIM_C_END 85 | -------------------------------------------------------------------------------- /src/common/cvars.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/cvar.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | extern ConVar cv_basedir; 8 | extern ConVar cv_game; 9 | extern ConVar cv_con_logpath; 10 | extern ConVar cv_in_pitchscale; 11 | extern ConVar cv_in_yawscale; 12 | extern ConVar cv_in_movescale; 13 | extern ConVar cv_r_fov; 14 | extern ConVar cv_r_znear; 15 | extern ConVar cv_r_zfar; 16 | extern ConVar cv_r_whitepoint; 17 | extern ConVar cv_r_display_nits_min; 18 | extern ConVar cv_r_display_nits_max; 19 | extern ConVar cv_r_ui_nits; 20 | extern ConVar cv_r_maxdelqueue; 21 | extern ConVar cv_r_scale; 22 | extern ConVar cv_r_width; 23 | extern ConVar cv_r_height; 24 | extern ConVar cv_r_fpslimit; 25 | extern ConVar cv_r_bumpiness; 26 | extern ConVar cv_r_tex_custom; 27 | extern ConVar cv_r_brdflut_spf; 28 | 29 | extern ConVar cv_pt_dist_meters; 30 | extern ConVar cv_pt_trace; 31 | extern ConVar cv_pt_denoise; 32 | extern ConVar cv_pt_normal; 33 | extern ConVar cv_pt_albedo; 34 | 35 | extern ConVar cv_r_refl_gen; 36 | extern ConVar cv_r_sun_dir; 37 | extern ConVar cv_r_sun_lum; 38 | extern ConVar cv_r_sun_res; 39 | extern ConVar cv_r_sun_steps; 40 | extern ConVar cv_ui_opacity; 41 | 42 | extern ConVar cv_lm_upload; 43 | extern ConVar cv_lm_gen; 44 | extern ConVar cv_lm_density; 45 | extern ConVar cv_lm_timeslice; 46 | extern ConVar cv_lm_spp; 47 | 48 | extern ConVar cv_exp_standard; 49 | extern ConVar cv_exp_manual; 50 | extern ConVar cv_exp_aperture; 51 | extern ConVar cv_exp_shutter; 52 | extern ConVar cv_exp_adaptrate; 53 | extern ConVar cv_exp_evoffset; 54 | extern ConVar cv_exp_evmin; 55 | extern ConVar cv_exp_evmax; 56 | extern ConVar cv_exp_cdfmin; 57 | extern ConVar cv_exp_cdfmax; 58 | 59 | extern ConVar cv_sky_rad_cr; 60 | extern ConVar cv_sky_rad_at; 61 | extern ConVar cv_sky_rlh_mfp; 62 | extern ConVar cv_sky_rlh_sh; 63 | extern ConVar cv_sky_mie_mfp; 64 | extern ConVar cv_sky_mie_sh; 65 | extern ConVar cv_sky_mie_g; 66 | 67 | extern ConVar cv_fullscreen; 68 | 69 | void ConVars_RegisterAll(void); 70 | 71 | PIM_C_END 72 | -------------------------------------------------------------------------------- /src/common/dbytes.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | typedef struct DiskBytes_s 8 | { 9 | i32 offset; 10 | i32 size; 11 | } DiskBytes; 12 | 13 | #define DiskBytes_Check(db, stride) \ 14 | if (db.offset < 0) { INTERRUPT(); goto cleanup; } \ 15 | if (db.size < 0) { INTERRUPT(); goto cleanup; } \ 16 | if (db.size % stride) { INTERRUPT(); goto cleanup; } 17 | 18 | pim_inline DiskBytes DiskBytes_New(i32 length, i32 stride, i32* pOffset) 19 | { 20 | DiskBytes db = { 0 }; 21 | db.size = length * stride; 22 | db.offset = *pOffset; 23 | *pOffset = db.offset + db.size; 24 | return db; 25 | } 26 | 27 | PIM_C_END 28 | -------------------------------------------------------------------------------- /src/common/find.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | i32 Find(const void* arr, i32 stride, i32 length, const void* key); 8 | i32 RFind(const void* arr, i32 stride, i32 length, const void* key); 9 | i32 StrFind(const char** arr, i32 length, const char* key); 10 | i32 StrRFind(const char** arr, i32 length, const char* key); 11 | i32 HashFind(const void* arr, i32 stride, const u32* hashes, i32 length, const void* key); 12 | i32 HashRFind(const void* arr, i32 stride, const u32* hashes, i32 length, const void* key); 13 | 14 | i32 Find_i32(const i32* values, i32 length, i32 key); 15 | i32 Find_u32(const u32* values, i32 length, u32 key); 16 | i32 Find_u64(const u64* values, i32 length, u64 key); 17 | i32 Find_ptr(const void** values, i32 length, const void* key); 18 | 19 | PIM_C_END 20 | -------------------------------------------------------------------------------- /src/common/fnv1a.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | #define Fnv32Bias 2166136261u 8 | #define Fnv32Prime 16777619u 9 | #define Fnv64Bias 14695981039346656037ull 10 | #define Fnv64Prime 1099511628211ull 11 | 12 | char FnvToUpper(char x); 13 | 14 | u32 Fnv32Char(char x, u32 hash); 15 | u32 Fnv32Byte(u8 x, u32 hash); 16 | u32 Fnv32Word(u16 x, u32 hash); 17 | u32 Fnv32Dword(u32 x, u32 hash); 18 | u32 Fnv32Qword(u64 x, u32 hash); 19 | u32 Fnv32String(char const *const pim_noalias str, u32 hash); 20 | u32 Fnv32Bytes(void const *const pim_noalias ptr, i32 nBytes, u32 hash); 21 | 22 | u64 Fnv64Char(char x, u64 hash); 23 | u64 Fnv64Byte(u8 x, u64 hash); 24 | u64 Fnv64Word(u16 x, u64 hash); 25 | u64 Fnv64Dword(u32 x, u64 hash); 26 | u64 Fnv64Qword(u64 x, u64 hash); 27 | u64 Fnv64String(char const *const pim_noalias ptr, u64 hash); 28 | u64 Fnv64Bytes(void const *const pim_noalias ptr, i32 nBytes, u64 hash); 29 | 30 | u32 HashStr(char const *const pim_noalias text); 31 | u32 HashBytes(void const *const pim_noalias ptr, i32 nBytes); 32 | 33 | PIM_C_END 34 | -------------------------------------------------------------------------------- /src/common/guid.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | typedef struct Guid_s 8 | { 9 | pim_alignas(16) 10 | u64 a; 11 | u64 b; 12 | } Guid; 13 | 14 | Guid VEC_CALL Guid_New(void); 15 | 16 | bool VEC_CALL Guid_IsNull(Guid x); 17 | bool VEC_CALL Guid_Equal(Guid lhs, Guid rhs); 18 | i32 VEC_CALL Guid_Compare(Guid lhs, Guid rhs); 19 | 20 | void VEC_CALL Guid_SetName(Guid id, const char* str); 21 | bool VEC_CALL Guid_GetName(Guid id, char* dst, i32 size); 22 | 23 | i32 VEC_CALL Guid_Find(Guid const *const pim_noalias ptr, i32 count, Guid key); 24 | // adds str to a guid->string lookup table 25 | Guid VEC_CALL Guid_FromStr(char const *const pim_noalias str); 26 | // only hashes str 27 | Guid VEC_CALL Guid_HashStr(char const *const pim_noalias str); 28 | Guid VEC_CALL Guid_HashBytes(void const *const pim_noalias ptr, i32 nBytes); 29 | 30 | void VEC_CALL Guid_Format(char* dst, i32 size, Guid value); 31 | u32 VEC_CALL Guid_HashOf(Guid x); 32 | 33 | PIM_C_END 34 | -------------------------------------------------------------------------------- /src/common/iid.c: -------------------------------------------------------------------------------- 1 | #include "common/iid.h" 2 | #include "common/atomics.h" 3 | 4 | static u32 ms_counter; 5 | 6 | u32 iid_new(void) 7 | { 8 | return inc_u32(&ms_counter, MO_Relaxed); 9 | } 10 | -------------------------------------------------------------------------------- /src/common/iid.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | u32 iid_new(void); 8 | 9 | PIM_C_END 10 | -------------------------------------------------------------------------------- /src/common/library.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | typedef struct Library_s 8 | { 9 | void* handle; 10 | } Library; 11 | 12 | bool Library_IsOpen(Library l); 13 | Library Library_Open(const char* name); 14 | void Library_Close(Library lib); 15 | void* Library_Sym(Library lib, const char* name); 16 | 17 | PIM_C_END 18 | -------------------------------------------------------------------------------- /src/common/nextpow2.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | // https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 8 | pim_inline u32 NextPow2(u32 x) 9 | { 10 | --x; 11 | x |= x >> 1; 12 | x |= x >> 2; 13 | x |= x >> 4; 14 | x |= x >> 8; 15 | x |= x >> 16; 16 | ++x; 17 | return x; 18 | } 19 | 20 | pim_inline bool IsPow2(u32 x) 21 | { 22 | return (x & (x - 1u)) == 0u; 23 | } 24 | 25 | PIM_C_END 26 | -------------------------------------------------------------------------------- /src/common/profiler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | typedef struct ProfMark_s 8 | { 9 | char const *const name; 10 | u32 calls; 11 | u64 sum; 12 | } ProfMark; 13 | 14 | void ProfileSys_Gui(bool* pEnabled); 15 | 16 | void _ProfileBegin(ProfMark *const mark); 17 | void _ProfileEnd(ProfMark *const mark); 18 | 19 | #define PIM_PROFILE 1 20 | 21 | #if PIM_PROFILE 22 | #define ProfileMark(var, tag) static ProfMark var = { #tag }; 23 | #define ProfileBegin(mark) _ProfileBegin(&(mark)) 24 | #define ProfileEnd(mark) _ProfileEnd(&(mark)) 25 | #else 26 | #define ProfileMark(var, tag) 27 | #define ProfileBegin(mark) (void)0 28 | #define ProfileEnd(mark) (void)0 29 | #endif // PIM_PROFILE 30 | 31 | PIM_C_END 32 | -------------------------------------------------------------------------------- /src/common/random.c: -------------------------------------------------------------------------------- 1 | #include "common/random.h" 2 | 3 | #include "common/time.h" 4 | #include "math/pcg.h" 5 | #include "math/uint4_funcs.h" 6 | #include "common/atomics.h" 7 | #include "threading/task.h" 8 | #include 9 | 10 | static Prng ms_prngs[kMaxThreads]; 11 | static u32 ms_counter; 12 | static char const* const ms_seeds[] = 13 | { 14 | "Xsapc69Gp4XLUEjn", 15 | "ZfbDFT8AvK46mv5r", 16 | "9zpqamNLPCR9tVQ3", 17 | "wq3BCn9ccnebyvbm", 18 | "mt9YVp8RpLbgMdkE", 19 | "hsRdvvapGzZEP7Fq", 20 | "AXFBhB5UYYKMXASZ", 21 | "T6t9QgANXez3h7tK", 22 | "ZteqCnbbAFp3Gjrw", 23 | "HhJR3zeEqAbZhxfs", 24 | "3E8SJmULPetTTrjc", 25 | "XPbuZtLE7pArMC7U", 26 | "68uPVggNF3aVB4ft", 27 | "f3HmXpHu2n4RbA3d", 28 | "8Mb4quWcmkhVLh4y", 29 | "TTUzBDpE5wbhEdQJ", 30 | }; 31 | 32 | static const char* GetSeed(u32 x) 33 | { 34 | return ms_seeds[Pcg1(x) % NELEM(ms_seeds)]; 35 | } 36 | 37 | void Random_Init(void) 38 | { 39 | for (i32 i = 0; i < NELEM(ms_prngs); ++i) 40 | { 41 | ms_prngs[i] = Prng_New(); 42 | } 43 | } 44 | 45 | Prng Prng_New(void) 46 | { 47 | Prng rng; 48 | 49 | u64 tick = Time_GetRawCounter(); 50 | uint4 vtick; 51 | vtick.x = Pcg1((u32)((tick >> 0) & 0xffff)); 52 | vtick.y = Pcg1((u32)((tick >> 16) & 0xffff)); 53 | vtick.z = Pcg1((u32)((tick >> 32) & 0xffff)); 54 | vtick.w = Pcg1((u32)((tick >> 48) & 0xffff)); 55 | u32 id0 = inc_u32(&ms_counter, MO_Relaxed) + 1; 56 | u32 id1 = Pcg1(id0); 57 | uint4 hash = { 0 }; 58 | hash = Pcg4_String(GetSeed(id0), hash); 59 | hash = Pcg4_Permute(u4_add(Pcg4_Lcg(hash), vtick)); 60 | hash = Pcg4_String(GetSeed(id1), hash); 61 | hash = Pcg4_Permute(Pcg4_Lcg(hash)); 62 | rng.state = hash; 63 | 64 | return rng; 65 | } 66 | 67 | Prng* Prng_Get(void) 68 | { 69 | return &ms_prngs[Task_ThreadId()]; 70 | } 71 | -------------------------------------------------------------------------------- /src/common/sort.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | typedef i32(*CmpFn)(const void* lhs, const void* rhs, void* usr); 8 | typedef i32(*CmpFn_i32)(i32 lhs, i32 rhs, void* usr); 9 | 10 | void MemSwap(void* lhs, void* rhs, i32 stride); 11 | 12 | void QuickSort(void* pVoid, i32 count, i32 stride, CmpFn cmp, void* usr); 13 | void QuickSort_Int(i32* items, i32 count, CmpFn_i32 cmp, void* usr); 14 | i32* IndexSort(const void* items, i32 count, i32 stride, CmpFn cmp, void* usr); 15 | 16 | PIM_C_END 17 | -------------------------------------------------------------------------------- /src/common/time.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | void TimeSys_Init(void); 8 | void TimeSys_Update(void); 9 | void TimeSys_Shutdown(void); 10 | 11 | u64 Time_GetRawCounter(void); 12 | u64 Time_GetRawFreq(void); 13 | 14 | u32 Time_FrameCount(void); 15 | u64 Time_AppStart(void); 16 | u64 Time_FrameStart(void); 17 | u64 Time_PrevFrame(void); 18 | 19 | u64 Time_Now(void); 20 | u64 Time_Delta(void); 21 | double Time_Deltaf(void); 22 | double Time_SmoothDeltaf(void); 23 | 24 | double Time_Sec(u64 ticks); 25 | double Time_Milli(u64 ticks); 26 | double Time_Micro(u64 ticks); 27 | 28 | PIM_C_END 29 | -------------------------------------------------------------------------------- /src/common/unroll.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | pim_inline void Unroll16(i32 count, i32* n16, i32* n4) 8 | { 9 | *n16 = count >> 4; 10 | *n4 = (count >> 2) & 3; 11 | } 12 | 13 | pim_inline void Unroll64(i32 count, i32* n64, i32* n8) 14 | { 15 | *n64 = count >> 6; 16 | *n8 = (count >> 3) & 7; 17 | } 18 | 19 | PIM_C_END 20 | -------------------------------------------------------------------------------- /src/containers/dict.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | typedef struct Dict_s 8 | { 9 | u32 * pim_noalias hashes; 10 | void * pim_noalias keys; 11 | void * pim_noalias values; 12 | u32 width; 13 | i32 count; 14 | u32 keySize; 15 | u32 valueSize; 16 | EAlloc allocator; 17 | } Dict; 18 | 19 | // initialize dictionary before using 20 | void Dict_New(Dict* dict, u32 keySize, u32 valueSize, EAlloc allocator); 21 | // release storage 22 | void Dict_Del(Dict* dict); 23 | 24 | // removes all entries, but doesn't affect storage 25 | void Dict_Clear(Dict* dict); 26 | // resizes table if necessary. affects order and width. 27 | void Dict_Reserve(Dict* dict, i32 count); 28 | 29 | // number of items in dictionary 30 | i32 Dict_GetCount(const Dict* dict); 31 | // find slot of a key, or -1 if it does not exist 32 | i32 Dict_Find(const Dict* dict, const void* key); 33 | // copies to valueOut if key exists 34 | bool Dict_Get(const Dict* dict, const void* key, void* valueOut); 35 | // overwrites value if key exists 36 | bool Dict_Set(Dict* dict, const void* key, const void* valueIn); 37 | // adds a key and value if it does not exist 38 | bool Dict_Add(Dict* dict, const void* key, const void* valueIn); 39 | // removes a key and value if it exists, optional copy to valueOut 40 | bool Dict_Rm(Dict* dict, const void* key, void* valueOut); 41 | // overwrites a value if key exists, otherwise adds key and value 42 | bool Dict_SetAdd(Dict* dict, const void* key, const void* valueIn); 43 | // copies to valueOut if key exists, otherwise adds key and value 44 | bool Dict_GetAdd(Dict* dict, const void* key, void* valueInOut); 45 | 46 | typedef i32(*DictCmpFn)( 47 | const void* lkey, const void* rkey, 48 | const void* lval, const void* rval, 49 | void* usr); 50 | // returns a temporary array of sorted indices into the dict. 51 | // array length matches Dict_GetCount(). 52 | u32* Dict_Sort(const Dict* dict, DictCmpFn cmp, void* usr); 53 | 54 | // number of slots, for table entry iteration. 55 | u32 Dict_GetWidth(const Dict* dict); 56 | // does table slot have a valid entry 57 | bool Dict_ValidAt(const Dict* dict, u32 slot); 58 | bool Dict_GetKeyAt(const Dict* dict, u32 slot, void* keyOut); 59 | bool Dict_GetValueAt(const Dict* dict, u32 slot, void* valueOut); 60 | bool Dict_SetValueAt(Dict* dict, u32 slot, const void* valueIn); 61 | bool Dict_GetAt(const Dict* dict, u32 slot, void* keyOut, void* valueOut); 62 | // removes a key and value at slot if it exists. 63 | bool Dict_RmAt(Dict* dict, u32 slot, void* valueOut); 64 | 65 | PIM_C_END 66 | -------------------------------------------------------------------------------- /src/containers/genid.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | -------------------------------------------------------------------------------- /src/containers/graph.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | typedef struct Graph_s 8 | { 9 | void* verts; 10 | i32 length; 11 | EAlloc allocator; 12 | } Graph; 13 | 14 | void Graph_New(Graph* graph, EAlloc allocator); 15 | void Graph_Del(Graph* graph); 16 | 17 | void Graph_Clear(Graph* graph); 18 | 19 | i32 Graph_Size(const Graph* graph); 20 | void Graph_Sort(Graph* graph, i32* order, i32 length); 21 | 22 | i32 Graph_AddVert(Graph* graph); 23 | bool Graph_AddEdge(Graph* graph, i32 srcVert, i32 dstVert); 24 | const i32* Graph_Edges(const Graph* graph, i32 dstVert, i32* pLength); 25 | 26 | PIM_C_END 27 | -------------------------------------------------------------------------------- /src/containers/hash_set.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | typedef struct HashSet_s 8 | { 9 | u32* hashes; 10 | void* keys; 11 | u32 count; 12 | u32 width; 13 | u32 keySize; 14 | EAlloc allocator; 15 | } HashSet; 16 | 17 | void HashSet_New(HashSet* set, u32 keySize, EAlloc allocator); 18 | void HashSet_Del(HashSet* set); 19 | void HashSet_Clear(HashSet* set); 20 | void HashSet_Reserve(HashSet* set, u32 minCount); 21 | bool HashSet_Contains(const HashSet* set, const void* key, u32 keySize); 22 | bool HashSet_Add(HashSet* set, const void* key, u32 keySize); 23 | bool HashSet_Rm(HashSet* set, const void* key, u32 keySize); 24 | 25 | PIM_C_END 26 | -------------------------------------------------------------------------------- /src/containers/hash_util.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | #include "common/fnv1a.h" 8 | #include "common/nextpow2.h" 9 | 10 | #define hashutil_tomb_mask (1u << 31u) 11 | #define hashutil_hash_mask (~hashutil_tomb_mask) 12 | 13 | pim_inline u32 HashUtil_Filled(u32 hash) 14 | { 15 | return hash & 1u; 16 | } 17 | 18 | pim_inline u32 HashUtil_Tomb(u32 hash) 19 | { 20 | return (hash >> 31u) & 1u; 21 | } 22 | 23 | pim_inline u32 HashUtil_Empty(u32 hash) 24 | { 25 | return HashUtil_Filled(~hash); 26 | } 27 | 28 | pim_inline u32 HashUtil_NotTomb(u32 hash) 29 | { 30 | return HashUtil_Tomb(~hash); 31 | } 32 | 33 | pim_inline u32 HashUtil_EmptyOrTomb(u32 hash) 34 | { 35 | return HashUtil_Empty(hash) | HashUtil_Tomb(hash); 36 | } 37 | 38 | pim_inline u32 HashUtil_Valid(u32 hash) 39 | { 40 | return HashUtil_Filled(hash) & HashUtil_NotTomb(hash); 41 | } 42 | 43 | pim_inline u32 HashUtil_CreateHash(u32 hash) 44 | { 45 | return (hash | 1u) & hashutil_hash_mask; 46 | } 47 | 48 | pim_inline u32 HashUtil_HashBytes(void const *const pim_noalias key, i32 sizeOf) 49 | { 50 | return HashUtil_CreateHash(Fnv32Bytes(key, sizeOf, Fnv32Bias)); 51 | } 52 | 53 | PIM_C_END 54 | -------------------------------------------------------------------------------- /src/containers/idalloc.c: -------------------------------------------------------------------------------- 1 | #include "containers/idalloc.h" 2 | #include "allocator/allocator.h" 3 | #include 4 | 5 | void IdAlloc_New(IdAlloc* ia) 6 | { 7 | memset(ia, 0, sizeof(*ia)); 8 | } 9 | 10 | void IdAlloc_Del(IdAlloc* ia) 11 | { 12 | Mem_Free(ia->versions); 13 | IntQueue_Del(&ia->freelist); 14 | memset(ia, 0, sizeof(*ia)); 15 | } 16 | 17 | i32 IdAlloc_Capacity(const IdAlloc* ia) 18 | { 19 | return ia->length; 20 | } 21 | 22 | i32 IdAlloc_Size(const IdAlloc* ia) 23 | { 24 | return ia->length - (i32)IntQueue_Size(&ia->freelist); 25 | } 26 | 27 | void IdAlloc_Clear(IdAlloc* ia) 28 | { 29 | ia->length = 0; 30 | IntQueue_Clear(&ia->freelist); 31 | } 32 | 33 | bool IdAlloc_Exists(const IdAlloc* ia, GenId id) 34 | { 35 | i32 i = id.index; 36 | u8 v = id.version; 37 | return (i < ia->length) && (ia->versions[i] == v); 38 | } 39 | 40 | bool IdAlloc_ExistsAt(const IdAlloc* ia, i32 index) 41 | { 42 | ASSERT((u32)index < (u32)ia->length); 43 | return ia->versions[index] & 1; 44 | } 45 | 46 | GenId IdAlloc_Alloc(IdAlloc* ia) 47 | { 48 | i32 index = 0; 49 | if (!IntQueue_TryPop(&ia->freelist, &index)) 50 | { 51 | index = ia->length++; 52 | Perm_Reserve(ia->versions, ia->length); 53 | ia->versions[index] = 0; 54 | } 55 | u8 version = ++(ia->versions[index]); 56 | GenId id; 57 | id.version = version; 58 | id.index = index; 59 | ASSERT(version & 1); 60 | return id; 61 | } 62 | 63 | bool IdAlloc_Free(IdAlloc* ia, GenId id) 64 | { 65 | if (IdAlloc_Exists(ia, id)) 66 | { 67 | i32 index = id.index; 68 | ia->versions[index]++; 69 | IntQueue_Push(&ia->freelist, index); 70 | ASSERT(!(ia->versions[index] & 1)); 71 | return true; 72 | } 73 | return false; 74 | } 75 | 76 | bool IdAlloc_FreeAt(IdAlloc* ia, i32 index) 77 | { 78 | if (IdAlloc_ExistsAt(ia, index)) 79 | { 80 | ia->versions[index]++; 81 | IntQueue_Push(&ia->freelist, index); 82 | return true; 83 | } 84 | return false; 85 | } 86 | -------------------------------------------------------------------------------- /src/containers/idalloc.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | #include "containers/queue_i32.h" 5 | #include "containers/genid.h" 6 | 7 | PIM_C_BEGIN 8 | 9 | typedef struct IdAlloc_s 10 | { 11 | i32 length; 12 | u8* pim_noalias versions; 13 | IntQueue freelist; 14 | } IdAlloc; 15 | 16 | void IdAlloc_New(IdAlloc* ia); 17 | void IdAlloc_Del(IdAlloc* ia); 18 | void IdAlloc_Clear(IdAlloc* ia); 19 | 20 | i32 IdAlloc_Capacity(const IdAlloc* ia); 21 | i32 IdAlloc_Size(const IdAlloc* ia); 22 | 23 | bool IdAlloc_Exists(const IdAlloc* ia, GenId id); 24 | bool IdAlloc_ExistsAt(const IdAlloc* ia, i32 index); 25 | 26 | GenId IdAlloc_Alloc(IdAlloc* ia); 27 | 28 | bool IdAlloc_Free(IdAlloc* ia, GenId id); 29 | bool IdAlloc_FreeAt(IdAlloc* ia, i32 index); 30 | 31 | PIM_C_END 32 | -------------------------------------------------------------------------------- /src/containers/lookup.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | #include "common/guid.h" 5 | 6 | typedef struct Lookup_s 7 | { 8 | i32* pim_noalias indices; 9 | u32 width; 10 | } Lookup; 11 | 12 | void Lookup_New(Lookup *const loo); 13 | void Lookup_Del(Lookup *const loo); 14 | 15 | void Lookup_Reserve( 16 | Lookup *const loo, 17 | const Guid* pim_noalias names, 18 | i32 nameCount, 19 | i32 capacity); 20 | 21 | i32 Lookup_Insert( 22 | Lookup *const loo, 23 | const Guid* pim_noalias names, 24 | i32 nameCount, 25 | Guid key, 26 | i32 keyIndex); 27 | 28 | bool Lookup_Find( 29 | Lookup const *const loo, 30 | const Guid* pim_noalias names, 31 | i32 nameCount, 32 | Guid key, 33 | i32 *const pim_noalias nameIndexOut, 34 | i32 *const pim_noalias iLookupOut); 35 | 36 | void Lookup_Remove( 37 | Lookup *const loo, 38 | i32 keyIndex, 39 | i32 iLookup); 40 | 41 | void Lookup_Clear(Lookup *const loo); 42 | -------------------------------------------------------------------------------- /src/containers/ptrqueue.c: -------------------------------------------------------------------------------- 1 | #include "containers/ptrqueue.h" 2 | #include "common/atomics.h" 3 | #include "common/nextpow2.h" 4 | #include "allocator/allocator.h" 5 | 6 | void PtrQueue_New(PtrQueue *const pq, EAlloc allocator, u32 capacity) 7 | { 8 | ASSERT(pq); 9 | pq->iWrite = 0; 10 | pq->iRead = 0; 11 | pq->width = 0; 12 | pq->ptr = NULL; 13 | pq->allocator = allocator; 14 | ASSERT(capacity); 15 | 16 | const u32 width = NextPow2(capacity); 17 | pq->width = width; 18 | pq->ptr = Mem_Calloc(allocator, sizeof(pq->ptr[0]) * width); 19 | } 20 | 21 | void PtrQueue_Del(PtrQueue *const pq) 22 | { 23 | Mem_Free(pq->ptr); 24 | pq->ptr = NULL; 25 | store_u32(&(pq->width), 0, MO_Release); 26 | store_u32(&(pq->iWrite), 0, MO_Release); 27 | store_u32(&(pq->iRead), 0, MO_Release); 28 | } 29 | 30 | u32 PtrQueue_Capacity(PtrQueue const *const pq) 31 | { 32 | ASSERT(pq); 33 | return load_u32(&pq->width, MO_Acquire); 34 | } 35 | 36 | u32 PtrQueue_Size(PtrQueue const *const pq) 37 | { 38 | ASSERT(pq); 39 | return load_u32(&pq->iWrite, MO_Acquire) - load_u32(&pq->iRead, MO_Acquire); 40 | } 41 | 42 | bool PtrQueue_TryPush(PtrQueue *const pq, void *const pValue) 43 | { 44 | ASSERT(pq); 45 | ASSERT(pValue); 46 | const isize iPtr = (isize)pValue; 47 | const u32 mask = pq->width - 1u; 48 | isize *const pim_noalias ptr = pq->ptr; 49 | for (u32 i = load_u32(&pq->iWrite, MO_Acquire); PtrQueue_Size(pq) <= mask; ++i) 50 | { 51 | i &= mask; 52 | isize prev = load_isize(ptr + i, MO_Relaxed); 53 | if (!prev && cmpex_isize(ptr + i, &prev, iPtr, MO_Acquire)) 54 | { 55 | inc_u32(&pq->iWrite, MO_Release); 56 | return true; 57 | } 58 | } 59 | return false; 60 | } 61 | 62 | void *const PtrQueue_TryPop(PtrQueue *const pq) 63 | { 64 | ASSERT(pq); 65 | const u32 mask = pq->width - 1u; 66 | isize *const pim_noalias ptr = pq->ptr; 67 | for (u32 i = load_u32(&pq->iRead, MO_Acquire); PtrQueue_Size(pq); ++i) 68 | { 69 | i &= mask; 70 | isize prev = load_isize(ptr + i, MO_Relaxed); 71 | if (prev && cmpex_isize(ptr + i, &prev, 0, MO_Acquire)) 72 | { 73 | inc_u32(&pq->iRead, MO_Release); 74 | ASSERT(prev); 75 | return (void *const)prev; 76 | } 77 | } 78 | return NULL; 79 | } 80 | -------------------------------------------------------------------------------- /src/containers/ptrqueue.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | typedef struct PtrQueue_s 8 | { 9 | u32 iWrite; 10 | u32 iRead; 11 | u32 width; 12 | isize* ptr; 13 | EAlloc allocator; 14 | } PtrQueue; 15 | 16 | void PtrQueue_New(PtrQueue *const pq, EAlloc allocator, u32 capacity); 17 | void PtrQueue_Del(PtrQueue *const pq); 18 | u32 PtrQueue_Capacity(PtrQueue const *const pq); 19 | u32 PtrQueue_Size(PtrQueue const *const pq); 20 | bool PtrQueue_TryPush(PtrQueue *const pq, void *const pValue); 21 | void *const PtrQueue_TryPop(PtrQueue *const pq); 22 | 23 | PIM_C_END 24 | -------------------------------------------------------------------------------- /src/containers/queue.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | typedef struct Queue_s 8 | { 9 | void* ptr; 10 | u32 width; 11 | u32 iRead; 12 | u32 iWrite; 13 | u32 valueSize; 14 | EAlloc allocator; 15 | } Queue; 16 | 17 | void Queue_New(Queue* queue, u32 valueSize, EAlloc allocator); 18 | void Queue_Del(Queue* queue); 19 | 20 | u32 Queue_Size(const Queue* queue); 21 | u32 Queue_Capacity(const Queue* queue); 22 | 23 | void Queue_Clear(Queue* queue); 24 | void Queue_Reserve(Queue* queue, u32 capacity); 25 | 26 | void Queue_Push(Queue* queue, const void* src, u32 itemSize); 27 | void Queue_PushFront(Queue* queue, const void* src, u32 itemSize); 28 | bool Queue_TryPop(Queue* queue, void* dst, u32 itemSize); 29 | void Queue_Get(Queue* queue, u32 i, void* dst, u32 itemSize); 30 | 31 | PIM_C_END 32 | -------------------------------------------------------------------------------- /src/containers/queue_i32.c: -------------------------------------------------------------------------------- 1 | #include "containers/queue_i32.h" 2 | #include "common/nextpow2.h" 3 | #include "allocator/allocator.h" 4 | #include 5 | 6 | void IntQueue_New(IntQueue* q) 7 | { 8 | memset(q, 0, sizeof(*q)); 9 | } 10 | 11 | void IntQueue_Del(IntQueue* q) 12 | { 13 | Mem_Free(q->ptr); 14 | memset(q, 0, sizeof(*q)); 15 | } 16 | 17 | void IntQueue_Clear(IntQueue* q) 18 | { 19 | q->iRead = 0; 20 | q->iWrite = 0; 21 | } 22 | 23 | u32 IntQueue_Size(const IntQueue* q) 24 | { 25 | return q->iWrite - q->iRead; 26 | } 27 | 28 | u32 IntQueue_Capacity(const IntQueue* q) 29 | { 30 | return q->width; 31 | } 32 | 33 | void IntQueue_Reserve(IntQueue* q, u32 capacity) 34 | { 35 | capacity = capacity > 16 ? capacity : 16; 36 | const u32 newWidth = NextPow2(capacity); 37 | const u32 oldWidth = q->width; 38 | if (newWidth > oldWidth) 39 | { 40 | i32 *const pim_noalias oldPtr = q->ptr; 41 | i32 *const pim_noalias newPtr = Perm_Calloc(sizeof(*newPtr) * newWidth); 42 | const u32 iRead = q->iRead; 43 | const u32 len = q->iWrite - iRead; 44 | const u32 mask = oldWidth - 1u; 45 | for (u32 i = 0; i < len; ++i) 46 | { 47 | u32 j = (iRead + i) & mask; 48 | newPtr[i] = oldPtr[j]; 49 | } 50 | Mem_Free(oldPtr); 51 | q->ptr = newPtr; 52 | q->width = newWidth; 53 | q->iRead = 0; 54 | q->iWrite = len; 55 | } 56 | } 57 | 58 | void IntQueue_Push(IntQueue* q, i32 value) 59 | { 60 | IntQueue_Reserve(q, IntQueue_Size(q) + 1); 61 | u32 mask = q->width - 1; 62 | u32 dst = q->iWrite++; 63 | q->ptr[dst & mask] = value; 64 | } 65 | 66 | bool IntQueue_TryPop(IntQueue* q, i32* pim_noalias valueOut) 67 | { 68 | ASSERT(valueOut); 69 | if (IntQueue_Size(q)) 70 | { 71 | u32 mask = q->width - 1; 72 | u32 src = q->iRead++; 73 | *valueOut = q->ptr[src & mask]; 74 | return true; 75 | } 76 | return false; 77 | } 78 | -------------------------------------------------------------------------------- /src/containers/queue_i32.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | typedef struct IntQueue_s 8 | { 9 | i32* pim_noalias ptr; 10 | u32 width; 11 | u32 iRead; 12 | u32 iWrite; 13 | } IntQueue; 14 | 15 | void IntQueue_New(IntQueue* q); 16 | void IntQueue_Del(IntQueue* q); 17 | void IntQueue_Clear(IntQueue* q); 18 | 19 | u32 IntQueue_Size(const IntQueue* q); 20 | u32 IntQueue_Capacity(const IntQueue* q); 21 | 22 | void IntQueue_Reserve(IntQueue* q, u32 capacity); 23 | 24 | void IntQueue_Push(IntQueue* q, i32 value); 25 | bool IntQueue_TryPop(IntQueue* q, i32* pim_noalias valueOut); 26 | 27 | PIM_C_END 28 | -------------------------------------------------------------------------------- /src/containers/sdict.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | typedef struct StrDict_s 8 | { 9 | u32* hashes; 10 | char** keys; 11 | void* values; 12 | u32 width; 13 | u32 count; 14 | u32 valueSize; 15 | EAlloc allocator; 16 | } StrDict; 17 | 18 | void StrDict_New(StrDict* dict, u32 valueSize, EAlloc allocator); 19 | void StrDict_Del(StrDict* dict); 20 | 21 | void StrDict_Clear(StrDict* dict); 22 | void StrDict_Reserve(StrDict* dict, i32 count); 23 | 24 | i32 StrDict_Find(const StrDict* dict, const char* key); 25 | bool StrDict_Get(const StrDict* dict, const char* key, void* valueOut); 26 | bool StrDict_Set(StrDict* dict, const char* key, const void* value); 27 | bool StrDict_Add(StrDict* dict, const char* key, const void* value); 28 | bool StrDict_Rm(StrDict* dict, const char* key, void* valueOut); 29 | 30 | typedef i32(*SDictCmpFn)( 31 | const char* lkey, const char* rkey, 32 | const void* lval, const void* rval, 33 | void* usr); 34 | 35 | u32* StrDict_Sort(const StrDict* dict, SDictCmpFn cmp, void* usr); 36 | 37 | // StrCmp sort metric 38 | i32 SDictStrCmp( 39 | const char* lKey, const char* rKey, 40 | const void* lVal, const void* rVal, 41 | void* usr); 42 | 43 | PIM_C_END 44 | -------------------------------------------------------------------------------- /src/containers/strlist.c: -------------------------------------------------------------------------------- 1 | #include "containers/strlist.h" 2 | #include "allocator/allocator.h" 3 | #include "common/stringutil.h" 4 | #include 5 | 6 | void StrList_New(StrList* list, EAlloc allocator) 7 | { 8 | memset(list, 0, sizeof(*list)); 9 | list->allocator = allocator; 10 | } 11 | 12 | void StrList_Del(StrList* list) 13 | { 14 | StrList_Clear(list); 15 | Mem_Free(list->ptr); 16 | list->ptr = NULL; 17 | } 18 | 19 | void StrList_Clear(StrList* list) 20 | { 21 | i32 len = list->count; 22 | char** pim_noalias ptr = list->ptr; 23 | for (i32 i = 0; i < len; ++i) 24 | { 25 | Mem_Free(ptr[i]); 26 | ptr[i] = NULL; 27 | } 28 | list->count = 0; 29 | } 30 | 31 | void StrList_Add(StrList* list, const char* item) 32 | { 33 | ASSERT(item); 34 | i32 len = ++list->count; 35 | list->ptr = Mem_Realloc(list->allocator, list->ptr, sizeof(list->ptr[0]) * len); 36 | list->ptr[len - 1] = StrDup(item, list->allocator); 37 | } 38 | 39 | void StrList_Rm(StrList* list, i32 i) 40 | { 41 | i32 len = list->count; 42 | i32 back = len - 1; 43 | ASSERT(i < len); 44 | ASSERT(back >= 0); 45 | list->count = back; 46 | char** const pim_noalias ptr = list->ptr; 47 | Mem_Free(ptr[i]); 48 | ptr[i] = ptr[back]; 49 | ptr[back] = NULL; 50 | } 51 | 52 | i32 StrList_Find(const StrList* list, const char* key) 53 | { 54 | ASSERT(key); 55 | const i32 len = list->count; 56 | char** const pim_noalias ptr = list->ptr; 57 | for (i32 i = 0; i < len; ++i) 58 | { 59 | if (StrCmp(ptr[i], PIM_PATH, key) == 0) 60 | { 61 | return i; 62 | } 63 | } 64 | return -1; 65 | } 66 | -------------------------------------------------------------------------------- /src/containers/strlist.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | typedef struct StrList_s 8 | { 9 | char** ptr; 10 | i32 count; 11 | EAlloc allocator; 12 | } StrList; 13 | 14 | void StrList_New(StrList* list, EAlloc allocator); 15 | void StrList_Del(StrList* list); 16 | void StrList_Clear(StrList* list); 17 | void StrList_Add(StrList* list, const char* item); 18 | void StrList_Rm(StrList* list, i32 i); 19 | i32 StrList_Find(const StrList* list, const char* key); 20 | 21 | PIM_C_END 22 | -------------------------------------------------------------------------------- /src/containers/table.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | #include "containers/queue_i32.h" 5 | #include "containers/lookup.h" 6 | #include "containers/genid.h" 7 | #include "common/guid.h" 8 | 9 | PIM_C_BEGIN 10 | 11 | typedef struct Table_s 12 | { 13 | i32 width; 14 | i32 valueSize; 15 | u8* pim_noalias versions; 16 | void* pim_noalias values; 17 | i32* pim_noalias refcounts; 18 | Guid* pim_noalias names; 19 | IntQueue freelist; 20 | Lookup lookup; 21 | i32 itemCount; 22 | } Table; 23 | 24 | void Table_New(Table *const table, i32 valueSize); 25 | void Table_Del(Table *const table); 26 | 27 | void Table_Clear(Table *const table); 28 | 29 | bool Table_Exists(Table const *const table, GenId id); 30 | 31 | bool Table_Add(Table *const table, Guid name, const void *const valueIn, GenId *const idOut); 32 | bool Table_Retain(Table *const table, GenId id); 33 | bool Table_Release(Table *const table, GenId id, void *const valueOut); 34 | 35 | void *const Table_Get(const Table *const table, GenId id); 36 | 37 | bool Table_Find(const Table *const table, Guid name, GenId *const idOut); 38 | bool Table_GetName(const Table *const table, GenId id, Guid *const nameOut); 39 | 40 | PIM_C_END 41 | -------------------------------------------------------------------------------- /src/containers/text.c: -------------------------------------------------------------------------------- 1 | #include "containers/text.h" 2 | #include "common/stringutil.h" 3 | 4 | #include 5 | 6 | void Text_New(void* txt, i32 sizeOf, const char* str) 7 | { 8 | ASSERT(txt); 9 | ASSERT(sizeOf > 0); 10 | ASSERT(str); 11 | // zero entire struct out, as Text is used for dictionary keys 12 | // which will hash past the null terminator. 13 | memset(txt, 0, sizeOf); 14 | StrCpy(txt, sizeOf, str); 15 | } 16 | -------------------------------------------------------------------------------- /src/containers/text.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | typedef struct Text16_s 8 | { 9 | char c[16]; 10 | } Text16; 11 | 12 | typedef struct Text32_s 13 | { 14 | char c[32]; 15 | } Text32; 16 | 17 | typedef struct Text64_s 18 | { 19 | char c[64]; 20 | } Text64; 21 | 22 | typedef struct Text128_s 23 | { 24 | char c[128]; 25 | } Text128; 26 | 27 | typedef struct Text256_s 28 | { 29 | char c[256]; 30 | } Text256; 31 | 32 | typedef struct Text512_s 33 | { 34 | char c[512]; 35 | } Text512; 36 | 37 | typedef struct Text1k_s 38 | { 39 | char c[1024]; 40 | } Text1k; 41 | 42 | typedef struct Text2k_s 43 | { 44 | char c[2048]; 45 | } Text2k; 46 | 47 | typedef struct Text4k_s 48 | { 49 | char c[4096]; 50 | } Text4k; 51 | 52 | void Text_New(void* txt, i32 sizeOf, const char* str); 53 | 54 | PIM_C_END 55 | -------------------------------------------------------------------------------- /src/editor/editor.c: -------------------------------------------------------------------------------- 1 | #include "editor/editor.h" 2 | #include "editor/menubar.h" 3 | #include "common/profiler.h" 4 | 5 | // ---------------------------------------------------------------------------- 6 | 7 | void EditorSys_Init(void) 8 | { 9 | MenuBar_Init(); 10 | } 11 | 12 | ProfileMark(pm_update, EditorSys_Update) 13 | void EditorSys_Update(void) 14 | { 15 | ProfileBegin(pm_update); 16 | 17 | MenuBar_Update(); 18 | 19 | ProfileEnd(pm_update); 20 | } 21 | 22 | void EditorSys_Shutdown(void) 23 | { 24 | MenuBar_Shutdown(); 25 | } 26 | 27 | // ---------------------------------------------------------------------------- 28 | -------------------------------------------------------------------------------- /src/editor/editor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | void EditorSys_Init(void); 8 | void EditorSys_Update(void); 9 | void EditorSys_Shutdown(void); 10 | 11 | PIM_C_END 12 | -------------------------------------------------------------------------------- /src/editor/menubar.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | void MenuBar_Init(void); 8 | void MenuBar_Update(void); 9 | void MenuBar_Shutdown(void); 10 | 11 | PIM_C_END 12 | -------------------------------------------------------------------------------- /src/io/dir.c: -------------------------------------------------------------------------------- 1 | #include "io/dir.h" 2 | 3 | pim_inline void* NotNull(void* x) 4 | { 5 | ASSERT(x != NULL); 6 | return x; 7 | } 8 | 9 | pim_inline i32 IsZero(i32 x) 10 | { 11 | ASSERT(x == 0); 12 | return x; 13 | } 14 | 15 | static char* GetCwd(char* dst, i32 size); 16 | static i32 ChDir(const char* path); 17 | static i32 RmDir(const char* path); 18 | static i32 ChMod(const char* filename, i32 mode); 19 | static i32 MkDir(const char* path); 20 | 21 | bool IO_GetCwd(char* dst, i32 size) 22 | { 23 | ASSERT(dst); 24 | ASSERT(size > 0); 25 | return NotNull(GetCwd(dst, size - 1)) != NULL; 26 | } 27 | 28 | bool IO_ChDir(const char* path) 29 | { 30 | ASSERT(path); 31 | return IsZero(ChDir(path)) == 0; 32 | } 33 | 34 | bool IO_MkDir(const char* path) 35 | { 36 | ASSERT(path); 37 | return MkDir(path) == 0; 38 | } 39 | 40 | bool IO_RmDir(const char* path) 41 | { 42 | ASSERT(path); 43 | return IsZero(RmDir(path)) == 0; 44 | } 45 | 46 | bool IO_ChMod(const char* path, i32 flags) 47 | { 48 | ASSERT(path); 49 | return IsZero(ChMod(path, flags)) == 0; 50 | } 51 | 52 | #if PLAT_WINDOWS 53 | #include 54 | #include 55 | 56 | static char* GetCwd(char* dst, i32 size) 57 | { 58 | return _getcwd(dst, size); 59 | } 60 | static i32 ChDir(const char* path) 61 | { 62 | return _chdir(path); 63 | } 64 | static i32 RmDir(const char* path) 65 | { 66 | return _rmdir(path); 67 | } 68 | static i32 ChMod(const char* filename, i32 mode) 69 | { 70 | return _chmod(filename, mode); 71 | } 72 | static i32 MkDir(const char* path) 73 | { 74 | return _mkdir(path); 75 | } 76 | 77 | #else 78 | #include 79 | #include 80 | 81 | static char* GetCwd(char* dst, i32 size) 82 | { 83 | return getcwd(dst, size); 84 | } 85 | static i32 ChDir(const char* path) 86 | { 87 | return chdir(path); 88 | } 89 | static i32 RmDir(const char* path) 90 | { 91 | return rmdir(path); 92 | } 93 | static i32 ChMod(const char* filename, i32 mode) 94 | { 95 | return chmod(filename, mode); 96 | } 97 | static i32 MkDir(const char* path) 98 | { 99 | return mkdir(path, 0755); 100 | } 101 | 102 | #endif // PLAT_XXX 103 | -------------------------------------------------------------------------------- /src/io/dir.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | bool IO_GetCwd(char* dst, i32 size); 8 | bool IO_ChDir(const char* path); 9 | bool IO_MkDir(const char* path); 10 | bool IO_RmDir(const char* path); 11 | bool IO_ChMod(const char* path, i32 flags); 12 | 13 | PIM_C_END 14 | -------------------------------------------------------------------------------- /src/io/env.c: -------------------------------------------------------------------------------- 1 | #include "io/env.h" 2 | 3 | #include "common/stringutil.h" 4 | #include 5 | 6 | #if PLAT_WINDOWS 7 | #ifndef putenv 8 | # define putenv(p) _putenv((p)) 9 | #endif // putenv 10 | #endif // PLAT_WINDOWS 11 | 12 | static void* NotNull(void* x) 13 | { 14 | ASSERT(x != NULL); 15 | return x; 16 | } 17 | 18 | static i32 IsZero(i32 x) 19 | { 20 | ASSERT(x == 0); 21 | return x; 22 | } 23 | 24 | const char* Env_Get(const char* varname) 25 | { 26 | ASSERT(varname); 27 | return NotNull(getenv(varname)); 28 | } 29 | 30 | bool Env_Set(const char* varname, const char* value) 31 | { 32 | ASSERT(varname); 33 | char buf[260] = { 0 }; 34 | SPrintf(ARGS(buf), "%s=%s", varname, value ? value : ""); 35 | return IsZero(putenv(buf)) == 0; 36 | } 37 | -------------------------------------------------------------------------------- /src/io/env.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | const char* Env_Get(const char* varname); 8 | bool Env_Set(const char* varname, const char* value); 9 | 10 | PIM_C_END 11 | -------------------------------------------------------------------------------- /src/io/fd.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "io/types.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | extern const fd_t fd_stdin; 8 | extern const fd_t fd_stdout; 9 | extern const fd_t fd_stderr; 10 | 11 | bool fd_isopen(fd_t fd); 12 | fd_t fd_new(const char* filename); 13 | fd_t fd_open(const char* filename, bool writable); 14 | bool fd_close(fd_t* hdl); 15 | 16 | i32 fd_read(fd_t hdl, void* dst, i32 size); 17 | i32 fd_write(fd_t hdl, const void* src, i32 size); 18 | 19 | i32 fd_puts(fd_t hdl, const char* str); 20 | i32 fd_printf(fd_t hdl, const char* fmt, ...); 21 | 22 | bool fd_seek(fd_t hdl, i32 offset); 23 | i32 fd_tell(fd_t hdl); 24 | 25 | bool fd_pipe(fd_t* p0, fd_t* p1, i32 bufferSize); 26 | bool fd_stat(fd_t hdl, fd_status_t* status); 27 | i64 fd_size(fd_t hdl); 28 | 29 | PIM_C_END 30 | -------------------------------------------------------------------------------- /src/io/fmap.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "io/types.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | bool FileMap_IsOpen(const FileMap* map); 8 | 9 | // memory maps the file descriptor 10 | FileMap FileMap_New(fd_t fd, bool writable); 11 | 12 | // does not close file descriptor 13 | void FileMap_Del(FileMap* map); 14 | 15 | // writes changes in mapped memory back to source 16 | bool FileMap_Flush(FileMap* map); 17 | 18 | // owns descriptor 19 | FileMap FileMap_Open(const char* path, bool writable); 20 | // owns descriptor 21 | void FileMap_Close(FileMap* map); 22 | 23 | PIM_C_END 24 | -------------------------------------------------------------------------------- /src/io/fnd.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "io/types.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | bool Finder_IsOpen(Finder* fdr); 8 | bool Finder_Begin(Finder* fdr, FinderData* data, const char* path); 9 | bool Finder_Next(Finder* fdr, FinderData* data, const char* path); 10 | // Always call End if you call Begin, or a leak occurs. 11 | void Finder_End(Finder* fdr); 12 | 13 | // Begin + Next + Close 14 | bool Finder_Iterate(Finder* fdr, FinderData* data, const char* path); 15 | 16 | PIM_C_END 17 | -------------------------------------------------------------------------------- /src/io/fstr.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "io/types.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | bool FStream_IsOpen(FStream fstr); 8 | FStream FStream_Open(const char* filename, const char* mode); 9 | bool FStream_Close(FStream* stream); 10 | bool FStream_Flush(FStream stream); 11 | bool FStream_AtEnd(FStream stream); 12 | i32 FStream_Read(FStream stream, void* dst, i32 size); 13 | i32 FStream_Write(FStream stream, const void* src, i32 size); 14 | bool FStream_Gets(FStream stream, char* dst, i32 size); 15 | i32 FStream_Getc(FStream stream); 16 | i32 FStream_Puts(FStream stream, const char* src); 17 | i32 FStream_VPrintf(FStream stream, const char* fmt, va_list ap); 18 | i32 FStream_Printf(FStream stream, const char* fmt, ...); 19 | i32 FStream_VScanf(FStream stream, const char* fmt, va_list ap); 20 | i32 FStream_Scanf(FStream stream, const char* fmt, ...); 21 | 22 | fd_t FStream_ToFd(FStream stream); 23 | FStream Fd_ToFStream(fd_t* hdl, const char* mode); 24 | 25 | bool FStream_Seek(FStream stream, i32 offset); 26 | i32 FStream_Tell(FStream stream); 27 | 28 | FStream FStream_POpen(const char* cmd, const char* mode); 29 | bool FStream_PClose(FStream* stream); 30 | 31 | bool FStream_Stat(FStream stream, fd_status_t* status); 32 | i64 FStream_Size(FStream stream); 33 | 34 | PIM_C_END 35 | -------------------------------------------------------------------------------- /src/io/types.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | // ------------------------------------ 8 | // fd 9 | 10 | typedef struct fd_s { i32 handle; } fd_t; 11 | 12 | // only the fields we actually care about from stat 13 | typedef struct fd_status_s 14 | { 15 | i64 size; 16 | i64 accessTime; 17 | i64 modifyTime; 18 | i64 createTime; 19 | } fd_status_t; 20 | 21 | // ------------------------------------ 22 | // fmap 23 | 24 | typedef struct FileMap_s 25 | { 26 | void* ptr; 27 | i32 size; 28 | fd_t fd; 29 | } FileMap; 30 | 31 | // ------------------------------------ 32 | // fstr 33 | 34 | typedef struct FStream_s 35 | { 36 | void* handle; 37 | } FStream; 38 | 39 | // ------------------------------------ 40 | // dir 41 | 42 | typedef enum 43 | { 44 | ChMod_Read = 0x0100, 45 | ChMod_Write = 0x0080, 46 | ChMod_Exec = 0x0040, 47 | } ChModFlags; 48 | 49 | // ------------------------------------ 50 | // fnd 51 | 52 | typedef struct Finder_s 53 | { 54 | void* handle; 55 | } Finder; 56 | 57 | typedef struct FinderData_s 58 | { 59 | char path[PIM_PATH]; 60 | i64 size; 61 | i64 accessTime; 62 | i64 modifyTime; 63 | i64 createTime; 64 | u32 isNormal : 1; 65 | u32 isReadOnly : 1; 66 | u32 isHidden : 1; 67 | u32 isSystem : 1; 68 | u32 isFolder : 1; 69 | u32 isArchive : 1; 70 | } FinderData; 71 | 72 | // ------------------------------------ 73 | 74 | PIM_C_END 75 | -------------------------------------------------------------------------------- /src/logic/camera_logic.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | void CameraLogic_Init(void); 8 | void CameraLogic_Update(void); 9 | void CameraLogic_Shutdown(void); 10 | 11 | PIM_C_END 12 | -------------------------------------------------------------------------------- /src/logic/logic.c: -------------------------------------------------------------------------------- 1 | #include "logic/logic.h" 2 | #include "logic/camera_logic.h" 3 | #include "common/profiler.h" 4 | 5 | void LogicSys_Init(void) 6 | { 7 | CameraLogic_Init(); 8 | } 9 | 10 | ProfileMark(pm_update, LogicSys_Update) 11 | void LogicSys_Update(void) 12 | { 13 | ProfileBegin(pm_update); 14 | 15 | CameraLogic_Update(); 16 | 17 | ProfileEnd(pm_update); 18 | } 19 | 20 | void LogicSys_Shutdown(void) 21 | { 22 | CameraLogic_Shutdown(); 23 | } 24 | -------------------------------------------------------------------------------- /src/logic/logic.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | void LogicSys_Init(void); 8 | void LogicSys_Update(void); 9 | void LogicSys_Shutdown(void); 10 | 11 | PIM_C_END 12 | -------------------------------------------------------------------------------- /src/math/ambcube.c: -------------------------------------------------------------------------------- 1 | #include "math/ambcube.h" 2 | #include "rendering/path_tracer.h" 3 | #include "math/float3_funcs.h" 4 | 5 | i32 AmbCube_Bake( 6 | PtScene* scene, 7 | AmbCube_t* pCube, 8 | float4 origin, 9 | i32 samples, 10 | i32 prevSampleCount) 11 | { 12 | ASSERT(scene); 13 | ASSERT(pCube); 14 | ASSERT(samples >= 0); 15 | ASSERT(prevSampleCount >= 0); 16 | 17 | PtResults results = Pt_RayGen(scene, origin, samples); 18 | 19 | const float4* pim_noalias colors = results.colors; 20 | const float4* pim_noalias directions = results.directions; 21 | 22 | AmbCube_t cube = *pCube; 23 | float w = 6.0f / (1.0f + samples); 24 | w = w / (1.0f + prevSampleCount); 25 | for (i32 i = 0; i < samples; ++i) 26 | { 27 | cube = AmbCube_Fit(cube, w, directions[i], colors[i]); 28 | } 29 | *pCube = cube; 30 | 31 | return prevSampleCount + 1; 32 | } 33 | -------------------------------------------------------------------------------- /src/math/ambcube.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "math/types.h" 4 | #include "math/float4_funcs.h" 5 | 6 | PIM_C_BEGIN 7 | 8 | typedef struct PtScene_s PtScene; 9 | 10 | pim_inline float4 VEC_CALL AmbCube_Eval(AmbCube_t c, float4 dir) 11 | { 12 | bool4 face = f4_gtvs(dir, 0.0f); 13 | dir = f4_mul(dir, dir); 14 | float4 v = f4_0; 15 | 16 | if (face.x) 17 | v = f4_add(v, f4_mulvs(c.Values[0], dir.x)); 18 | else 19 | v = f4_add(v, f4_mulvs(c.Values[1], dir.x)); 20 | 21 | if (face.y) 22 | v = f4_add(v, f4_mulvs(c.Values[2], dir.y)); 23 | else 24 | v = f4_add(v, f4_mulvs(c.Values[3], dir.y)); 25 | 26 | if (face.z) 27 | v = f4_add(v, f4_mulvs(c.Values[4], dir.z)); 28 | else 29 | v = f4_add(v, f4_mulvs(c.Values[5], dir.z)); 30 | 31 | return v; 32 | } 33 | 34 | pim_inline float4 VEC_CALL AmbCube_Irradiance(AmbCube_t c, float4 dir) 35 | { 36 | return f4_mulvs(AmbCube_Eval(c, dir), kTau); 37 | } 38 | 39 | pim_inline AmbCube_t VEC_CALL AmbCube_Fit(AmbCube_t c, float weight, float4 dir, float4 rad) 40 | { 41 | bool4 face = f4_gtvs(dir, 0.0f); 42 | dir = f4_mul(dir, dir); 43 | dir = f4_mulvs(dir, weight); 44 | 45 | if (face.x) 46 | c.Values[0] = f4_lerpvs(c.Values[0], rad, dir.x); 47 | else 48 | c.Values[1] = f4_lerpvs(c.Values[1], rad, dir.x); 49 | 50 | if (face.y) 51 | c.Values[2] = f4_lerpvs(c.Values[2], rad, dir.y); 52 | else 53 | c.Values[3] = f4_lerpvs(c.Values[3], rad, dir.y); 54 | 55 | if (face.z) 56 | c.Values[4] = f4_lerpvs(c.Values[4], rad, dir.z); 57 | else 58 | c.Values[5] = f4_lerpvs(c.Values[5], rad, dir.z); 59 | 60 | return c; 61 | } 62 | 63 | i32 AmbCube_Bake( 64 | PtScene* scene, 65 | AmbCube_t* pCube, 66 | float4 origin, 67 | i32 samples, 68 | i32 prevSampleCount); 69 | 70 | PIM_C_END 71 | -------------------------------------------------------------------------------- /src/math/area.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "math/float4_funcs.h" 4 | #include "math/float2_funcs.h" 5 | 6 | PIM_C_BEGIN 7 | 8 | pim_inline float VEC_CALL SphereArea(float radius) 9 | { 10 | return 4.0f * kPi * (radius * radius); 11 | } 12 | 13 | pim_inline float VEC_CALL DiskArea(float radius) 14 | { 15 | return kPi * (radius * radius); 16 | } 17 | 18 | pim_inline float VEC_CALL TubeArea(float radius, float width) 19 | { 20 | return (2.0f * kPi * radius * width) + (4.0f * kPi * radius * radius); 21 | } 22 | 23 | pim_inline float VEC_CALL RectArea(float width, float height) 24 | { 25 | return width * height; 26 | } 27 | 28 | pim_inline float VEC_CALL TriArea3D(float4 A, float4 B, float4 C) 29 | { 30 | return 0.5f * f4_length3(f4_cross3(f4_sub(B, A), f4_sub(C, A))); 31 | } 32 | 33 | pim_inline float VEC_CALL TriArea2D(Tri2D tri) 34 | { 35 | float2 ab = f2_sub(tri.b, tri.a); 36 | float2 ac = f2_sub(tri.c, tri.a); 37 | float cr = ab.x * ac.y - ac.x * ab.y; 38 | return 0.5f * f1_abs(cr); 39 | } 40 | 41 | PIM_C_END 42 | -------------------------------------------------------------------------------- /src/math/atmosphere.c: -------------------------------------------------------------------------------- 1 | #include "math/atmosphere.h" 2 | 3 | const SkyMedium kEarthAtmosphere = 4 | { 5 | .rCrust = 6360e3f, // 6360km 6 | .rAtmos = 60.0f, // 6420km 7 | 8 | .muR = 9 | { 10 | 1.0f / 192428.0f, // 192km mfp red, rayleigh 11 | 1.0f / 82354.0f, // 82km mfp green, rayleigh 12 | 1.0f / 33732.0f, // 34km mfp blue, rayleigh 13 | }, 14 | .rhoR = 1.0f / 8500.0f, // 8.5km mean radius, rayleigh 15 | 16 | .muM = 1.0f / 47619.0f, // 48km mfp, mie 17 | .rhoM = 1.0f / 1200.0f, // 1.2km mean radius, mie 18 | .gM = 0.758f, 19 | }; 20 | -------------------------------------------------------------------------------- /src/math/atomic_float.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "math/types.h" 4 | #include "math/scalar.h" 5 | #include "common/atomics.h" 6 | #include 7 | 8 | PIM_C_BEGIN 9 | 10 | #ifndef ATOMIC_FLOAT_MAX 11 | # define ATOMIC_FLOAT_MAX (1e30f) 12 | #endif // ATOMIC_FLOAT_MAX 13 | 14 | pim_inline u32 VEC_CALL f1_tobits(float x) 15 | { 16 | u32 y; 17 | memcpy(&y, &x, 4); 18 | return y; 19 | } 20 | pim_inline float VEC_CALL f1_frombits(u32 x) 21 | { 22 | float y; 23 | memcpy(&y, &x, 4); 24 | return y; 25 | } 26 | 27 | pim_inline void VEC_CALL f1_add_atomic(volatile float* pA, float b) 28 | { 29 | // this is just a CAS loop emulating an atomic float. 30 | // it is horribly slow, don't stick it in the inner-loop of a program. 31 | // thread-local work will almost always outperform atomics. 32 | volatile u32* dst = (volatile u32*)pA; 33 | u32 prev = load_u32(dst, MO_Relaxed); 34 | while (true) 35 | { 36 | float v = f1_frombits(prev) + b; 37 | // to avoid +-inf 38 | v = f1_min(v, ATOMIC_FLOAT_MAX); 39 | v = f1_max(v, -ATOMIC_FLOAT_MAX); 40 | u32 next = f1_tobits(v); 41 | if (cmpex_u32(dst, &prev, next, MO_Relaxed)) 42 | { 43 | break; 44 | } 45 | } 46 | } 47 | pim_inline void VEC_CALL f2_add_atomic(volatile float2* pA, float2 b) 48 | { 49 | f1_add_atomic(&pA->x, b.x); 50 | f1_add_atomic(&pA->y, b.y); 51 | } 52 | pim_inline void VEC_CALL f3_add_atomic(volatile float3* pA, float3 b) 53 | { 54 | f1_add_atomic(&pA->x, b.x); 55 | f1_add_atomic(&pA->y, b.y); 56 | f1_add_atomic(&pA->z, b.z); 57 | } 58 | pim_inline void VEC_CALL f4_add_atomic(volatile float4* pA, float4 b) 59 | { 60 | f1_add_atomic(&pA->x, b.x); 61 | f1_add_atomic(&pA->y, b.y); 62 | f1_add_atomic(&pA->z, b.z); 63 | f1_add_atomic(&pA->w, b.w); 64 | } 65 | 66 | pim_inline void VEC_CALL f1_lerp_atomic(volatile float* pA, float b, float t) 67 | { 68 | volatile u32* dst = (volatile u32*)pA; 69 | u32 prev = load_u32(dst, MO_Relaxed); 70 | u32 next; 71 | do 72 | { 73 | next = f1_tobits(f1_lerp(f1_frombits(prev), b, t)); 74 | } while (!cmpex_u32(dst, &prev, next, MO_Relaxed)); 75 | } 76 | pim_inline void VEC_CALL f2_lerpvs_atomic(volatile float2* pA, float2 b, float t) 77 | { 78 | f1_lerp_atomic(&pA->x, b.x, t); 79 | f1_lerp_atomic(&pA->y, b.y, t); 80 | } 81 | pim_inline void VEC_CALL f3_lerpvs_atomic(volatile float3* pA, float3 b, float t) 82 | { 83 | f1_lerp_atomic(&pA->x, b.x, t); 84 | f1_lerp_atomic(&pA->y, b.y, t); 85 | f1_lerp_atomic(&pA->z, b.z, t); 86 | } 87 | pim_inline void VEC_CALL f4_lerpvs_atomic(volatile float4* pA, float4 b, float t) 88 | { 89 | f1_lerp_atomic(&pA->x, b.x, t); 90 | f1_lerp_atomic(&pA->y, b.y, t); 91 | f1_lerp_atomic(&pA->z, b.z, t); 92 | f1_lerp_atomic(&pA->w, b.w, t); 93 | } 94 | 95 | PIM_C_END 96 | -------------------------------------------------------------------------------- /src/math/bool_funcs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "math/types.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | pim_inline bool VEC_CALL b2_any(bool2 b) 8 | { 9 | return (b.x | b.y) != 0; 10 | } 11 | 12 | pim_inline bool VEC_CALL b2_all(bool2 b) 13 | { 14 | return (b.x && b.y); 15 | } 16 | 17 | pim_inline bool2 VEC_CALL b2_not(bool2 b) 18 | { 19 | bool2 vec = { !b.x, !b.y }; 20 | return vec; 21 | } 22 | 23 | pim_inline bool VEC_CALL b3_any(bool3 b) 24 | { 25 | return (b.x | b.y | b.z) != 0; 26 | } 27 | 28 | pim_inline bool VEC_CALL b3_all(bool3 b) 29 | { 30 | return (b.x && b.y && b.z); 31 | } 32 | 33 | pim_inline bool3 VEC_CALL b3_not(bool3 b) 34 | { 35 | bool3 vec = { !b.x, !b.y, !b.z }; 36 | return vec; 37 | } 38 | 39 | pim_inline bool VEC_CALL b4_any4(bool4 b) 40 | { 41 | return (b.x | b.y | b.z | b.w) != 0; 42 | } 43 | pim_inline bool VEC_CALL b4_any3(bool4 b) 44 | { 45 | return (b.x | b.y | b.z | b.w) != 0; 46 | } 47 | 48 | pim_inline bool VEC_CALL b4_all4(bool4 b) 49 | { 50 | return (b.x && b.y && b.z && b.w); 51 | } 52 | pim_inline bool VEC_CALL b4_all3(bool4 b) 53 | { 54 | return (b.x && b.y && b.z); 55 | } 56 | 57 | pim_inline bool4 VEC_CALL b4_not(bool4 b) 58 | { 59 | bool4 vec = { !b.x, !b.y, !b.z, !b.w }; 60 | return vec; 61 | } 62 | 63 | PIM_C_END 64 | -------------------------------------------------------------------------------- /src/math/box.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "math/types.h" 4 | #include "math/float4_funcs.h" 5 | #include "math/float4x4_funcs.h" 6 | #include "math/bool_funcs.h" 7 | 8 | PIM_C_BEGIN 9 | 10 | pim_inline Box3D VEC_CALL box_new(float4 lo, float4 hi) 11 | { 12 | Box3D box = { lo, hi }; 13 | return box; 14 | } 15 | 16 | pim_inline Box3D VEC_CALL box_empty(void) 17 | { 18 | return box_new(f4_s(1 << 23), f4_s(-(1 << 23))); 19 | } 20 | 21 | pim_inline float4 VEC_CALL box_center(Box3D box) 22 | { 23 | return f4_lerpvs(box.lo, box.hi, 0.5f); 24 | } 25 | 26 | pim_inline float4 VEC_CALL box_size(Box3D box) 27 | { 28 | return f4_sub(box.hi, box.lo); 29 | } 30 | 31 | pim_inline float4 VEC_CALL box_extents(Box3D box) 32 | { 33 | return f4_mulvs(box_size(box), 0.5f); 34 | } 35 | 36 | pim_inline bool VEC_CALL box_contains(Box3D box, float4 pt) 37 | { 38 | return b4_all3(f4_gteq(pt, box.lo)) && b4_all3(f4_lteq(pt, box.hi)); 39 | } 40 | 41 | pim_inline float VEC_CALL box_volume(Box3D box) 42 | { 43 | float4 size = box_size(box); 44 | return size.x * size.y * size.z; 45 | } 46 | 47 | pim_inline float VEC_CALL box_area(Box3D box) 48 | { 49 | float4 size = box_size(box); 50 | return (size.x * size.y + size.x * size.z + size.y * size.z) * 2.0f; 51 | } 52 | 53 | pim_inline Box3D VEC_CALL box_from_pts(const float4* pim_noalias pts, i32 length) 54 | { 55 | if (length == 0) 56 | { 57 | return box_new(f4_0, f4_0); 58 | } 59 | float4 lo = f4_s(1 << 23); 60 | float4 hi = f4_s(-(1 << 23)); 61 | for (i32 i = 0; i < length; ++i) 62 | { 63 | float4 pt = pts[i]; 64 | lo = f4_min(lo, pt); 65 | hi = f4_max(hi, pt); 66 | } 67 | return box_new(lo, hi); 68 | } 69 | 70 | pim_inline Box3D VEC_CALL box_union(Box3D lhs, Box3D rhs) 71 | { 72 | return box_new(f4_min(lhs.lo, rhs.lo), f4_max(lhs.hi, rhs.hi)); 73 | } 74 | 75 | pim_inline Box3D VEC_CALL box_intersect(Box3D lhs, Box3D rhs) 76 | { 77 | float4 lo = f4_min(lhs.lo, rhs.lo); 78 | float4 hi = f4_max(lhs.hi, rhs.hi); 79 | float4 mid = f4_lerpvs(lo, hi, 0.5f); 80 | bool4 inverted = f4_gt(lo, hi); 81 | lo = f4_select(lo, mid, inverted); 82 | hi = f4_select(hi, mid, inverted); 83 | return box_new(lo, hi); 84 | } 85 | 86 | pim_inline Box3D VEC_CALL box_transform(float4x4 matrix, Box3D box) 87 | { 88 | float4 center = box_center(box); 89 | float4 extents = f4_sub(box.hi, center); 90 | center = f4x4_mul_pt(matrix, center); 91 | extents = f4x4_mul_extents(matrix, extents); 92 | float4 lo = f4_sub(center, extents); 93 | float4 hi = f4_add(center, extents); 94 | return box_new(lo, hi); 95 | } 96 | 97 | PIM_C_END 98 | -------------------------------------------------------------------------------- /src/math/cubic_fit.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "math/types.h" 4 | #include "math/scalar.h" 5 | 6 | PIM_C_BEGIN 7 | 8 | // Attempts to fit a cubic polynomial to the given set of samples 9 | float CubicFit(dataset_t data, fit_t* fit, i32 iterations); 10 | float SqrticFit(dataset_t data, fit_t* fit, i32 iterations); 11 | float TMapFit(dataset_t data, fit_t* fit, i32 iterations); 12 | float PolyFit(dataset_t data, fit_t* fit, i32 iterations); 13 | 14 | pim_inline float VEC_CALL CubicEval(float x, fit_t fit) 15 | { 16 | return fit.value[0] * x + fit.value[1] * x * x + fit.value[2] * x * x * x; 17 | } 18 | 19 | pim_inline float VEC_CALL SqrticEval(float x, fit_t fit) 20 | { 21 | float s1 = sqrtf(x); 22 | float s2 = sqrtf(s1); 23 | float s3 = sqrtf(s2); 24 | return fit.value[0] * s1 + fit.value[1] * s2 + fit.value[2] * s3; 25 | } 26 | 27 | pim_inline float VEC_CALL TMapEval(float x, fit_t fit) 28 | { 29 | float a = fit.value[0]; 30 | float b = fit.value[1]; 31 | float c = fit.value[2]; 32 | float d = fit.value[3]; 33 | float e = fit.value[4]; 34 | return (x * (a * x + b)) / (x * (c * x + d) + e); 35 | } 36 | 37 | pim_inline float VEC_CALL PolyEval(float x, fit_t fit) 38 | { 39 | float x2 = x * x; 40 | float x3 = x * x * x; 41 | float nom = fit.value[1] * x + fit.value[2] * x2 + fit.value[3] * x3; 42 | float denom = fit.value[4] + fit.value[5] * x + fit.value[6] * x2 + fit.value[7] * x3; 43 | return nom / denom; 44 | } 45 | 46 | PIM_C_END 47 | -------------------------------------------------------------------------------- /src/math/dist1d.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "math/types.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | void Dist1D_New(Dist1D *const dist, i32 length); 8 | void Dist1D_Del(Dist1D *const dist); 9 | 10 | void Dist1D_Bake(Dist1D *const dist); 11 | 12 | // continuous 13 | float Dist1D_SampleC(Dist1D const *const dist, float u); 14 | 15 | // discrete 16 | i32 Dist1D_SampleD(Dist1D const *const dist, float u); 17 | float Dist1D_PdfD(Dist1D const *const dist, i32 i); 18 | 19 | void Dist1D_Inc(Dist1D *const dist, i32 i); 20 | void Dist1D_Update(Dist1D *const dist); 21 | 22 | PIM_C_END 23 | -------------------------------------------------------------------------------- /src/math/float4x4_funcs.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vethanis/pim/15a50bdbf9eb3e78d29cfdb412e21a3dc0fd223a/src/math/float4x4_funcs.h -------------------------------------------------------------------------------- /src/math/grid.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "math/types.h" 4 | #include "math/float4_funcs.h" 5 | 6 | PIM_C_BEGIN 7 | 8 | pim_inline void VEC_CALL Grid_New(Grid *const grid, Box3D bounds, float cellsPerMeter) 9 | { 10 | float4 range = f4_sub(bounds.hi, bounds.lo); 11 | float4 sizef = f4_ceil(f4_mulvs(range, cellsPerMeter)); 12 | int3 size = { (i32)sizef.x, (i32)sizef.y, (i32)sizef.z }; 13 | grid->bounds = bounds; 14 | grid->size = size; 15 | grid->cellsPerMeter = cellsPerMeter; 16 | } 17 | 18 | pim_inline i32 VEC_CALL Grid_Len(Grid const *const grid) 19 | { 20 | int3 size = grid->size; 21 | return size.x * size.y * size.z; 22 | } 23 | 24 | pim_inline float4 VEC_CALL Grid_Position(Grid const *const grid, i32 index) 25 | { 26 | const int3 size = grid->size; 27 | const float metersPerCell = 1.0f / grid->cellsPerMeter; 28 | i32 ix = index % size.x; 29 | i32 iy = (index / size.x) % size.y; 30 | i32 iz = index / (size.x * size.y); 31 | float4 offset = 32 | { 33 | (ix + 0.5f) * metersPerCell, 34 | (iy + 0.5f) * metersPerCell, 35 | (iz + 0.5f) * metersPerCell, 36 | 0.0f, 37 | }; 38 | return f4_add(grid->bounds.lo, offset); 39 | } 40 | 41 | pim_inline i32 VEC_CALL Grid_Index(Grid const *const grid, float4 position) 42 | { 43 | float4 offset = f4_mulvs(f4_sub(position, grid->bounds.lo), grid->cellsPerMeter); 44 | const int3 size = grid->size; 45 | i32 x = i1_clamp((i32)offset.x, 0, size.x - 1); 46 | i32 y = i1_clamp((i32)offset.y, 0, size.y - 1); 47 | i32 z = i1_clamp((i32)offset.z, 0, size.z - 1); 48 | return x + y * size.x + z * size.x * size.y; 49 | } 50 | 51 | PIM_C_END 52 | -------------------------------------------------------------------------------- /src/math/markov_sampler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "math/types.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | void MarkovSampler_New( 8 | MarkovSampler* s, 9 | u32 sampleCount); 10 | void MarkovSampler_Del(MarkovSampler* s); 11 | 12 | void MarkovSampler_Reset(MarkovSampler* s); 13 | 14 | void MarkovSampler_StartIteration(MarkovSampler* s, float probLargeStep); 15 | 16 | void MarkovSampler_Accept(MarkovSampler* s); 17 | void MarkovSampler_Reject(MarkovSampler* s); 18 | 19 | float VEC_CALL MarkovSampler_Sample1D(MarkovSampler* s, float sigma); 20 | float2 VEC_CALL MarkovSampler_Sample2D(MarkovSampler* s, float sigma); 21 | 22 | float VEC_CALL Markov_AcceptProb(float proposedLum, float currentLum); 23 | float VEC_CALL Markov_ProposedWeight(float acceptProb, float proposedLum); 24 | float VEC_CALL Markov_CurrentWeight(float acceptProb, float currentLum); 25 | 26 | PIM_C_END 27 | -------------------------------------------------------------------------------- /src/math/pcg.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vethanis/pim/15a50bdbf9eb3e78d29cfdb412e21a3dc0fd223a/src/math/pcg.h -------------------------------------------------------------------------------- /src/os/socket.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | typedef enum 8 | { 9 | SocketProto_UDP = 0, 10 | SocketProto_TCP, 11 | SocketProto_COUNT 12 | } SocketProto; 13 | 14 | typedef struct Socket_s 15 | { 16 | void* handle; 17 | SocketProto proto; 18 | } Socket; 19 | 20 | void NetSys_Init(void); 21 | void NetSys_Update(void); 22 | void NetSys_Shutdown(void); 23 | 24 | bool Net_UrlToAddr(const char* url, u32* addrOut); 25 | 26 | bool Socket_Open(Socket* sock, SocketProto proto); 27 | void Socket_Close(Socket* sock); 28 | 29 | bool Socket_IsOpen(Socket sock); 30 | bool Socket_Bind(Socket sock, u32 addr, u16 port); 31 | bool Socket_Listen(Socket sock); 32 | Socket Socket_Accept(Socket sock, u32* addr); 33 | bool Socket_Connect(Socket sock, u32 addr, u16 port); 34 | 35 | i32 Socket_Send(Socket sock, const void* src, i32 len); 36 | i32 Socket_Recv(Socket sock, void* dst, i32 len); 37 | 38 | PIM_C_END 39 | -------------------------------------------------------------------------------- /src/rendering/camera.c: -------------------------------------------------------------------------------- 1 | #include "rendering/camera.h" 2 | #include "math/float4x4_funcs.h" 3 | #include "math/frustum.h" 4 | 5 | static Camera ms_camera = 6 | { 7 | .position = { 0.0f, 0.0f, 5.0f, 1.0f }, 8 | .rotation = { 0.0f, 0.0f, 0.0f, 1.0f }, 9 | .zNear = 0.1f, 10 | .zFar = 500.0f, 11 | .fovy = 90.0f, 12 | }; 13 | 14 | void Camera_Get(Camera* dst) 15 | { 16 | ASSERT(dst); 17 | *dst = ms_camera; 18 | } 19 | 20 | void Camera_Set(const Camera* src) 21 | { 22 | ASSERT(src); 23 | ms_camera = *src; 24 | } 25 | 26 | void Camera_Reset(void) 27 | { 28 | ms_camera.position = f4_0; 29 | ms_camera.rotation = quat_id; 30 | } 31 | 32 | void Camera_Frustum(const Camera* src, Frustum* dst, float aspect) 33 | { 34 | Camera_SubFrustum( 35 | src, dst, 36 | f2_s(-1.0f), f2_s(1.0f), 37 | src->zNear, src->zFar, 38 | aspect); 39 | } 40 | 41 | void Camera_SubFrustum( 42 | const Camera* src, 43 | Frustum* dst, 44 | float2 lo, float2 hi, 45 | float zNear, float zFar, 46 | float aspect) 47 | { 48 | ASSERT(src); 49 | ASSERT(dst); 50 | quat rot = src->rotation; 51 | *dst = frus_new( 52 | src->position, 53 | quat_right(rot), 54 | quat_up(rot), 55 | quat_fwd(rot), 56 | lo, 57 | hi, 58 | proj_slope(f1_radians(src->fovy), aspect), 59 | zNear, 60 | zFar); 61 | } 62 | 63 | float4x4 VEC_CALL Camera_GetView(const Camera* src) 64 | { 65 | float4 pos = src->position; 66 | quat rot = src->rotation; 67 | return f4x4_lookat( 68 | pos, 69 | f4_add(pos, quat_fwd(rot)), 70 | quat_up(rot)); 71 | } 72 | 73 | float4x4 VEC_CALL Camera_GetProj(const Camera* src, float aspect) 74 | { 75 | return f4x4_vkperspective( 76 | f1_radians(src->fovy), 77 | aspect, 78 | src->zNear, src->zFar); 79 | } 80 | 81 | float4x4 VEC_CALL Camera_GetWorldToClip(const Camera* src, float aspect) 82 | { 83 | return f4x4_mul( 84 | Camera_GetProj(src, aspect), 85 | Camera_GetView(src)); 86 | } 87 | -------------------------------------------------------------------------------- /src/rendering/camera.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | #include "math/types.h" 5 | 6 | PIM_C_BEGIN 7 | 8 | typedef struct Camera_s 9 | { 10 | float4 position; 11 | quat rotation; 12 | float zNear; 13 | float zFar; 14 | float fovy; 15 | } Camera; 16 | 17 | void Camera_Get(Camera* dst); 18 | void Camera_Set(const Camera* src); 19 | void Camera_Reset(void); 20 | void Camera_Frustum(const Camera* src, Frustum* dst, float aspect); 21 | // lo, hi: [-1, 1] range screen bounds 22 | void Camera_SubFrustum(const Camera* src, Frustum* dst, float2 lo, float2 hi, float zNear, float zFar, float aspect); 23 | float4x4 VEC_CALL Camera_GetView(const Camera* src); 24 | float4x4 VEC_CALL Camera_GetProj(const Camera* src, float aspect); 25 | float4x4 VEC_CALL Camera_GetWorldToClip(const Camera* src, float aspect); 26 | 27 | PIM_C_END 28 | -------------------------------------------------------------------------------- /src/rendering/denoise.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | #include "math/types.h" 5 | 6 | PIM_C_BEGIN 7 | 8 | typedef enum 9 | { 10 | DenoiseType_Image, 11 | DenoiseType_Lightmap, 12 | 13 | DenoiseType_COUNT 14 | } DenoiseType; 15 | 16 | bool Denoise( 17 | DenoiseType type, 18 | int2 size, 19 | const float3* color, 20 | const float3* albedo, 21 | const float3* normal, 22 | float3* output); 23 | 24 | void Denoise_Evict(void); 25 | 26 | PIM_C_END 27 | -------------------------------------------------------------------------------- /src/rendering/drawable.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | #include "common/dbytes.h" 5 | #include "common/guid.h" 6 | #include "math/types.h" 7 | 8 | PIM_C_BEGIN 9 | 10 | typedef struct MeshId_s MeshId; 11 | typedef struct Material_s Material; 12 | typedef struct Crate_s Crate; 13 | 14 | typedef struct Entities_s 15 | { 16 | i32 count; 17 | Guid* pim_noalias names; // hash identifier 18 | MeshId* pim_noalias meshes; // immutable object space mesh 19 | Box3D* pim_noalias bounds; // object space bounds 20 | Material* pim_noalias materials; // material description 21 | float4x4* pim_noalias matrices; // local to world matrix 22 | float3x3* pim_noalias invMatrices; // world to local rotation matrix 23 | float4* pim_noalias translations; 24 | quat* pim_noalias rotations; 25 | float4* pim_noalias scales; 26 | u64 modtime; 27 | } Entities; 28 | 29 | #define kDiskEntitiesVersion 3 30 | typedef struct DiskEntities_s 31 | { 32 | i32 version; 33 | i32 length; 34 | DiskBytes names; 35 | DiskBytes meshes; // dmeshid_t 36 | DiskBytes bounds; 37 | DiskBytes materials; // dmaterial_t 38 | DiskBytes translations; 39 | DiskBytes rotations; 40 | DiskBytes scales; 41 | } DiskEntities; 42 | 43 | void EntSys_Init(void); 44 | void EntSys_Update(void); 45 | void EntSys_Shutdown(void); 46 | void EntSys_Gui(bool* enabled); 47 | 48 | Entities *const Entities_Get(void); 49 | 50 | i32 Entities_Add(Entities *const dr, Guid name); 51 | bool Entities_Rm(Entities *const dr, Guid name); 52 | i32 Entities_Find(Entities const *const dr, Guid name); 53 | void Entities_Clear(Entities *const dr); 54 | void Entities_Del(Entities *const dr); 55 | 56 | void Entities_UpdateBounds(Entities *const dr); 57 | void Entities_UpdateTransforms(Entities *const dr); 58 | Box3D Entities_GetBounds(Entities const *const dr); 59 | 60 | bool Entities_Save(Crate *const crate, Entities const *const src); 61 | bool Entities_Load(Crate *const crate, Entities *const dst); 62 | 63 | PIM_C_END 64 | -------------------------------------------------------------------------------- /src/rendering/exposure.c: -------------------------------------------------------------------------------- 1 | #include "rendering/exposure.h" 2 | #include "rendering/sampler.h" 3 | #include "math/color.h" 4 | #include "threading/task.h" 5 | #include "allocator/allocator.h" 6 | #include "common/profiler.h" 7 | #include "common/time.h" 8 | #include "common/cvars.h" 9 | 10 | typedef struct task_ToLum 11 | { 12 | Task task; 13 | int2 size; 14 | const float4* pim_noalias light; 15 | float* pim_noalias averages; 16 | } task_ToLum; 17 | 18 | static void CalcAverageFn(void* pbase, i32 begin, i32 end) 19 | { 20 | task_ToLum* task = pbase; 21 | const int2 size = task->size; 22 | const float4* pim_noalias light = task->light; 23 | float* pim_noalias averages = task->averages; 24 | 25 | const float weight = 1.0f / size.x; 26 | for (i32 y = begin; y < end; ++y) 27 | { 28 | const i32 i0 = size.x * y; 29 | const i32 i1 = size.x * (y + 1); 30 | float average = 0.0f; 31 | for (i32 i = i0; i < i1; ++i) 32 | { 33 | float lum = f4_avglum(light[i]); 34 | average += lum * weight; 35 | } 36 | averages[y] = average; 37 | } 38 | } 39 | 40 | ProfileMark(pm_average, CalcAverage) 41 | static float CalcAverage(const float4* light, int2 size) 42 | { 43 | ProfileBegin(pm_average); 44 | 45 | const i32 worksize = size.y; 46 | task_ToLum* task = Temp_Calloc(sizeof(*task)); 47 | task->size = size; 48 | task->light = light; 49 | task->averages = Temp_Alloc(sizeof(task->averages[0]) * worksize); 50 | Task_Run(&task->task, CalcAverageFn, worksize); 51 | 52 | const float* pim_noalias averages = task->averages; 53 | const float weight = 1.0f / worksize; 54 | float avgLum = 0.0f; 55 | for (i32 i = 0; i < worksize; ++i) 56 | { 57 | avgLum += averages[i] * weight; 58 | } 59 | 60 | ProfileEnd(pm_average); 61 | return avgLum; 62 | } 63 | 64 | ProfileMark(pm_exposeimg, ExposeImage) 65 | void ExposeImage( 66 | int2 size, 67 | float4* pim_noalias light, 68 | vkrExposure* parameters) 69 | { 70 | ProfileBegin(pm_exposeimg); 71 | 72 | parameters->deltaTime = f1_lerp(parameters->deltaTime, (float)Time_Deltaf(), 0.5f); 73 | 74 | parameters->avgLum = AdaptLuminance( 75 | parameters->avgLum, 76 | CalcAverage(light, size), 77 | parameters->deltaTime, 78 | parameters->adaptRate); 79 | parameters->exposure = CalcExposure(parameters); 80 | 81 | ProfileEnd(pm_exposeimg); 82 | } 83 | -------------------------------------------------------------------------------- /src/rendering/framebuffer.c: -------------------------------------------------------------------------------- 1 | #include "rendering/framebuffer.h" 2 | #include "allocator/allocator.h" 3 | #include 4 | 5 | void FrameBuf_New(FrameBuf* buf, i32 width, i32 height) 6 | { 7 | ASSERT(buf); 8 | ASSERT(width > 0); 9 | ASSERT(height > 0); 10 | memset(buf, 0, sizeof(*buf)); 11 | buf->width = width; 12 | buf->height = height; 13 | const i32 len = width * height; 14 | ASSERT(len > 0); 15 | buf->light = Tex_Alloc(len * sizeof(buf->light[0])); 16 | } 17 | 18 | void FrameBuf_Del(FrameBuf* buf) 19 | { 20 | if (buf) 21 | { 22 | Mem_Free(buf->light); 23 | memset(buf, 0, sizeof(*buf)); 24 | } 25 | } 26 | 27 | void FrameBuf_Reserve(FrameBuf* buf, i32 width, i32 height) 28 | { 29 | const i32 len = width * height; 30 | if (len > 0) 31 | { 32 | buf->light = Tex_Realloc(buf->light, sizeof(buf->light[0]) * len); 33 | buf->width = width; 34 | buf->height = height; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/rendering/framebuffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | #include "math/types.h" 5 | 6 | PIM_C_BEGIN 7 | 8 | typedef struct FrameBuf_s 9 | { 10 | i32 width; 11 | i32 height; 12 | float4* pim_noalias light; // scene luminance, linear AP1 13 | } FrameBuf; 14 | 15 | void FrameBuf_New(FrameBuf* buf, i32 width, i32 height); 16 | void FrameBuf_Del(FrameBuf* buf); 17 | void FrameBuf_Reserve(FrameBuf* buf, i32 width, i32 height); 18 | 19 | PIM_C_END 20 | -------------------------------------------------------------------------------- /src/rendering/gltf_model.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | typedef struct Entities_s Entities; 8 | 9 | bool Gltf_Load(const char* path, Entities* dst); 10 | 11 | PIM_C_END 12 | -------------------------------------------------------------------------------- /src/rendering/lightmap.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | #include "common/dbytes.h" 5 | #include "math/types.h" 6 | #include "common/guid.h" 7 | #include "rendering/vulkan/vkr.h" 8 | 9 | PIM_C_BEGIN 10 | 11 | #define kLmPackVersion 2 12 | #define kGiDirections 5 13 | 14 | static const float4 kGiAxii[kGiDirections] = 15 | { 16 | { 0.000000f, 0.000000f, 1.000000f, 4.999773f }, 17 | { 0.577350f, 0.577350f, 0.577350f, 4.999773f }, 18 | { -0.577350f, 0.577350f, 0.577350f, 4.999773f }, 19 | { 0.577350f, -0.577350f, 0.577350f, 4.999773f }, 20 | { -0.577350f, -0.577350f, 0.577350f, 4.999773f }, 21 | }; 22 | 23 | typedef struct Task_s Task; 24 | typedef struct PtScene_s PtScene; 25 | typedef struct Crate_s Crate; 26 | 27 | typedef struct Lightmap_s 28 | { 29 | float4* pim_noalias probes[kGiDirections]; 30 | float3* pim_noalias position; 31 | float3* pim_noalias normal; 32 | float* pim_noalias sampleCounts; 33 | i32 size; 34 | vkrTextureId slot; 35 | } Lightmap; 36 | 37 | typedef struct LmPack_s 38 | { 39 | float4 axii[kGiDirections]; 40 | Lightmap* pim_noalias lightmaps; 41 | i32 lmCount; 42 | i32 lmSize; 43 | float texelsPerMeter; 44 | } LmPack; 45 | 46 | typedef struct DiskLmPack_s 47 | { 48 | i32 version; 49 | i32 directions; 50 | i32 lmCount; 51 | i32 lmSize; 52 | i32 bytesPerLightmap; 53 | float texelsPerMeter; 54 | } DiskLmPack; 55 | 56 | void Lightmap_New(Lightmap* lm, i32 size); 57 | void Lightmap_Del(Lightmap* lm); 58 | // upload changes to the GPU copy 59 | void Lightmap_Upload(Lightmap* lm); 60 | 61 | LmPack* LmPack_Get(void); 62 | LmPack LmPack_Pack( 63 | i32 atlasSize, 64 | float texelsPerUnit, 65 | float distThresh, 66 | float degThresh); 67 | void LmPack_Del(LmPack* pack); 68 | 69 | void LmPack_Bake(PtScene* scene, float timeSlice, i32 spp); 70 | 71 | bool LmPack_Save(Crate* crate, const LmPack* src); 72 | bool LmPack_Load(Crate* crate, LmPack* dst); 73 | 74 | PIM_C_END 75 | -------------------------------------------------------------------------------- /src/rendering/lights.c: -------------------------------------------------------------------------------- 1 | #include "rendering/lights.h" 2 | #include "allocator/allocator.h" 3 | 4 | static Lights ms_lights; 5 | 6 | Lights* Lights_Get(void) 7 | { 8 | return &ms_lights; 9 | } 10 | 11 | void Lights_Clear(void) 12 | { 13 | ms_lights.ptCount = 0; 14 | ms_lights.dirCount = 0; 15 | } 16 | 17 | i32 Lights_AddPt(PtLight pt) 18 | { 19 | i32 len = ++ms_lights.ptCount; 20 | ms_lights.ptLights = Perm_Realloc(ms_lights.ptLights, sizeof(pt) * len); 21 | ms_lights.ptLights[len - 1] = pt; 22 | return len - 1; 23 | } 24 | 25 | i32 Lights_AddDir(DirLight dir) 26 | { 27 | i32 len = ++ms_lights.dirCount; 28 | ms_lights.dirLights = Perm_Realloc(ms_lights.ptLights, sizeof(dir) * len); 29 | ms_lights.dirLights[len - 1] = dir; 30 | return len - 1; 31 | } 32 | 33 | void Lights_RmPt(i32 i) 34 | { 35 | i32 len = ms_lights.ptCount; 36 | PtLight* pts = ms_lights.ptLights; 37 | if (i >= 0 && i < len) 38 | { 39 | for (i32 j = i + 1; j < len; ++j) 40 | { 41 | pts[j - 1] = pts[j]; 42 | } 43 | ms_lights.ptCount = len - 1; 44 | } 45 | } 46 | 47 | void Lights_RmDir(i32 i) 48 | { 49 | i32 len = ms_lights.dirCount; 50 | DirLight* dirs = ms_lights.dirLights; 51 | if (i >= 0 && i < len) 52 | { 53 | for (i32 j = i + 1; j < len; ++j) 54 | { 55 | dirs[j - 1] = dirs[j]; 56 | } 57 | ms_lights.dirCount = len - 1; 58 | } 59 | } 60 | 61 | void Lights_SetPt(i32 i, PtLight pt) 62 | { 63 | ASSERT(i >= 0 && i < ms_lights.ptCount); 64 | ms_lights.ptLights[i] = pt; 65 | } 66 | 67 | void Lights_SetDir(i32 i, DirLight dir) 68 | { 69 | ASSERT(i >= 0 && i < ms_lights.dirCount); 70 | ms_lights.dirLights[i] = dir; 71 | } 72 | 73 | PtLight Lights_GetPt(i32 i) 74 | { 75 | ASSERT(i >= 0 && i < ms_lights.ptCount); 76 | return ms_lights.ptLights[i]; 77 | } 78 | 79 | DirLight Lights_GetDir(i32 i) 80 | { 81 | ASSERT(i >= 0 && i < ms_lights.dirCount); 82 | return ms_lights.dirLights[i]; 83 | } 84 | 85 | i32 Lights_PtCount(void) 86 | { 87 | return ms_lights.ptCount; 88 | } 89 | 90 | i32 Lights_DirCount(void) 91 | { 92 | return ms_lights.dirCount; 93 | } 94 | -------------------------------------------------------------------------------- /src/rendering/lights.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | #include "math/types.h" 8 | 9 | // TODO: Make these regular entities 10 | 11 | typedef struct DirLight_s 12 | { 13 | float4 dir; 14 | float4 rad; 15 | } DirLight; 16 | 17 | typedef struct PtLight_s 18 | { 19 | float4 pos; 20 | float4 rad; 21 | } PtLight; 22 | 23 | typedef struct Lights_s 24 | { 25 | DirLight* dirLights; 26 | PtLight* ptLights; 27 | i32 dirCount; 28 | i32 ptCount; 29 | } Lights; 30 | 31 | Lights* Lights_Get(void); 32 | 33 | void Lights_Clear(void); 34 | 35 | i32 Lights_AddPt(PtLight pt); 36 | i32 Lights_AddDir(DirLight dir); 37 | 38 | void Lights_RmPt(i32 i); 39 | void Lights_RmDir(i32 i); 40 | 41 | void Lights_SetPt(i32 i, PtLight pt); 42 | void Lights_SetDir(i32 i, DirLight dir); 43 | 44 | PtLight Lights_GetPt(i32 i); 45 | DirLight Lights_GetDir(i32 i); 46 | 47 | i32 Lights_PtCount(void); 48 | i32 Lights_DirCount(void); 49 | 50 | PIM_C_END 51 | -------------------------------------------------------------------------------- /src/rendering/material.c: -------------------------------------------------------------------------------- 1 | #include "rendering/material.h" 2 | -------------------------------------------------------------------------------- /src/rendering/material.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "math/types.h" 4 | #include "rendering/texture.h" 5 | 6 | PIM_C_BEGIN 7 | 8 | typedef enum 9 | { 10 | MatFlag_Emissive = 1 << 0, // enable emissive term 11 | MatFlag_Sky = 1 << 1, // lookup emission from sky cubemap 12 | MatFlag_Water = 1 << 2, 13 | MatFlag_Slime = 1 << 3, 14 | MatFlag_Lava = 1 << 4, 15 | MatFlag_Refractive = 1 << 5, // enable refraction term 16 | MatFlag_Warped = 1 << 6, // uv animated 17 | MatFlag_Animated = 1 << 7, // keyframe animated 18 | MatFlag_Underwater = 1 << 8, // SURF_UNDERWATER 19 | } MatFlagBits; 20 | typedef u32 MatFlag; 21 | 22 | typedef struct Material_s 23 | { 24 | TextureId albedo; // rgba8 srgb (albedo, alpha) 25 | TextureId rome; // rgba8 srgb (roughness, occlusion, metallic, emission) 26 | TextureId normal; // rg16 (tangent space xy) 27 | MatFlag flags; 28 | float4 meanFreePath; // .w = scatter dir 'g' 29 | float ior; // index of refraction 30 | float bumpiness; 31 | } Material; 32 | 33 | typedef struct DiskMaterial_s 34 | { 35 | DiskTextureId albedo; 36 | DiskTextureId rome; 37 | DiskTextureId normal; 38 | MatFlag flags; 39 | float ior; 40 | } DiskMaterial; 41 | 42 | PIM_C_END 43 | -------------------------------------------------------------------------------- /src/rendering/mesh.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | #include "math/types.h" 5 | #include "common/guid.h" 6 | #include "common/dbytes.h" 7 | #include "rendering/vulkan/vkr.h" 8 | 9 | PIM_C_BEGIN 10 | 11 | typedef struct Crate_s Crate; 12 | typedef struct Material_s Material; 13 | 14 | typedef struct MeshId_s 15 | { 16 | u32 version : 8; 17 | u32 index : 24; 18 | } MeshId; 19 | 20 | typedef struct DiskMeshId_s 21 | { 22 | Guid id; 23 | } DiskMeshId; 24 | 25 | typedef struct Mesh_s 26 | { 27 | float4* pim_noalias positions; 28 | float4* pim_noalias normals; 29 | float4* pim_noalias uvs; 30 | int4* pim_noalias texIndices; 31 | i32 length; 32 | vkrMeshId id; 33 | } Mesh; 34 | 35 | #define kMeshVersion 5 36 | typedef struct DiskMesh_s 37 | { 38 | i32 version; 39 | i32 length; 40 | char name[64]; 41 | } DiskMesh; 42 | 43 | void MeshSys_Init(void); 44 | void MeshSys_Update(void); 45 | void MeshSys_Shutdown(void); 46 | void MeshSys_Gui(bool* pEnabled); 47 | 48 | bool Mesh_New(Mesh *const mesh, Guid name, MeshId *const idOut); 49 | 50 | bool Mesh_Exists(MeshId id); 51 | 52 | void Mesh_Retain(MeshId id); 53 | void Mesh_Release(MeshId id); 54 | 55 | Mesh *const Mesh_Get(MeshId id); 56 | 57 | bool Mesh_Find(Guid name, MeshId *const idOut); 58 | bool Mesh_GetName(MeshId id, Guid *const dst); 59 | 60 | Box3D Mesh_CalcBounds(MeshId id); 61 | 62 | bool Mesh_Save(Crate *const crate, MeshId id, Guid *const dst); 63 | bool Mesh_Load(Crate *const crate, Guid name, MeshId *const dst); 64 | 65 | bool Mesh_Upload(MeshId id); 66 | 67 | PIM_C_END 68 | -------------------------------------------------------------------------------- /src/rendering/path_tracer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | #include "math/types.h" 5 | #include "common/random.h" 6 | 7 | PIM_C_BEGIN 8 | 9 | typedef struct Material_s Material; 10 | typedef struct Camera_s Camera; 11 | typedef struct Task_s Task; 12 | 13 | typedef struct PtScene_s PtScene; 14 | 15 | typedef enum 16 | { 17 | PtHit_Nothing = 0, 18 | PtHit_Backface, 19 | PtHit_Triangle, 20 | 21 | PtHit_COUNT 22 | } PtHitType; 23 | 24 | typedef struct PtRayHit_s 25 | { 26 | float4 wuvt; 27 | float4 normal; 28 | PtHitType type; 29 | i32 iVert; 30 | u32 flags; 31 | } PtRayHit; 32 | 33 | typedef struct PtDofInfo_s 34 | { 35 | float aperture; 36 | float focalLength; 37 | i32 bladeCount; 38 | float bladeRot; 39 | float focalPlaneCurvature; 40 | float autoFocusSpeed; 41 | bool autoFocus; 42 | } PtDofInfo; 43 | 44 | typedef struct PtTrace_s 45 | { 46 | float3* pim_noalias color; 47 | float3* pim_noalias albedo; 48 | float3* pim_noalias normal; 49 | float3* pim_noalias denoised; 50 | int2 imageSize; 51 | float sampleWeight; 52 | } PtTrace; 53 | 54 | typedef struct PtResult_s 55 | { 56 | float3 color; 57 | float3 albedo; 58 | float3 normal; 59 | } PtResult; 60 | 61 | typedef struct PtResults_s 62 | { 63 | float4* colors; 64 | float4* directions; 65 | } PtResults; 66 | 67 | void PtSys_Init(void); 68 | void PtSys_Update(void); 69 | void PtSys_Shutdown(void); 70 | 71 | PtScene* PtScene_New(void); 72 | void PtScene_Update(PtScene* scene); 73 | void PtScene_Del(PtScene* scene); 74 | void PtScene_Gui(PtScene* scene); 75 | 76 | void PtTrace_New(PtTrace* trace, int2 imageSize); 77 | void PtTrace_Del(PtTrace* trace); 78 | 79 | void DofInfo_New(PtDofInfo* dof); 80 | void DofInfo_Gui(PtDofInfo* dof); 81 | 82 | PtRayHit VEC_CALL Pt_Intersect( 83 | const PtScene* pim_noalias scene, 84 | float4 ro, 85 | float4 rd, 86 | float tNear, 87 | float tFar); 88 | 89 | PtResult VEC_CALL Pt_TraceRay( 90 | PtScene* pim_noalias scene, 91 | float4 ro, 92 | float4 rd); 93 | 94 | void Pt_Trace( 95 | PtTrace* pim_noalias trace, 96 | PtDofInfo* pim_noalias dof, 97 | PtScene* pim_noalias scene, 98 | const Camera* pim_noalias camera); 99 | 100 | PtResults Pt_RayGen( 101 | PtScene* pim_noalias scene, 102 | float4 origin, 103 | i32 count); 104 | 105 | PIM_C_END 106 | -------------------------------------------------------------------------------- /src/rendering/r_constants.c: -------------------------------------------------------------------------------- 1 | #include "rendering/r_constants.h" 2 | #include "common/cvars.h" 3 | #include "rendering/vulkan/vkr_display.h" 4 | 5 | static bool ms_init; 6 | 7 | static void EnsureInit(void) 8 | { 9 | if (!ms_init) 10 | { 11 | ms_init = true; 12 | i32 width = 0; 13 | i32 height = 0; 14 | if (vkrDisplay_GetWorkSize(&width, &height)) 15 | { 16 | ConVar_SetInt(&cv_r_width, width); 17 | ConVar_SetInt(&cv_r_height, height); 18 | } 19 | } 20 | } 21 | 22 | i32 r_width_get(void) 23 | { 24 | EnsureInit(); 25 | return ConVar_GetInt(&cv_r_width); 26 | } 27 | 28 | void r_width_set(i32 width) 29 | { 30 | EnsureInit(); 31 | ConVar_SetInt(&cv_r_width, width); 32 | } 33 | 34 | i32 r_height_get(void) 35 | { 36 | EnsureInit(); 37 | return ConVar_GetInt(&cv_r_height); 38 | } 39 | 40 | void r_height_set(i32 height) 41 | { 42 | EnsureInit(); 43 | ConVar_SetInt(&cv_r_height, height); 44 | } 45 | 46 | float r_aspect_get(void) 47 | { 48 | return (float)r_width_get() / (float)r_height_get(); 49 | } 50 | 51 | float r_scale_get(void) 52 | { 53 | EnsureInit(); 54 | return ConVar_GetFloat(&cv_r_scale); 55 | } 56 | 57 | void r_scale_set(float scale) 58 | { 59 | EnsureInit(); 60 | ConVar_SetFloat(&cv_r_scale, scale); 61 | } 62 | 63 | i32 r_scaledwidth_get(void) 64 | { 65 | return (i32)(r_width_get() * r_scale_get() + 0.5f); 66 | } 67 | 68 | i32 r_scaledheight_get(void) 69 | { 70 | return (i32)(r_height_get() * r_scale_get() + 0.5f); 71 | } 72 | -------------------------------------------------------------------------------- /src/rendering/r_constants.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | i32 r_width_get(void); 8 | void r_width_set(i32 width); 9 | 10 | i32 r_height_get(void); 11 | void r_height_set(i32 height); 12 | 13 | float r_aspect_get(void); 14 | 15 | float r_scale_get(void); 16 | void r_scale_set(float scale); 17 | 18 | i32 r_scaledwidth_get(void); 19 | i32 r_scaledheight_get(void); 20 | 21 | PIM_C_END 22 | -------------------------------------------------------------------------------- /src/rendering/r_gpu_shared.c: -------------------------------------------------------------------------------- 1 | #include "r_gpu_shared.h" 2 | 3 | SASSERT((sizeof(GpuGlobals) % 16) == 0); 4 | GpuGlobals g_GpuGlobals; 5 | -------------------------------------------------------------------------------- /src/rendering/r_gpu_shared.h: -------------------------------------------------------------------------------- 1 | #ifndef R_GPU_SHARED_H 2 | #define R_GPU_SHARED_H 3 | 4 | #ifndef PIM_HLSL 5 | # include "rendering/r_config.h" 6 | # include "math/types.h" 7 | #endif // !PIM_HLSL 8 | 9 | PIM_STRUCT_BEGIN(GpuGlobals) 10 | { 11 | float4x4 worldToClip; 12 | 13 | float4 eye; 14 | float4 forward; 15 | float4 right; 16 | float4 up; 17 | float2 slope; 18 | float zNear; 19 | float zFar; 20 | 21 | float hdrEnabled; 22 | float whitepoint; 23 | float displayNits; 24 | float uiNits; 25 | 26 | uint2 renderSize; 27 | uint2 displaySize; 28 | } PIM_STRUCT_END(GpuGlobals); 29 | 30 | #ifndef PIM_HLSL 31 | extern GpuGlobals g_GpuGlobals; 32 | #endif // !PIM_HLSL 33 | 34 | #endif // R_GPU_SHARED_H 35 | -------------------------------------------------------------------------------- /src/rendering/r_window.c: -------------------------------------------------------------------------------- 1 | #include "rendering/r_window.h" 2 | #include 3 | #include "common/time.h" 4 | #include "common/cvars.h" 5 | #include "threading/intrin.h" 6 | #include "threading/sleep.h" 7 | #include "common/profiler.h" 8 | #include "common/console.h" 9 | #include "input/input_system.h" 10 | #include "rendering/vulkan/vkr.h" 11 | #include 12 | 13 | static u64 ms_lastSwap; 14 | 15 | static void OnGlfwError(i32 error_code, const char* description); 16 | 17 | // ---------------------------------------------------------------------------- 18 | 19 | void WinSys_Init(void) 20 | { 21 | ms_lastSwap = Time_Now(); 22 | 23 | glfwSetErrorCallback(OnGlfwError); 24 | i32 rv = glfwInit(); 25 | ASSERT(rv == GLFW_TRUE); 26 | } 27 | 28 | void WinSys_Shutdown(void) 29 | { 30 | glfwTerminate(); 31 | } 32 | 33 | i32 Window_Width(void) 34 | { 35 | return g_vkr.window.height; 36 | } 37 | 38 | i32 Window_Height(void) 39 | { 40 | return g_vkr.window.width; 41 | } 42 | 43 | bool Window_IsOpen(void) 44 | { 45 | if (g_vkr.window.handle) 46 | { 47 | return !glfwWindowShouldClose(g_vkr.window.handle); 48 | } 49 | return false; 50 | } 51 | 52 | void Window_Close(bool shouldClose) 53 | { 54 | if (g_vkr.window.handle) 55 | { 56 | glfwSetWindowShouldClose(g_vkr.window.handle, shouldClose); 57 | } 58 | } 59 | 60 | i32 window_get_target(void) 61 | { 62 | return ConVar_GetInt(&cv_r_fpslimit); 63 | } 64 | 65 | void window_set_target(i32 fps) 66 | { 67 | ConVar_SetInt(&cv_r_fpslimit, fps); 68 | } 69 | 70 | ProfileMark(pm_waitfps, WaitForTargetFps) 71 | static void WaitForTargetFps(void) 72 | { 73 | ProfileBegin(pm_waitfps); 74 | 75 | const double targetMS = 1000.0 / window_get_target(); 76 | const double diffMS = targetMS - Time_Milli(Time_Now() - ms_lastSwap); 77 | if (diffMS > 1.5) 78 | { 79 | Intrin_Sleep((u32)(diffMS - 0.5)); 80 | } 81 | 82 | ms_lastSwap = Time_Now(); 83 | 84 | ProfileEnd(pm_waitfps); 85 | } 86 | 87 | void Window_Wait(void) 88 | { 89 | WaitForTargetFps(); 90 | } 91 | 92 | GLFWwindow* Window_Get(void) 93 | { 94 | return g_vkr.window.handle; 95 | } 96 | 97 | static void OnGlfwError(i32 error_code, const char* description) 98 | { 99 | Con_Logf(LogSev_Error, "glfw", "%s", description); 100 | ASSERT(false); 101 | } 102 | -------------------------------------------------------------------------------- /src/rendering/r_window.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | typedef struct GLFWwindow GLFWwindow; 8 | 9 | void WinSys_Init(void); 10 | void WinSys_Shutdown(void); 11 | 12 | GLFWwindow* Window_Get(void); 13 | 14 | i32 Window_Width(void); 15 | i32 Window_Height(void); 16 | bool Window_IsOpen(void); 17 | void Window_Close(bool shouldClose); 18 | void Window_Wait(void); 19 | 20 | PIM_C_END 21 | -------------------------------------------------------------------------------- /src/rendering/render_system.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | typedef struct FrameBuf_s FrameBuf; 8 | 9 | bool RenderSys_Init(void); 10 | bool RenderSys_WindowUpdate(void); 11 | void RenderSys_Update(void); 12 | void RenderSys_Shutdown(void); 13 | void RenderSys_Gui(bool* pEnabled); 14 | 15 | FrameBuf* RenderSys_FrontBuf(void); 16 | 17 | PIM_C_END 18 | -------------------------------------------------------------------------------- /src/rendering/resolve_tile.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | #include "math/types.h" 5 | #include "rendering/tonemap.h" 6 | 7 | PIM_C_BEGIN 8 | 9 | typedef struct FrameBuf_s FrameBuf; 10 | 11 | void ResolveTile(FrameBuf* target, TonemapId tonemapper, float4 toneParams); 12 | 13 | PIM_C_END 14 | -------------------------------------------------------------------------------- /src/rendering/rtcdraw.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | -------------------------------------------------------------------------------- /src/rendering/screenblit.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "rendering/vulkan/vkr.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | bool vkrScreenBlit_New(void); 8 | void vkrScreenBlit_Del(void); 9 | 10 | void vkrScreenBlit_Blit( 11 | const void* src, 12 | i32 width, 13 | i32 height, 14 | VkFormat format); 15 | 16 | PIM_C_END 17 | -------------------------------------------------------------------------------- /src/rendering/texture.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "math/types.h" 4 | #include "common/guid.h" 5 | #include "common/dbytes.h" 6 | #include "rendering/vulkan/vkr.h" 7 | 8 | PIM_C_BEGIN 9 | 10 | typedef struct Table_s Table; 11 | typedef struct Crate_s Crate; 12 | typedef struct Material_s Material; 13 | 14 | typedef struct TextureId_s 15 | { 16 | u32 version : 8; 17 | u32 index : 24; 18 | } TextureId; 19 | 20 | typedef struct DiskTextureId_s 21 | { 22 | Guid id; 23 | } DiskTextureId; 24 | 25 | typedef struct Texture_s 26 | { 27 | int2 size; 28 | void* pim_noalias texels; 29 | VkFormat format; 30 | vkrTextureId slot; 31 | } Texture; 32 | 33 | #define kTextureVersion 5 34 | typedef struct DiskTexture_s 35 | { 36 | i32 version; 37 | VkFormat format; 38 | char name[64]; 39 | int2 size; 40 | } DiskTexture; 41 | 42 | Table const *const Texture_GetTable(void); 43 | 44 | void TextureSys_Init(void); 45 | void TextureSys_Update(void); 46 | void TextureSys_Shutdown(void); 47 | void TextureSys_Gui(bool* pEnabled); 48 | 49 | bool Texture_LoadAt(const char* path, VkFormat format, VkSamplerAddressMode clamp, TextureId* idOut); 50 | bool Texture_New( 51 | Texture* tex, 52 | VkFormat format, 53 | VkSamplerAddressMode clamp, 54 | Guid name, 55 | TextureId* idOut); 56 | 57 | // upload cpu changes to gpu 58 | bool Texture_Upload(TextureId id); 59 | 60 | bool Texture_Exists(TextureId id); 61 | 62 | void Texture_Retain(TextureId id); 63 | void Texture_Release(TextureId id); 64 | 65 | Texture* Texture_Get(TextureId id); 66 | 67 | bool Texture_Find(Guid name, TextureId* idOut); 68 | bool Texture_GetGuid(TextureId id, Guid* nameOut); 69 | bool Texture_GetName(TextureId tid, char* dst, i32 size); 70 | 71 | bool Texture_Save(Crate* crate, TextureId tid, Guid* dst); 72 | bool Texture_Load(Crate* crate, Guid name, TextureId* dst); 73 | 74 | PIM_C_END 75 | -------------------------------------------------------------------------------- /src/rendering/tonemap.c: -------------------------------------------------------------------------------- 1 | #include "rendering/tonemap.h" 2 | #include "math/color.h" 3 | 4 | static const char* const kTonemapNames[] = 5 | { 6 | "Reinhard", 7 | "Uncharted2", 8 | "Hable", 9 | "Aces", 10 | }; 11 | SASSERT(NELEM(kTonemapNames) == TMap_COUNT); 12 | const char* const* Tonemap_Names(void) 13 | { 14 | return kTonemapNames; 15 | } 16 | -------------------------------------------------------------------------------- /src/rendering/tonemap.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | typedef enum 8 | { 9 | TMap_Reinhard = 0, 10 | TMap_Uncharted2, 11 | TMap_Hable, 12 | TMap_ACES, 13 | 14 | TMap_COUNT 15 | } TonemapId; 16 | const char* const* Tonemap_Names(void); 17 | 18 | PIM_C_END 19 | -------------------------------------------------------------------------------- /src/rendering/vulkan/shaderc_table.c: -------------------------------------------------------------------------------- 1 | #include "rendering/vulkan/shaderc_table.h" 2 | #include 3 | 4 | #define LOAD_FN(sym) \ 5 | g_shaderc.sym = Library_Sym(g_shaderc.lib, STR_TOK(shaderc_##sym)); \ 6 | ASSERT(g_shaderc.sym) 7 | 8 | shaderc_t g_shaderc; 9 | 10 | bool shaderc_open(void) 11 | { 12 | if (g_shaderc.lib.handle) 13 | { 14 | return true; 15 | } 16 | 17 | Library lib = Library_Open("shaderc_shared"); 18 | if (!lib.handle) 19 | { 20 | return false; 21 | } 22 | 23 | g_shaderc.lib = lib; 24 | 25 | LOAD_FN(compiler_initialize); 26 | LOAD_FN(compiler_release); 27 | LOAD_FN(compile_options_initialize); 28 | LOAD_FN(compile_options_clone); 29 | LOAD_FN(compile_options_release); 30 | LOAD_FN(compile_options_add_macro_definition); 31 | LOAD_FN(compile_options_set_source_language); 32 | LOAD_FN(compile_options_set_generate_debug_info); 33 | LOAD_FN(compile_options_set_optimization_level); 34 | LOAD_FN(compile_options_set_forced_version_profile); 35 | LOAD_FN(compile_options_set_include_callbacks); 36 | LOAD_FN(compile_options_set_suppress_warnings); 37 | LOAD_FN(compile_options_set_target_env); 38 | LOAD_FN(compile_options_set_target_spirv); 39 | LOAD_FN(compile_options_set_warnings_as_errors); 40 | LOAD_FN(compile_options_set_limit); 41 | LOAD_FN(compile_options_set_auto_bind_uniforms); 42 | LOAD_FN(compile_options_set_hlsl_io_mapping); 43 | LOAD_FN(compile_options_set_hlsl_offsets); 44 | LOAD_FN(compile_options_set_binding_base); 45 | LOAD_FN(compile_options_set_binding_base_for_stage); 46 | LOAD_FN(compile_options_set_auto_map_locations); 47 | LOAD_FN(compile_options_set_hlsl_register_set_and_binding_for_stage); 48 | LOAD_FN(compile_options_set_hlsl_register_set_and_binding); 49 | LOAD_FN(compile_options_set_hlsl_functionality1); 50 | LOAD_FN(compile_options_set_invert_y); 51 | LOAD_FN(compile_options_set_nan_clamp); 52 | LOAD_FN(compile_into_spv); 53 | LOAD_FN(compile_into_spv_assembly); 54 | LOAD_FN(compile_into_preprocessed_text); 55 | LOAD_FN(assemble_into_spv); 56 | LOAD_FN(result_release); 57 | LOAD_FN(result_get_length); 58 | LOAD_FN(result_get_num_warnings); 59 | LOAD_FN(result_get_num_errors); 60 | LOAD_FN(result_get_compilation_status); 61 | LOAD_FN(result_get_bytes); 62 | LOAD_FN(result_get_error_message); 63 | LOAD_FN(get_spv_version); 64 | LOAD_FN(parse_version_profile); 65 | 66 | return true; 67 | } 68 | 69 | void shaderc_close(void) 70 | { 71 | if (g_shaderc.lib.handle) 72 | { 73 | Library_Close(g_shaderc.lib); 74 | memset(&g_shaderc, 0, sizeof(g_shaderc)); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vk_mem_alloc.cpp: -------------------------------------------------------------------------------- 1 | #include "common/macro.h" 2 | #include 3 | #define VMA_ASSERT ASSERT 4 | #define VMA_STATIC_VULKAN_FUNCTIONS 0 5 | #define VMA_IMPLEMENTATION 1 6 | #include "VulkanMemoryAllocator/src/vk_mem_alloc.h" 7 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_bindings.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "rendering/vulkan/vkr.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | bool vkrBindings_Init(void); 8 | void vkrBindings_Update(void); 9 | void vkrBindings_Shutdown(void); 10 | 11 | VkDescriptorSetLayout vkrBindings_GetSetLayout(void); 12 | VkDescriptorSet vkrBindings_GetSet(void); 13 | 14 | void vkrBindings_BindImage( 15 | i32 id, 16 | VkDescriptorType type, 17 | VkSampler sampler, 18 | VkImageView view, 19 | VkImageLayout layout); 20 | 21 | void vkrBindings_BindBuffer( 22 | i32 id, 23 | VkDescriptorType type, 24 | vkrBuffer const *const buffer); 25 | 26 | PIM_C_END 27 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_buffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "rendering/vulkan/vkr.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | bool vkrBuffer_New( 8 | vkrBuffer *const buffer, 9 | i32 size, 10 | VkBufferUsageFlags usage, 11 | vkrMemUsage memUsage); 12 | void vkrBuffer_Release(vkrBuffer *const buffer); 13 | 14 | // if size exceeds buffer's current size: 15 | // - creates new larger buffer 16 | // - releases old buffer with fence 17 | // - updates buffer inout argument 18 | // - contents of buffer are invalidated by this call! 19 | bool vkrBuffer_Reserve( 20 | vkrBuffer *const buffer, 21 | i32 size, 22 | VkBufferUsageFlags bufferUsage, 23 | vkrMemUsage memUsage); 24 | 25 | const void* vkrBuffer_MapRead(vkrBuffer* buffer); 26 | void vkrBuffer_UnmapRead(vkrBuffer* buffer); 27 | void* vkrBuffer_MapWrite(vkrBuffer* buffer); 28 | void vkrBuffer_UnmapWrite(vkrBuffer* buffer); 29 | 30 | // helper for map, unmap, flush 31 | bool vkrBuffer_Write( 32 | vkrBuffer* buffer, 33 | const void* src, 34 | i32 size); 35 | bool vkrBuffer_Read( 36 | vkrBuffer* buffer, 37 | void* dst, 38 | i32 size); 39 | 40 | // ---------------------------------------------------------------------------- 41 | 42 | bool vkrBufferSet_New( 43 | vkrBufferSet *const set, 44 | i32 size, 45 | VkBufferUsageFlags usage, 46 | vkrMemUsage memUsage); 47 | void vkrBufferSet_Release(vkrBufferSet *const set); 48 | vkrBuffer *const vkrBufferSet_Current(vkrBufferSet *const set); 49 | vkrBuffer *const vkrBufferSet_Next(vkrBufferSet *const set); 50 | vkrBuffer *const vkrBufferSet_Prev(vkrBufferSet *const set); 51 | bool vkrBufferSet_Reserve( 52 | vkrBufferSet *const set, 53 | i32 size, 54 | VkBufferUsageFlags bufferUsage, 55 | vkrMemUsage memUsage); 56 | bool vkrBufferSet_Write( 57 | vkrBufferSet *const set, 58 | const void* src, 59 | i32 size); 60 | bool vkrBufferSet_Read( 61 | vkrBufferSet *const set, 62 | void* dst, 63 | i32 size); 64 | 65 | PIM_C_END 66 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_compile.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | #include "rendering/vulkan/vkr.h" 5 | 6 | PIM_C_BEGIN 7 | 8 | bool vkrCompile(const vkrCompileInput* input, vkrCompileOutput* output); 9 | void vkrCompileOutput_Del(vkrCompileOutput* output); 10 | 11 | char* vkrLoadShader(const char* filename); 12 | 13 | PIM_C_END 14 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_context.c: -------------------------------------------------------------------------------- 1 | #include "rendering/vulkan/vkr_context.h" 2 | #include "rendering/vulkan/vkr_cmd.h" 3 | #include "rendering/vulkan/vkr_desc.h" 4 | #include "rendering/vulkan/vkr_mem.h" 5 | #include "rendering/vulkan/vkr_buffer.h" 6 | #include "allocator/allocator.h" 7 | #include "common/profiler.h" 8 | #include "threading/task.h" 9 | #include 10 | 11 | vkrContext* vkrGetContext(void) 12 | { 13 | return &g_vkr.context; 14 | } 15 | 16 | bool vkrContext_New(vkrContext* ctx) 17 | { 18 | memset(ctx, 0, sizeof(*ctx)); 19 | return true; 20 | } 21 | 22 | void vkrContext_Del(vkrContext* ctx) 23 | { 24 | memset(ctx, 0, sizeof(*ctx)); 25 | } 26 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_context.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "rendering/vulkan/vkr.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | bool vkrContext_New(vkrContext* ctx); 8 | void vkrContext_Del(vkrContext* ctx); 9 | 10 | PIM_C_END 11 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_debug.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "rendering/vulkan/vkr.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | VkDebugUtilsMessengerEXT vkrCreateDebugMessenger(void); 8 | void vkrDestroyDebugMessenger(VkDebugUtilsMessengerEXT messenger); 9 | 10 | static VKAPI_ATTR VkBool32 VKAPI_CALL vkrOnVulkanMessage( 11 | VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, 12 | VkDebugUtilsMessageTypeFlagsEXT messageType, 13 | const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, 14 | void* pUserData); 15 | 16 | PIM_C_END 17 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_depthpass.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "rendering/vulkan/vkr.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | bool vkrDepthPass_New(void); 8 | void vkrDepthPass_Del(void); 9 | 10 | void vkrDepthPass_Setup(void); 11 | void vkrDepthPass_Execute(void); 12 | 13 | PIM_C_END 14 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_desc.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "rendering/vulkan/vkr.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | VkDescriptorSetLayout vkrDescSetLayout_New( 8 | i32 bindingCount, 9 | const VkDescriptorSetLayoutBinding* pBindings, 10 | VkDescriptorSetLayoutCreateFlags flags); 11 | void vkrDescSetLayout_Del(VkDescriptorSetLayout layout); 12 | 13 | VkDescriptorPool vkrDescPool_New( 14 | i32 maxSets, 15 | i32 sizeCount, 16 | const VkDescriptorPoolSize* sizes); 17 | void vkrDescPool_Del(VkDescriptorPool pool); 18 | void vkrDescPool_Reset(VkDescriptorPool pool); 19 | 20 | VkDescriptorSet vkrDescSet_New(VkDescriptorPool pool, VkDescriptorSetLayout layout); 21 | void vkrDescSet_Del(VkDescriptorPool pool, VkDescriptorSet set); 22 | 23 | void vkrDesc_WriteImageTable( 24 | VkDescriptorSet set, i32 binding, 25 | VkDescriptorType type, 26 | i32 count, const VkDescriptorImageInfo* bindings); 27 | 28 | void vkrDesc_WriteBufferTable( 29 | VkDescriptorSet set, i32 binding, 30 | VkDescriptorType type, 31 | i32 count, const VkDescriptorBufferInfo* bindings); 32 | 33 | PIM_C_END 34 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_device.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "rendering/vulkan/vkr.h" 4 | #include "containers/strlist.h" 5 | 6 | PIM_C_BEGIN 7 | 8 | bool vkrDevice_Init(vkrSys* vkr); 9 | void vkrDevice_Shutdown(vkrSys* vkr); 10 | void vkrDevice_WaitIdle(void); 11 | 12 | // ---------------------------------------------------------------------------- 13 | 14 | u32 vkrEnumPhysicalDevices( 15 | VkInstance inst, 16 | VkPhysicalDevice** devicesOut, 17 | vkrProps** propsOut, 18 | vkrFeats** featuresOut, 19 | vkrDevExts** extsOut); 20 | VkPhysicalDevice vkrSelectPhysicalDevice( 21 | const vkrWindow* window, 22 | vkrProps* propsOut, 23 | vkrFeats* featsOut, 24 | vkrDevExts* extsOut); 25 | 26 | VkDevice vkrCreateDevice( 27 | const vkrWindow* window, 28 | StrList extensions, 29 | StrList layers); 30 | 31 | PIM_C_END 32 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_display.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "rendering/vulkan/vkr.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | // usable windowed size 8 | bool vkrDisplay_GetWorkSize(i32* widthOut, i32* heightOut); 9 | // usable fullscreen size 10 | bool vkrDisplay_GetFullSize(i32* widthOut, i32* heightOut); 11 | bool vkrDisplay_GetSize(i32* widthOut, i32* heightOut, bool fullscreen); 12 | 13 | bool vkrWindow_New( 14 | vkrWindow* window, 15 | const char* title, 16 | i32 width, i32 height, 17 | bool fullscreen); 18 | void vkrWindow_Del(vkrWindow* window); 19 | 20 | // returns true when width or height has changed 21 | bool vkrWindow_UpdateSize(vkrWindow* window); 22 | 23 | void vkrWindow_GetPosition(vkrWindow* window, i32* xOut, i32* yOut); 24 | void vkrWindow_SetPosition(vkrWindow* window, i32 x, i32 y); 25 | 26 | // returns false when the display window should close 27 | bool vkrWindow_IsOpen(const vkrWindow* window); 28 | 29 | // processes windowing and input event queue 30 | void vkrWindow_Poll(void); 31 | 32 | PIM_C_END 33 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_exposure.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vethanis/pim/15a50bdbf9eb3e78d29cfdb412e21a3dc0fd223a/src/rendering/vulkan/vkr_exposure.c -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_exposure.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "rendering/vulkan/vkr.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | vkrExposure* vkrExposure_GetParams(void); 8 | float vkrGetAvgLuminance(void); 9 | float vkrGetExposure(void); 10 | float vkrGetMaxLuminance(void); 11 | float vkrGetMinLuminance(void); 12 | 13 | bool vkrExposure_Init(void); 14 | void vkrExposure_Shutdown(void); 15 | 16 | void vkrExposure_Setup(void); 17 | void vkrExposure_Execute(void); 18 | 19 | PIM_C_END 20 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_extension.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "rendering/vulkan/vkr.h" 4 | #include "containers/strlist.h" 5 | 6 | PIM_C_BEGIN 7 | 8 | typedef struct vkrPhDevScore_s 9 | { 10 | i32 rtScore; 11 | i32 extScore; 12 | i32 featScore; 13 | i32 propScore; 14 | bool hasRequiredExts; 15 | bool hasQueueSupport; 16 | } vkrPhDevScore; 17 | 18 | i32 vkrFindExtension( 19 | const VkExtensionProperties* props, 20 | u32 count, 21 | const char* name); 22 | i32 vkrFindLayer( 23 | const VkLayerProperties* props, 24 | u32 count, 25 | const char* name); 26 | 27 | bool vkrTryAddExtension( 28 | StrList* list, 29 | const VkExtensionProperties* props, 30 | u32 propCount, 31 | const char* name); 32 | bool vkrTryAddLayer( 33 | StrList* list, 34 | const VkLayerProperties* props, 35 | u32 propCount, 36 | const char* name); 37 | 38 | VkLayerProperties* vkrEnumInstLayers(u32* countOut); 39 | VkExtensionProperties* vkrEnumInstExtensions(u32* countOut); 40 | VkExtensionProperties* vkrEnumDevExtensions(VkPhysicalDevice phdev, u32* countOut); 41 | 42 | StrList vkrGetLayers(vkrLayers* layersOut); 43 | StrList vkrGetInstExtensions(vkrInstExts* extsOut); 44 | StrList vkrGetDevExtensions(VkPhysicalDevice phdev, vkrDevExts* extsOut); 45 | 46 | void vkrListInstLayers(void); 47 | void vkrListInstExtensions(void); 48 | void vkrListDevExtensions(VkPhysicalDevice phdev); 49 | 50 | void vkrDevExts_New(vkrDevExts* exts, VkPhysicalDevice phdev); 51 | StrList vkrDevExts_ToList(const vkrDevExts* exts); 52 | 53 | i32 vkrFeats_Eval(const vkrFeats* feats); 54 | 55 | i32 vkrProps_Eval(const vkrProps* props); 56 | i32 vkrProps_LimitsEval(const VkPhysicalDeviceLimits* lims); 57 | #if VKR_RT 58 | i32 vkrProps_AccStrEval(const VkPhysicalDeviceAccelerationStructurePropertiesKHR* accstr); 59 | i32 vkrProps_RtPipeEval(const VkPhysicalDeviceRayTracingPipelinePropertiesKHR* rtpipe); 60 | #endif // VKR_RT 61 | 62 | i32 vkrDevExts_OptEval(const vkrDevExts* exts); 63 | i32 vkrDevExts_RtEval(const vkrDevExts* exts); 64 | bool vkrDevExts_ReqEval(const vkrDevExts* exts); 65 | 66 | PIM_C_END 67 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_framebuffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "rendering/vulkan/vkr.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | bool vkrFramebuffer_Init(void); 8 | void vkrFramebuffer_Shutdown(void); 9 | 10 | // find or create a framebuffer matching the inputs 11 | VkFramebuffer vkrFramebuffer_Get( 12 | const vkrImage** attachments, 13 | i32 count, 14 | i32 width, 15 | i32 height); 16 | 17 | // remove all framebuffers referencing the given view 18 | void vkrFramebuffer_Remove(VkImageView view); 19 | 20 | PIM_C_END 21 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_im.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/macro.h" 4 | #include "math/types.h" 5 | 6 | PIM_C_BEGIN 7 | 8 | // ---------------------------------------------------------------------------- 9 | // system 10 | 11 | bool vkrImSys_Init(void); 12 | void vkrImSys_Shutdown(void); 13 | 14 | void vkrImSys_Clear(void); 15 | void vkrImSys_Flush(void); 16 | 17 | void vkrImSys_Draw(void); 18 | void vkrImSys_DrawDepth(void); 19 | 20 | // ---------------------------------------------------------------------------- 21 | // user 22 | 23 | void vkrIm_Begin(void); 24 | void vkrIm_End(void); 25 | 26 | void vkrIm_Mesh( 27 | const float4* pim_noalias positions, 28 | const float4* pim_noalias normals, 29 | const float4* pim_noalias uvs, 30 | const int4* pim_noalias texInds, 31 | i32 vertCount); 32 | 33 | void VEC_CALL vkrIm_Vert(float4 pos, float4 nor, float4 uv, int4 itex); 34 | 35 | PIM_C_END 36 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_image.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "rendering/vulkan/vkr.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | // ---------------------------------------------------------------------------- 8 | 9 | bool vkrImage_New( 10 | vkrImage* image, 11 | const VkImageCreateInfo* info, 12 | vkrMemUsage memUsage); 13 | void vkrImage_Release(vkrImage* image); 14 | 15 | // turns an external VkImage handle into a vkrImage 16 | bool vkrImage_Import( 17 | vkrImage* image, 18 | const VkImageCreateInfo* info, 19 | VkImage handle); 20 | 21 | bool vkrImage_Reserve( 22 | vkrImage* image, 23 | const VkImageCreateInfo* info, 24 | vkrMemUsage memUsage); 25 | 26 | void* vkrImage_Map(const vkrImage* image); 27 | void vkrImage_Unmap(const vkrImage* image); 28 | void vkrImage_Flush(const vkrImage* image); 29 | 30 | // ---------------------------------------------------------------------------- 31 | 32 | bool vkrImageSet_New( 33 | vkrImageSet* set, 34 | const VkImageCreateInfo* info, 35 | vkrMemUsage memUsage); 36 | void vkrImageSet_Release(vkrImageSet* set); 37 | 38 | vkrImage* vkrImageSet_Current(vkrImageSet* set); 39 | vkrImage* vkrImageSet_Prev(vkrImageSet* set); 40 | vkrImage* vkrImageSet_Next(vkrImageSet* set); 41 | 42 | bool vkrImageSet_Reserve( 43 | vkrImageSet* set, 44 | const VkImageCreateInfo* info, 45 | vkrMemUsage memUsage); 46 | 47 | // ---------------------------------------------------------------------------- 48 | 49 | void vkrImageView_Release(VkImageView view, vkrSubmitId submitId); 50 | void vkrAttachment_Release(VkImageView view, vkrSubmitId submitId); 51 | 52 | // ---------------------------------------------------------------------------- 53 | 54 | VkImageViewType vkrImage_InfoToViewType(const VkImageCreateInfo* info); 55 | VkImageAspectFlags vkrImage_InfoToAspects(const VkImageCreateInfo* info); 56 | bool vkrImage_InfoToViewInfo( 57 | const VkImageCreateInfo* info, 58 | VkImageViewCreateInfo* viewInfo); 59 | 60 | PIM_C_END 61 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_instance.c: -------------------------------------------------------------------------------- 1 | #include "rendering/vulkan/vkr_instance.h" 2 | #include "rendering/vulkan/vkr_debug.h" 3 | #include "rendering/vulkan/vkr_extension.h" 4 | #include "allocator/allocator.h" 5 | #include "common/console.h" 6 | #include "common/stringutil.h" 7 | #include 8 | #include 9 | 10 | bool vkrInstance_Init(vkrSys* vkr) 11 | { 12 | ASSERT(vkr); 13 | 14 | VkCheck(volkInitialize()); 15 | 16 | vkrListInstLayers(); 17 | vkrListInstExtensions(); 18 | 19 | vkr->inst = vkrCreateInstance( 20 | vkrGetInstExtensions(&g_vkrInstExts), 21 | vkrGetLayers(&g_vkrLayers)); 22 | ASSERT(vkr->inst); 23 | if (!vkr->inst) 24 | { 25 | return false; 26 | } 27 | 28 | volkLoadInstance(vkr->inst); 29 | 30 | vkr->messenger = vkrCreateDebugMessenger(); 31 | 32 | return true; 33 | } 34 | 35 | void vkrInstance_Shutdown(vkrSys* vkr) 36 | { 37 | if (vkr) 38 | { 39 | vkrDestroyDebugMessenger(vkr->messenger); 40 | vkr->messenger = NULL; 41 | if (vkr->inst) 42 | { 43 | vkDestroyInstance(vkr->inst, NULL); 44 | vkr->inst = NULL; 45 | } 46 | } 47 | } 48 | 49 | VkInstance vkrCreateInstance(StrList extensions, StrList layers) 50 | { 51 | const VkApplicationInfo appInfo = 52 | { 53 | .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, 54 | .pApplicationName = "pim", 55 | .applicationVersion = 1, 56 | .pEngineName = "pim", 57 | .engineVersion = 1, 58 | .apiVersion = VK_API_VERSION_1_2, 59 | }; 60 | 61 | const VkInstanceCreateInfo instInfo = 62 | { 63 | .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, 64 | .flags = 0x0, 65 | .pApplicationInfo = &appInfo, 66 | .enabledLayerCount = layers.count, 67 | .ppEnabledLayerNames = layers.ptr, 68 | .enabledExtensionCount = extensions.count, 69 | .ppEnabledExtensionNames = extensions.ptr, 70 | }; 71 | 72 | VkInstance inst = NULL; 73 | VkCheck(vkCreateInstance(&instInfo, NULL, &inst)); 74 | 75 | StrList_Del(&extensions); 76 | StrList_Del(&layers); 77 | 78 | return inst; 79 | } 80 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_instance.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "rendering/vulkan/vkr.h" 4 | #include "containers/strlist.h" 5 | 6 | PIM_C_BEGIN 7 | 8 | bool vkrInstance_Init(vkrSys* vkr); 9 | void vkrInstance_Shutdown(vkrSys* vkr); 10 | 11 | // ---------------------------------------------------------------------------- 12 | 13 | VkInstance vkrCreateInstance(StrList extensions, StrList layers); 14 | 15 | PIM_C_END 16 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_mainpass.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "rendering/vulkan/vkr.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | bool vkrMainPass_New(void); 8 | void vkrMainPass_Del(void); 9 | 10 | void vkrMainPass_Setup(void); 11 | void vkrMainPass_Execute(void); 12 | 13 | PIM_C_END 14 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_mem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "rendering/vulkan/vkr.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | bool vkrMemSys_Init(void); 8 | void vkrMemSys_Shutdown(void); 9 | void vkrMemSys_Update(void); 10 | void vkrMemSys_Finalize(void); 11 | 12 | bool vkrMem_BufferNew( 13 | vkrBuffer* buffer, 14 | i32 size, 15 | VkBufferUsageFlags usage, 16 | vkrMemUsage memUsage); 17 | void vkrMem_BufferDel(vkrBuffer* buffer); 18 | 19 | bool vkrMem_ImageNew( 20 | vkrImage* image, 21 | const VkImageCreateInfo* info, 22 | vkrMemUsage memUsage); 23 | void vkrMem_ImageDel(vkrImage* image); 24 | 25 | void vkrReleasable_Add(const vkrReleasable* releasable); 26 | void vkrReleasable_Del(vkrReleasable* releasable); 27 | 28 | void* vkrMem_Map(VmaAllocation allocation); 29 | void vkrMem_Unmap(VmaAllocation allocation); 30 | void vkrMem_Flush(VmaAllocation allocation); 31 | 32 | PIM_C_END 33 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_mesh.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "rendering/vulkan/vkr.h" 4 | #include "math/types.h" 5 | 6 | PIM_C_BEGIN 7 | 8 | bool vkrMeshSys_Init(void); 9 | void vkrMeshSys_Update(void); 10 | void vkrMeshSys_Shutdown(void); 11 | 12 | bool vkrMesh_Exists(vkrMeshId id); 13 | vkrMeshId vkrMesh_New( 14 | i32 vertCount, 15 | const float4* pim_noalias positions, 16 | const float4* pim_noalias normals, 17 | const float4* pim_noalias uv01, 18 | const int4* pim_noalias texIndices); 19 | bool vkrMesh_Del(vkrMeshId id); 20 | 21 | bool vkrMesh_Upload( 22 | vkrMeshId id, 23 | i32 vertCount, 24 | const float4* pim_noalias positions, 25 | const float4* pim_noalias normals, 26 | const float4* pim_noalias uv01, 27 | const int4* pim_noalias texIndices); 28 | 29 | PIM_C_END 30 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_opaquepass.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "rendering/vulkan/vkr.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | bool vkrOpaquePass_New(void); 8 | void vkrOpaquePass_Del(void); 9 | 10 | void vkrOpaquePass_Setup(void); 11 | void vkrOpaquePass_Execute(void); 12 | 13 | PIM_C_END 14 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_pass.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "rendering/vulkan/vkr.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | bool vkrPass_New(vkrPass *const pass, vkrPassDesc const *const desc); 8 | void vkrPass_Del(vkrPass *const pass); 9 | 10 | PIM_C_END 11 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_pipeline.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "rendering/vulkan/vkr.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | i32 vkrVertTypeSize(vkrVertType type); 8 | VkFormat vkrVertTypeFormat(vkrVertType type); 9 | 10 | VkPipelineLayout vkrPipelineLayout_New( 11 | i32 setCount, const VkDescriptorSetLayout* setLayouts, 12 | i32 rangeCount, const VkPushConstantRange* ranges); 13 | void vkrPipelineLayout_Del(VkPipelineLayout layout); 14 | 15 | VkPipeline vkrPipeline_NewGfx( 16 | const vkrFixedFuncs* fixedfuncs, 17 | const vkrVertexLayout* vertLayout, 18 | VkPipelineLayout layout, 19 | VkRenderPass renderPass, 20 | i32 subpass, 21 | i32 shaderCount, 22 | const VkPipelineShaderStageCreateInfo* shaders); 23 | 24 | VkPipeline vkrPipeline_NewComp( 25 | VkPipelineLayout layout, 26 | const VkPipelineShaderStageCreateInfo* shader); 27 | 28 | void vkrPipeline_Del(VkPipeline pipeline); 29 | 30 | PIM_C_END 31 | 32 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_queue.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "rendering/vulkan/vkr.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | void vkrCreateQueues(void); 8 | void vkrDestroyQueues(void); 9 | 10 | // ---------------------------------------------------------------------------- 11 | 12 | bool vkrQueue_New( 13 | vkrQueue* queue, 14 | const vkrQueueSupport* support, 15 | vkrQueueId id); 16 | void vkrQueue_Del(vkrQueue* queue); 17 | 18 | VkQueueFamilyProperties* vkrEnumQueueFamilyProperties( 19 | VkPhysicalDevice phdev, 20 | u32* countOut); 21 | vkrQueueSupport vkrQueryQueueSupport(VkPhysicalDevice phdev, VkSurfaceKHR surf); 22 | 23 | PIM_C_END 24 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_renderpass.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "rendering/vulkan/vkr.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | VkRenderPass vkrRenderPass_Get(const vkrRenderPassDesc* desc); 8 | void vkrRenderPass_Clear(void); 9 | 10 | PIM_C_END 11 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_sampler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "rendering/vulkan/vkr.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | bool vkrSampler_Init(void); 8 | void vkrSampler_Update(void); 9 | void vkrSampler_Shutdown(void); 10 | 11 | VkSampler vkrSampler_Get( 12 | VkFilter filter, 13 | VkSamplerMipmapMode mipMode, 14 | VkSamplerAddressMode addressMode, 15 | float aniso); 16 | 17 | PIM_C_END 18 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_shader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "rendering/vulkan/vkr.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | VkShaderStageFlags vkrShaderTypeToStage(vkrShaderType type); 8 | 9 | bool vkrShader_New( 10 | VkPipelineShaderStageCreateInfo* shader, 11 | const char* filename, 12 | const char* entrypoint, 13 | vkrShaderType type); 14 | 15 | void vkrShader_Del(VkPipelineShaderStageCreateInfo* shader); 16 | 17 | PIM_C_END 18 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_swapchain.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "rendering/vulkan/vkr.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | bool vkrSwapchain_New(vkrSwapchain* chain, vkrSwapchain* prev); 8 | void vkrSwapchain_Del(vkrSwapchain* chain); 9 | 10 | bool vkrSwapchain_Recreate(void); 11 | 12 | // acquire synchronization index for a frame in flight 13 | // should be done at beginning of frame 14 | u32 vkrSwapchain_AcquireSync(void); 15 | // acquire image index for a swapchain image 16 | // should be done for presentation render pass 17 | u32 vkrSwapchain_AcquireImage(void); 18 | // submits then presents final render pass to the swapchain 19 | void vkrSwapchain_Submit(vkrCmdBuf* cmd); 20 | 21 | VkViewport vkrSwapchain_GetViewport(void); 22 | VkRect2D vkrSwapchain_GetRect(void); 23 | float vkrSwapchain_GetAspect(void); 24 | 25 | // ---------------------------------------------------------------------------- 26 | 27 | vkrSwapchainSupport vkrQuerySwapchainSupport( 28 | VkPhysicalDevice phdev, 29 | VkSurfaceKHR surf); 30 | VkSurfaceFormatKHR vkrSelectSwapFormat( 31 | const VkSurfaceFormatKHR* formats, 32 | i32 count); 33 | VkPresentModeKHR vkrSelectSwapMode( 34 | const VkPresentModeKHR* modes, 35 | i32 count); 36 | VkExtent2D vkrSelectSwapExtent( 37 | const VkSurfaceCapabilitiesKHR* caps, 38 | i32 width, 39 | i32 height); 40 | 41 | PIM_C_END 42 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_sync.c: -------------------------------------------------------------------------------- 1 | #include "rendering/vulkan/vkr_sync.h" 2 | #include "allocator/allocator.h" 3 | #include "common/profiler.h" 4 | #include 5 | 6 | ProfileMark(pm_createsema, vkrSemaphore_New) 7 | VkSemaphore vkrSemaphore_New(void) 8 | { 9 | ProfileBegin(pm_createsema); 10 | ASSERT(g_vkr.dev); 11 | const VkSemaphoreCreateInfo info = 12 | { 13 | .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, 14 | }; 15 | VkSemaphore handle = NULL; 16 | VkCheck(vkCreateSemaphore(g_vkr.dev, &info, NULL, &handle)); 17 | ASSERT(handle); 18 | ProfileEnd(pm_createsema); 19 | return handle; 20 | } 21 | 22 | ProfileMark(pm_destroysema, vkrSemaphore_Del) 23 | void vkrSemaphore_Del(VkSemaphore sema) 24 | { 25 | ASSERT(g_vkr.dev); 26 | if (sema) 27 | { 28 | ProfileBegin(pm_destroysema); 29 | vkDestroySemaphore(g_vkr.dev, sema, NULL); 30 | ProfileEnd(pm_destroysema); 31 | } 32 | } 33 | 34 | ProfileMark(pm_createfence, vkrFence_New) 35 | VkFence vkrFence_New(bool signalled) 36 | { 37 | ProfileBegin(pm_createfence); 38 | ASSERT(g_vkr.dev); 39 | const VkFenceCreateInfo info = 40 | { 41 | .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, 42 | .flags = signalled ? VK_FENCE_CREATE_SIGNALED_BIT : 0, 43 | }; 44 | VkFence handle = NULL; 45 | VkCheck(vkCreateFence(g_vkr.dev, &info, NULL, &handle)); 46 | ASSERT(handle); 47 | ProfileEnd(pm_createfence); 48 | return handle; 49 | } 50 | 51 | ProfileMark(pm_destroyfence, vkrFence_Del) 52 | void vkrFence_Del(VkFence fence) 53 | { 54 | ASSERT(g_vkr.dev); 55 | if (fence) 56 | { 57 | ProfileBegin(pm_destroyfence); 58 | vkDestroyFence(g_vkr.dev, fence, NULL); 59 | ProfileEnd(pm_destroyfence); 60 | } 61 | } 62 | 63 | void vkrFence_Reset(VkFence fence) 64 | { 65 | ASSERT(g_vkr.dev); 66 | ASSERT(fence); 67 | VkCheck(vkResetFences(g_vkr.dev, 1, &fence)); 68 | } 69 | 70 | ProfileMark(pm_waitfence, vkrFence_Wait) 71 | void vkrFence_Wait(VkFence fence) 72 | { 73 | ProfileBegin(pm_waitfence); 74 | ASSERT(g_vkr.dev); 75 | ASSERT(fence); 76 | const u64 timeout = -1; 77 | while (vkrFence_Stat(fence) != vkrFenceState_Signalled) 78 | { 79 | VkCheck(vkWaitForFences(g_vkr.dev, 1, &fence, false, timeout)); 80 | } 81 | ProfileEnd(pm_waitfence); 82 | } 83 | 84 | vkrFenceState vkrFence_Stat(VkFence fence) 85 | { 86 | ASSERT(g_vkr.dev); 87 | ASSERT(fence); 88 | VkResult state = vkGetFenceStatus(g_vkr.dev, fence); 89 | ASSERT(state != vkrFenceState_Lost); 90 | return (vkrFenceState)state; 91 | } 92 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_sync.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "rendering/vulkan/vkr.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | VkSemaphore vkrSemaphore_New(void); 8 | void vkrSemaphore_Del(VkSemaphore sema); 9 | 10 | VkFence vkrFence_New(bool signalled); 11 | void vkrFence_Del(VkFence fence); 12 | void vkrFence_Reset(VkFence fence); 13 | void vkrFence_Wait(VkFence fence); 14 | vkrFenceState vkrFence_Stat(VkFence fence); 15 | 16 | PIM_C_END 17 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_targets.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "rendering/vulkan/vkr.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | bool vkrTargets_Init(void); 8 | void vkrTargets_Shutdown(void); 9 | void vkrTargets_Recreate(void); 10 | 11 | PIM_C_END 12 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_textable.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "rendering/vulkan/vkr.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | bool vkrTexTable_Init(void); 8 | void vkrTexTable_Update(void); 9 | void vkrTexTable_Shutdown(void); 10 | 11 | void vkrTexTable_Write(VkDescriptorSet set); 12 | 13 | bool vkrTexTable_Exists(vkrTextureId id); 14 | vkrTextureId vkrTexTable_Alloc( 15 | VkImageViewType type, 16 | VkFormat format, 17 | VkSamplerAddressMode clamp, 18 | i32 width, 19 | i32 height, 20 | i32 depth, 21 | i32 layers, 22 | bool mips); 23 | bool vkrTexTable_Free(vkrTextureId id); 24 | bool vkrTexTable_Upload( 25 | vkrTextureId id, 26 | i32 layer, 27 | void const *const data, 28 | i32 bytes); 29 | 30 | bool vkrTexTable_SetSampler( 31 | vkrTextureId id, 32 | VkFilter filter, 33 | VkSamplerMipmapMode mipMode, 34 | VkSamplerAddressMode addressMode, 35 | float aniso); 36 | 37 | // returns bindless index 38 | u32 vkrTexTable_State( 39 | vkrTextureId id, 40 | vkrCmdBuf* cmd, 41 | const vkrImageState_t* state); 42 | u32 vkrTexTable_FragSample( 43 | vkrTextureId id, 44 | vkrCmdBuf* cmd); 45 | u32 vkrTexTable_ComputeSample( 46 | vkrTextureId id, 47 | vkrCmdBuf* cmd); 48 | u32 vkrTexTable_ComputeLoadStore( 49 | vkrTextureId id, 50 | vkrCmdBuf* cmd); 51 | 52 | void vkrTexTable_StateAll( 53 | vkrCmdBuf* cmd, 54 | const vkrImageState_t* state); 55 | void vkrTexTable_FragSampleAll(vkrCmdBuf* cmd); 56 | void vkrTexTable_ComputeSampleAll(vkrCmdBuf* cmd); 57 | void vkrTexTable_ComputeLoadStoreAll(vkrCmdBuf* cmd); 58 | 59 | PIM_C_END 60 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_texture.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "rendering/vulkan/vkr.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | i32 vkrFormatToBpp(VkFormat format); 8 | 9 | i32 vkrTexture_MipCount(i32 width, i32 height, i32 depth); 10 | 11 | bool vkrTexture_New( 12 | vkrImage *const image, 13 | VkImageViewType viewType, 14 | VkFormat format, 15 | i32 width, 16 | i32 height, 17 | i32 depth, 18 | i32 layers, 19 | bool mips); 20 | void vkrTexture_Release(vkrImage *const image); 21 | 22 | void vkrTexture_Upload( 23 | vkrImage *const image, 24 | i32 layer, 25 | void const *const data, 26 | i32 bytes); 27 | 28 | PIM_C_END 29 | -------------------------------------------------------------------------------- /src/rendering/vulkan/vkr_uipass.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "rendering/vulkan/vkr.h" 4 | 5 | PIM_C_BEGIN 6 | 7 | bool vkrUIPass_New(void); 8 | void vkrUIPass_Del(void); 9 | 10 | void vkrUIPass_Setup(void); 11 | void vkrUIPass_Execute(void); 12 | 13 | PIM_C_END 14 | -------------------------------------------------------------------------------- /src/scriptsys/scr_cmd.c: -------------------------------------------------------------------------------- 1 | #include "scriptsys/scr_cmd.h" 2 | 3 | #include "scriptsys/script.h" 4 | 5 | #include "common/console.h" 6 | #include "common/cmd.h" 7 | #include "common/stringutil.h" 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | // ---------------------------------------------------------------------------- 14 | 15 | static i32 scr_func_exec(lua_State* L); 16 | 17 | static cmdstat_t scr_cmd_exec(i32 argc, const char** argv); 18 | static cmdstat_t scr_cmd_eval(i32 argc, const char** argv); 19 | 20 | // ---------------------------------------------------------------------------- 21 | 22 | static const luaL_Reg ms_regs[] = 23 | { 24 | {.name = "exec",.func = scr_func_exec }, 25 | {0}, 26 | }; 27 | 28 | // ---------------------------------------------------------------------------- 29 | 30 | void scr_cmd_init(lua_State* L) 31 | { 32 | cmd_reg("script_exec", "