From 133a1b294d55babaf5986b89e927ff2cdbc0bde0 Mon Sep 17 00:00:00 2001 From: Matthew Date: Sun, 18 May 2025 06:47:28 +1000 Subject: [PATCH] fixed windows build --- build.bat | 54 +++++++--- build.ps1 | 135 +++++++++++++++++++++++ build.sh | 9 +- src/entry_linux.c | 3 +- src/entry_windows.c | 31 +++--- src/entry_windows.h | 6 +- src/packer.c | 30 ++++-- src/packer.h | 2 +- src/platform/platform.h | 59 +++++----- src/platform/platform_linux.c | 34 ++++++ src/platform/platform_linux.h | 7 ++ src/platform/platform_linux_public.c | 27 +---- src/platform/platform_windows.c | 66 +----------- src/platform/platform_windows.h | 12 ++- src/platform/platform_windows_public.c | 144 +++++++++++++++++++++++++ src/renderer.c | 7 -- src/renderer.h | 9 -- src/renderer_vulkan.c | 132 +++++++++-------------- src/renderer_vulkan.h | 30 ++---- src/renderer_vulkan_public.c | 27 ++--- src/util.c | 22 +++- src/util.h | 1 + 22 files changed, 545 insertions(+), 302 deletions(-) create mode 100644 build.ps1 diff --git a/build.bat b/build.bat index 69aa6b2..3f634ed 100644 --- a/build.bat +++ b/build.bat @@ -19,24 +19,23 @@ if "%msvc%"=="1" ( exit /b 1 ) -if "%vulkan%"=="1" echo test if "%vulkan%"=="1" set clang_renderer_flag=-DSTG_VULKAN_RENDERER set vulkan_include=C:\VulkanSDK\1.4.304.1\Include set out_name=Gears.exe -echo %clang_renderer_flag% - +:: clang set clang_out=-o set clang_compiler=clang set clang_include=-I..\src\ -I..\external\ -I%vulkan_include% set clang_src=..\src\entry_windows.c .\vma.o set clang_link=-luser32 -lkernel32 -lGdi32 -set clang_common=-fuse-ld=lld-link %clang_include% %clang_link% %clang_renderer_flag% --target=x86_64-pc-windows-msvc -ferror-limit=50 -std=c99 -D_USE_MATH_DEFINES -Xclang -flto-visibility-public-std -Wno-unknown-warning-option -fdiagnostics-absolute-paths -Wall -Wno-missing-braces -Wno-unused-function -Wno-writable-strings -Wno-unused-value -Wno-unused-variable -Wno-unused-local-typedef -Wno-deprecated-register -Wno-deprecated-declarations -Wno-microsoft-enum-forward-reference -Wno-unused-but-set-variable -Wno-single-bit-bitfield-constant-conversion -Wno-compare-distinct-pointer-types -Wno-initializer-overrides -Wno-incompatible-pointer-types-discards-qualifiers -Wno-for-loop-analysis -set clang_debug=%clang_compiler% %clang_src% -g -O0 -DBUILD_DEBUG=1 %clang_common% -set clang_release=%clang_compiler% %clang_src% -O2 %clang_common% +set clang_common=-fuse-ld=lld-link %clang_include% %clang_link% %clang_renderer_flag% -Wl --target=x86_64-pc-windows-msvc -ferror-limit=50 -std=c23 -DCOMPILER_CLANG -D_USE_MATH_DEFINES -Xclang -flto-visibility-public-std -Wno-unknown-warning-option -fdiagnostics-absolute-paths -Wall -Wno-missing-braces -Wno-unused-function -Wno-writable-strings -Wno-unused-value -Wno-unused-variable -Wno-unused-local-typedef -Wno-deprecated-register -Wno-deprecated-declarations -Wno-microsoft-enum-forward-reference -Wno-unused-but-set-variable -Wno-single-bit-bitfield-constant-conversion -Wno-compare-distinct-pointer-types -Wno-initializer-overrides -Wno-incompatible-pointer-types-discards-qualifiers -Wno-for-loop-analysis -Wno-nullability-completeness +set clang_debug=%clang_compiler% %clang_src% -g -O0 -DBUILD_DEBUG=1 %clang_common% -o %out_name% +set clang_release=%clang_compiler% %clang_src% -O2 %clang_common% -o %out_name% +:: clang - vma set vma_obj=vma.obj set clang_vma_compiler=clang++ set clang_vma_include=-I..\external\vma\ @@ -44,11 +43,17 @@ set clang_vma_common=%clang_vma_include% -Wl --target=x86_64-pc-windows-msvc -fu set clang_vma_debug=%clang_vma_compiler% ..\external\vma\vma.cpp -g -O0 %clang_vma_common% set clang_vma_release=%clang_vma_compiler% -O2 %clang_vma_common% +:: clang - packer +set packer_src=..\src\packer.c .\vma.o +set packer_include=-I..\src -I..\external +set packer_name=Packer.exe +set packer_debug=%clang_compiler% %packer_src% -g -O0 -DBUILD_DEBUG=1 %clang_common% -o %packer_name% + if "%clang%"=="1" set compile_debug=%clang_debug% if "%clang%"=="1" set compile_release=%clang_release% if "%clang%"=="1" set compile_vma_debug=%clang_vma_debug% if "%clang%"=="1" set compile_vma_release=%clang_vma_release% -if "%clang%"=="1" set out=%clang_out% +if "%clang%"=="1" set compile_packer_debug=%packer_debug% if "%debug%"=="1" set compile=%compile_debug% if "%debug%"=="1" set compile_vma=%compile_vma_debug% @@ -60,12 +65,35 @@ set vma_src=..\external\vma\vma.cpp set game_src=..\src\entry_windows.c set vma_obj=.\vma.obj -if not exist ".\build" mkdir build +if not exist "..\assets.sgp" ( + echo "">..\assets.sgp +) + pushd build -echo vma -%compile_vma% -echo game -echo %compile% -%compile% +if not exist ".\%packer_name%" ( + %compile_packer_debug% +) + +if "%vulkan%"=="1" ( + if not exist ".\shaders" mkdir shaders + if not exist ".\shaders\glsl" mkdir glsl + + for %%i in ("..\src\shaders\glsl\*") do ( + set base_name = %%~ni + set ext = %%~xbase_name + set out = "-o.\shaders\glsl\%%~ni.spv" + + if "%%i" NEQ "..\src\shaders\glsl\structures.glsl" ( + echo glslc --target-spv=spv1.6 -std=460 -fshader-stage=%ext% %i + ) + ) +) + + +::.\%packer_name% + +::if not exist ".\build" mkdir build +::%compile_vma% +::%compile% popd diff --git a/build.ps1 b/build.ps1 new file mode 100644 index 0000000..3764020 --- /dev/null +++ b/build.ps1 @@ -0,0 +1,135 @@ +foreach ($arg in $args) +{ + if ($arg -eq "clang") { $Global:clang = $true } + if ($arg -eq "msvc") { $Global:msvc = $true } + if ($arg -eq "vulkan") { $Global:vulkan = $true } + if ($arg -eq "pack") { $Global:pack = $true } + if ($arg -eq "packer") { $Global:packer = $true } + if ($arg -eq "debug") { $Global:debug = $true } + if ($arg -eq "release") { $Global:release = $true } +} + +if ($Global:vulkan -ne $true) { $Global:vulkan = $true } +if ($Global:clang -ne $true -and $Global:msvc -ne $true) { $Global:clang = $true } +if ($Global:debug -ne $true -and $Global:release -ne $true) { $Global:debug = $true } + +if ($Global:vulkan) { $Global:render_flag = "-DSTG_VULKAN_RENDERER" } + +$out_name = "Gears.exe" +$source_files = "..\src\entry_windows.c .\vma.o" + +$vulkan_include="C:\VulkanSDK\1.4.304.1\Include" + +$clang_out = "-o" +$clang_compiler = "clang" +$clang_includes = "-I..\src\ -I..\external\ -I$($vulkan_include)" +$clang_link = "-luser32 -lkernel32 -lGdi32" +$clang_common = "$($clang_includes) $($Global:render_flag) $($clang_link) -fuse-ld=lld-link --target=x86_64-pc-windows-msvc -DCOMPILER_CLANG -std=c23 -Xclang -flto-visibility-public-std -Wno-unknown-warning-option -fdiagnostics-absolute-paths -Wall -Wno-missing-braces -Wno-unused-function -Wno-writable-strings -Wno-unused-value -Wno-unused-variable -Wno-unused-local-typedef -Wno-deprecated-register -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wno-single-bit-bitfield-constant-conversion -Wno-compare-distinct-pointer-types -Wno-initializer-overrides -Wmicrosoft-enum-forward-reference -Wno-nullability-completeness -Wno-for-loop-analysis -DVMA_STATIC_VULKAN_FUNCTIONS=0 -ferror-limit=60" +$clang_debug = "$($clang_compiler) -g -O2 -DBUILD_DEBUG $($source_files) $($clang_common) $($clang_out) $($out_name)" +$clang_release = "$($clang_compiler) -O2 $($source_files) $($clang_common) $($clang_out) $($out_name)" +$clang_test = "$($clang_compiler) -O2 -DBUILD_TEST $($clang_common) $($clang_out) $($out_name)" + +$vma_out_name = "vma.o" +$clang_vma_compiler = "clang++" +$clang_vma_includes = "-I..\external\vma\" +$clang_vma_common = "$($clang_vma_includes) -Wl --target=x86_64-pc-windows-msvc -fuse-ld=lld-link -Wno-everything -D_USE_MATH_DEFINES -c -std=c++20 -I$($vulkan_include)" +$clang_vma_debug = "$($clang_vma_compiler) ..\external\vma\vma.cpp -g -O0 $($clang_vma_common) $($clang_out) $($vma_out_name)" +$clang_vma_release = "$($clang_vma_compiler) ..\external\vma\vma.cpp -O2 $($clang_vma_common) $($clang_out) $($vma_out_name)" + +$packer_src = "..\src\packer.c .\vma.o" +$packer_out_name = "Packer.exe" +$clang_packer_include = "-I..\src\ -I..\external\" +$clang_packer_debug = "$($clang_compiler) $($packer_src) -g -O0 -DBUILD_DEBUG=1 $($clang_common) $($clang_out) $($packer_out_name)" +$clang_packer_release = "$($clang_compiler) $($packer_src) -O2 -DBUILD_DEBUG=1 $($clang_common) $($clang_out) $($packer_out_name)" + +if ($Global:clang) +{ + $Global:compile_debug = $clang_debug + $Global:compile_release = $clang_release + $Global:compile_vma_debug = $clang_vma_debug + $Global:compile_vma_release = $clang_vma_release + $Global:compile_packer_debug = $clang_packer_debug + $Global:compile_packer_release = $clang_packer_release +} + +if ($Global:release) +{ + $Global:compile = $Global:compile_release + $Global:compile_vma = $Global:compile_vma_release + $Global:compile_packer = $Global:compile_packer_release +} + +if ($Global:debug) +{ + $Global:compile = $Global:compile_debug + $Global:compile_vma = $Global:compile_vma_debug + $Global:compile_packer = $Global:compile_packer_debug +} + +if (-not (Test-Path -Path ".\build" -PathType "Container")) +{ + New-Item -Path . -Name "build" -ItemType "Directory" +} + +Push-Location build + +if (-not (Test-Path -Path ".\assets.sgp" -PathType "Leaf")) +{ + New-Item -Path . -Name "assets.sgp" -ItemType "File" +} + +if (-not (Test-Path -Path ".\Packer.exe" -PathType "Leaf") -or $Global:packer) +{ + Invoke-Expression "$($Global:compile_packer)" +} + +if ($Global:vulkan) +{ + if (-not (Test-Path -Path ".\shaders" -PathType "Container")) + { + New-Item -Path . -Name "shaders" -ItemType "Container" + } + + if (-not (Test-Path -Path ".\shaders\glsl" -PathType "Container")) + { + New-Item -Path ".\shaders" -Name "glsl" -ItemType "Container" + } + + $glslc = "glslc" + $glslc_flags = "--target-spv=spv1.6 -std=460" + $glslc_out = "-o.\shaders\glsl\" + + $shader_files = Get-ChildItem "..\src\shaders\glsl\*.*.glsl" + foreach ($file in $shader_files) + { + $stage = "" + switch -Wildcard ($file.Name) + { + "*.vert.glsl" { $stage = "-fshader-stage=vert"; break } + "*.frag.glsl" { $stage = "-fshader-stage=frag"; break } + "*.tesc.glsl" { $stage = "-fshader-stage=tesc"; break } + "*.tese.glsl" { $stage = "-fshader-stage=tese"; break } + "*.geom.glsl" { $stage = "-fshader-stage=geom"; break } + "*.comp.glsl" { $stage = "-fshader-stage=comp"; break } + default { continue } + } + + Invoke-Expression "$($glslc) $($glslc_flags) $($stage) $($file.FullName) $($glslc_out)$($file.BaseName).spv" + } +} + +if ($Global:pack) +{ + Pop-Location + Invoke-Expression ".\build\$($packer_out_name)" + Push-Location build +} + +if (-not (Test-Path -Path ".\$($vma_out_name)" -PathType "Leaf")) +{ + Invoke-Expression "$($Global:compile_vma)" +} + +Invoke-Expression "$($Global:compile)" + +Pop-Location diff --git a/build.sh b/build.sh index f7600db..8ae476b 100755 --- a/build.sh +++ b/build.sh @@ -8,13 +8,9 @@ if [ -v debug ]; then echo "[debug mode]"; fi if [ -v release ]; then echo "[release mode]"; fi if [ -v gcc ]; then compiler="${CC:-gcc}"; cpp_compiler="g++"; echo "[gcc compiler]"; fi if [ -v clang ]; then compiler="${CC:-clang}"; cpp_compiler="clang++"; echo "[clang compiler]"; fi -if [ ! -v vulkan ] && [ ! -v dx11 ]; then vulkan=1; fi +if [ ! -v vulkan ] then vulkan=1; fi if [ -v vulkan ]; then render_flag="-DSTG_VULKAN_RENDERER"; fi if [ -v vulkan ]; then render_link="-lvulkan -l:libvma.a"; echo "[vulkan renderer]"; fi -if [ -v opengl ] && [ ! -v render_flag ]; then render_flag="-DSTG_OPENGL_RENDERER"; echo "[opengl renderer]"; fi -if [ -v webgl ] && [ ! -v render_flag ]; then render_flag="-DSTG_WEBGL_RENDERER"; echo "[webgl renderer]"; fi -if [ -v dx11 ] && [ ! -v render_flag ]; then render_flag="-DSTG_DX11_RENDERER"; echo "[dx11 renderer]"; fi -if [ -v dx11 ]; then render_link="-l:libdxvk_d3d11.so.0"; fi if [ ! -v render_flag ]; then render_flag="-DSTG_VULKAN_RENDERER"; vulkan="vulkan"; echo "[default renderer - vulkan]"; fi if [ -v test ]; then test_build=1; echo "[test build]"; fi @@ -47,6 +43,7 @@ glsl_stage_geom="-fshader-stage=geom" glsl_stage_comp="-fshader-stage=comp" glsl_out="-o./shaders/glsl/" +# clang clang_common="${include_flags} ${render_flag} -DCOMPILER_CLANG -std=c23 -fuse-ld=mold -Xclang -flto-visibility-public-std -Wno-unknown-warning-option -fdiagnostics-absolute-paths -Wall -Wno-missing-braces -Wno-unused-function -Wno-writable-strings -Wno-unused-value -Wno-unused-variable -Wno-unused-local-typedef -Wno-deprecated-register -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wno-single-bit-bitfield-constant-conversion -Wno-compare-distinct-pointer-types -Wno-initializer-overrides -Wno-for-loop-analysis -DVMA_STATIC_VULKAN_FUNCTIONS=0 -ferror-limit=60" clang_debug="$compiler -g -O0 -DBUILD_DEBUG=1 ${clang_common}" clang_release="$compiler -O2 ${clang_common}" @@ -54,6 +51,7 @@ clang_test="$compiler -O2 -DBUILD_TEST=1 ${clang_common}" clang_link="-lpthread -lm -lrt -ldl ${render_link} -lstdc++" clang_out="-o" +# gcc gcc_common="${include_flags} ${render_flag} -DCOMPILER_GCC -std=c23 -fuse-ld=mold -g -Wno-unknown-warning-option -Wall -Wno-missing-braces -Wno-unused-function -Wno-attributes -Wno-unused-value -Wno-unused-variable -Wno-unused-local-typedef -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wno-compare-distinct-pointer-types -D_USE_MATH_DEFINES -Dstrdup=_strdup -Dgnu_printf=printf -DVMA_STATIC_VULKAN_FUNCTIONS=0 -fzero-init-padding-bits=unions" gcc_debug="$compiler -g -O0 -DBUILD_DEBUG=1 ${gcc_common}" gcc_release="$compiler -O2 ${gcc_common} ${render_flag}" @@ -61,6 +59,7 @@ gcc_test="$compiler -O0 -DBUILD_TEST=1 ${gcc_common} ${render_flag}" gcc_link="-lpthread -lm -lrt -ldl ${render_link} -lstdc++" gcc_out="-o" +# linking link_dll="-fPIC" link_os_gfx="-lxcb -lX11 -lX11-xcb -lvulkan" diff --git a/src/entry_linux.c b/src/entry_linux.c index 4964372..b8854aa 100644 --- a/src/entry_linux.c +++ b/src/entry_linux.c @@ -45,13 +45,14 @@ void Traverse(RBTree *tree) int main(int argc, char **argv) { #ifdef BUILD_TEST +{ RunTests(); return 0; +} #endif Arena *arena = ArenaCreateDebug(MB(32), __LINE__); - Arena *game_arena = ArenaCreateDebug(MB(16), __LINE__); Assert(pWindowInit(WINDOW_NAME), "Failed to initialize the window"); diff --git a/src/entry_windows.c b/src/entry_windows.c index 406136d..dbbd6c3 100644 --- a/src/entry_windows.c +++ b/src/entry_windows.c @@ -2,10 +2,15 @@ #include "entry_windows.h" +// ::Entry::Windows::ThirdParty::Include:: + +#include "xxhash/xxhash.c" +#include "fastlz/fastlz.c" + #include "platform/platform.c" -#include "ds.c" -#include "assets.c" #include "util.c" +#include "assets.c" +#include "ds.c" #include "allocators.c" #include "renderer.c" #include "game.c" @@ -20,29 +25,29 @@ int CALLBACK WinMain(HINSTANCE instance, HINSTANCE prev_instance, LPSTR cmd_line } #endif - u8 *mem = (u8 *)pMemAllocZeroed(MB(32)); - Arena *arena = ArenaInitDebug(mem, MB(32), 1); +#ifdef BUILD_TEST + { + RunTests(); - isize renderer_mem_size = MB(16); - isize game_mem_size = MB(16); + return 0; + } +#endif - rawptr renderer_mem = ArenaAlloc(arena, renderer_mem_size); - Arena *renderer_arena = ArenaInitDebug(renderer_mem, renderer_mem_size, 2); - - rawptr game_mem = ArenaAlloc(arena, game_mem_size); - Arena *game_arena = ArenaInitDebug(game_mem, game_mem_size, 3); + Arena *arena = ArenaCreateDebug(MB(32), __LINE__); Assert(pWindowInit(WINDOW_NAME), "Failed to initialize window"); pGameInput *inputs = MakeArray(arena, pGameInput, 10); u32 i_count = 0; + + gGameCtx ctx = {0}; - gInit(renderer_arena); + gInit(&ctx); while (!global_quit) { pWindowEventsGet(); - gRunCycle(game_arena, inputs, i_count); + gRunCycle(&ctx, inputs, i_count); } gDestroy(); diff --git a/src/entry_windows.h b/src/entry_windows.h index 746a951..08ab064 100644 --- a/src/entry_windows.h +++ b/src/entry_windows.h @@ -14,10 +14,10 @@ #include "fastlz/fastlz.h" #include "shared_types.h" -#include "ds.h" -#include "assets.h" -#include "platform/platform.h" #include "util.h" +#include "assets.h" +#include "ds.h" +#include "platform/platform.h" #include "allocators.h" #include "renderer.h" #include "game.h" diff --git a/src/packer.c b/src/packer.c index ace35ef..dbb4302 100644 --- a/src/packer.c +++ b/src/packer.c @@ -13,6 +13,10 @@ #include "renderer.c" #include "game.c" +#ifdef _WIN32 +# include +#endif + // ::Packer::Includes::CFiles::End:: @@ -65,15 +69,16 @@ u64 ReadData(void *buf, u64 pos, u64 size, FILE *file) return FRead(buf, size, 1, file); } -FILE *OpenFile(c8 *name, c8 *mode) +FILE *pOpenFile(c8 *name, c8 *mode) { FILE *file = fopen(name, mode); - Assert(file != NULL, "OpenFile: file is null"); + Assert(file != NULL, "pOpenFile: file is null"); return file; } void CloseFile(FILE *file) { + fflush(file); Assert(fclose(file) != EOF, "Error closing file"); } @@ -119,12 +124,12 @@ void MoveToShaderDir(c8 **return_dir) { if (pDirIsVisible("build")) { - Assert(pDirNavigate("./build/shaders/glsl") == 0, "Unable to change to shader directory"); + Assert(pDirNavigate("build/shaders/glsl") == 0, "Unable to change to shader directory"); *return_dir = "../../.."; } else if (pDirIsVisible("shaders")) { - Assert(pDirNavigate("./shaders/glsl") == 0 , "Unable to change to shader directory"); + Assert(pDirNavigate("shaders/glsl") == 0 , "Unable to change to shader directory"); *return_dir = "../.."; } else @@ -190,7 +195,7 @@ void InitHeader(FileHeader *header) void PackFiles(Arena *arena, FileHeader *header) { - FILE *file = OpenFile("assets.sgp", "w+"); + FILE *file = pOpenFile("assets.sgp", "w+"); u64 file_pos = WriteData(header, 0, sizeof(FileHeader), file); @@ -217,7 +222,7 @@ void PackFiles(Arena *arena, FileHeader *header) Printfln("Packing file: %s...", asset_name); - FILE *asset_file = OpenFile(asset_name, "r"); + FILE *asset_file = pOpenFile(asset_name, "r"); u64 file_size = FileLength(asset_file); u8 *file_data = MakeArray(arena, u8, file_size); @@ -244,7 +249,7 @@ void PackFiles(Arena *arena, FileHeader *header) Printfln("Packing file: %s...", asset_name); - FILE *asset_file = OpenFile(asset_name, "r"); + FILE *asset_file = pOpenFile(asset_name, "r"); u64 file_size = FileLength(asset_file); u8 *file_data = MakeArray(arena, u8, file_size); @@ -253,6 +258,7 @@ void PackFiles(Arena *arena, FileHeader *header) int ch = 4; int w, h, has_ch; u8 *image_bytes = stbi_load_from_memory(file_data, file_size, &w, &h, &has_ch, ch); + Assert(w > 0 && h > 0 && has_ch > 0, "stbi_load_from_memory failure"); u64 loaded_length = u64(w * h * ch); @@ -286,7 +292,7 @@ void PackFiles(Arena *arena, FileHeader *header) static inline void TestAssetIsCorrect(Arena *arena, c8 *file_name, AssetFile *file_info, AssetType type, FILE *file) { - FILE *asset_file = OpenFile(file_name, "r"); + FILE *asset_file = pOpenFile(file_name, "r"); u64 size = FileLength(asset_file); @@ -330,7 +336,7 @@ static inline void TestAssetIsCorrect(Arena *arena, c8 *file_name, AssetFile *fi void TestAssetPack(Arena *arena) { - FILE *file = OpenFile("assets.sgp", "r"); + FILE *file = pOpenFile("assets.sgp", "r"); FileHeader header; i64 offset = FRead(&header, sizeof(FileHeader), 1, file); @@ -393,6 +399,12 @@ void TestAssetPack(Arena *arena) int main(int argc, c8 **argv) { + #ifdef _WIN32 + { + _set_fmode(_O_BINARY); + } + #endif + SetArrayLookups(); void *mem = pMemAllocZeroed(GB(1)); diff --git a/src/packer.h b/src/packer.h index 8df4299..c5621fb 100644 --- a/src/packer.h +++ b/src/packer.h @@ -45,7 +45,7 @@ typedef struct FileMapping // ::Packer::Files::Functions::Header:: -FILE *OpenFile(c8 *name, c8 *mode); +FILE *pOpenFile(c8 *name, c8 *mode); void CloseFile(FILE *file); u64 FileLength(FILE *file); u64 WriteData(void *buf, u64 pos, u64 size, FILE *file); diff --git a/src/platform/platform.h b/src/platform/platform.h index 09eeaa0..072e47f 100644 --- a/src/platform/platform.h +++ b/src/platform/platform.h @@ -7,29 +7,8 @@ typedef struct pFunction pFunction; // ::Platform::Declarations::Header:: -typedef enum KeyboardInput_e pKeyboardInput; typedef struct pGameInput pGameInput; -// ::Platform::Includes::Header:: - -#if __linux__ -#include "platform/platform_linux.h" -#endif - -#if _WIN32 -#include "platform/platform_windows.h" -#endif - -#if __APPLE__ || __MACH__ -#error Not yet implemented -#endif - -#if __unix__ && !__linux__ -#error Not yet implemented -#endif - -// ::Platform::Enum::Header:: - typedef enum KeyboardInput_e { KB_NONE, @@ -53,6 +32,26 @@ typedef enum KeyboardInput_e KB_MAX } pKeyboardInput; +// ::Platform::Includes::Header:: + +#if __linux__ +#include "platform/platform_linux.h" +#endif + +#if _WIN32 +#include "platform/platform_windows.h" +#endif + +#if __APPLE__ || __MACH__ +#error Not yet implemented +#endif + +#if __unix__ && !__linux__ +#error Not yet implemented +#endif + +// ::Platform::Enum::Header:: + typedef enum MouseInput_e { M_NONE, @@ -89,6 +88,8 @@ typedef struct pGameInput pGameInputType type; } pGameInput; // TODO: add gamepad input +typedef struct pThread pThread; + // ::Platform::ConsoleOut::Functions::Header:: i32 pWriteStdOut(void *buf, i32 len); @@ -114,15 +115,11 @@ pWindowSize pWindowGetSize(); b32 pWindowShouldQuit(); pPlatformWindow *pWindowGet(); -// ::Platform::SystemInfo::Functions::Header:: - -u32 pCPUCountGet(); - // ::Platform::FileSystem::Functions::Header:: b32 pDirNavigate(c8 *dir); c8 **pDirGetFileNames(Arena *arena, u32 *count); -b8 pDirIsVisible(c8 *dir_name); +static b8 pDirIsVisible(c8 *dir_name); // ::Platform::Profiling::Functions::Header:: @@ -130,15 +127,21 @@ static u64 pOSTimerFreq(); static u64 pOSTimerRead(); static inline u64 pCPUTimerRead(); +// ::Platform::Async::Functions::Header:: + +static pThread pThreadInit(rawptr proc, rawptr param); +static void pThreadSuspend(pThread *thread); +static void pThreadWake(pThread *thread); +static void pThreadKill(); + // ::Platform::Atomics::Header:: static inline void pAtomicSignalFenceSeqCst(); -static inline u8 pAtomicFetchSubU8(u8 volatile *ptr, u8 count); static inline u32 pAtomicFetchSubU32(u32 volatile *ptr, u32 count); static inline u32 pAtomicFetchIncrU32(u32 volatile *ptr); static inline void pAtomicIncrU8(u8 volatile *ptr); static inline void pAtomicIncrU32(u32 volatile *ptr); -static inline u32 AtomicLoadU32(u32 volatile *ptr); +static inline u32 pAtomicLoadU32(u32 volatile *ptr); static inline void pAtomicStoreB32(b32 volatile *ptr, b32 value); static inline b32 pAtomicCompareExchangeB32(b32 volatile *ptr, b32 *expect, b32 desired); diff --git a/src/platform/platform_linux.c b/src/platform/platform_linux.c index 79924a6..4e7c9ba 100644 --- a/src/platform/platform_linux.c +++ b/src/platform/platform_linux.c @@ -296,6 +296,40 @@ b32 pSyscallErrCheck(void *ptr) +// ::Platform::Linux::Async::Start:: + +static pThread pThreadInit(pThreadProc proc, rawptr param) +{ + pThread thread = {0}; + pthread_mutex_init(&thread.mut, NULL); + pthread_create(&thread.handle, NULL, proc, param); + + return thread; +} + +static void pThreadSuspend(pThread *thread) +{ + pthread_mutex_lock(&thread->mut); + pthread_cond_wait(&thread->cond, &thread->mut); + pthread_mutex_unlock(&thread->mut); +} + +static void pThreadWake(pThread *thread) +{ + pthread_cond_signal(&thread->cond); +} + +static void pThreadKill() +{ + pthread_exit(NULL); +} + +// ::Platform::Linux::Async::Start:: + + + // ::Platform::Linux::Includes::CFile:: #include "platform_linux_public.c" + + diff --git a/src/platform/platform_linux.h b/src/platform/platform_linux.h index f18c685..356025f 100644 --- a/src/platform/platform_linux.h +++ b/src/platform/platform_linux.h @@ -52,6 +52,13 @@ // ::Platform::Linux::Types::Header +typedef struct pThread +{ + pthread_t handle; + pthread_cond_t cond; + pthread_mutex_t mut; +} pThread; + typedef struct pPlatformWindow { Display *display; diff --git a/src/platform/platform_linux_public.c b/src/platform/platform_linux_public.c index 8941516..1e7f18f 100644 --- a/src/platform/platform_linux_public.c +++ b/src/platform/platform_linux_public.c @@ -225,19 +225,6 @@ b32 pWindowShouldQuit() -// ::Platform::Functions::SystemInfo::Start:: - -u32 pCPUCountGet() -{ - cpu_set_t cpu_set; - sched_getaffinity(0, sizeof(cpu_set), &cpu_set); - return CPU_COUNT(&cpu_set); -} - -// ::Platform::Functions::SystemInfo::StarEnd:: - - - // ::Platform::Functions::Directory::Start:: b32 pDirNavigate(c8 *dir) @@ -282,7 +269,7 @@ c8 **pDirGetFileNames(Arena *arena, u32 *count) return (c8 **)file_names; } -b8 pDirIsVisible(c8 *dir_name) +static b8 pDirIsVisible(c8 *dir_name) { b8 found = false; @@ -339,11 +326,6 @@ static inline void pAtomicSignalFenceSeqCst() __atomic_signal_fence(__ATOMIC_SEQ_CST); } -static inline u8 pAtomicFetchSubU8(u8 volatile *ptr, u8 count) -{ - return __atomic_fetch_sub(ptr, count, __ATOMIC_ACQUIRE); -} - static inline u32 pAtomicFetchSubU32(u32 volatile *ptr, u32 count) { return __atomic_fetch_sub(ptr, count, __ATOMIC_ACQUIRE); @@ -354,17 +336,12 @@ static inline u32 pAtomicFetchIncrU32(u32 volatile *ptr) return __atomic_fetch_add(ptr, (u32)1, __ATOMIC_ACQUIRE); } -static inline void pAtomicIncrU8(u8 volatile *ptr) -{ - __atomic_fetch_add(ptr, (u8)1, __ATOMIC_RELEASE); -} - static inline void pAtomicIncrU32(u32 volatile *ptr) { __atomic_fetch_add(ptr, (u32)1, __ATOMIC_RELEASE); } -static inline u32 AtomicLoadU32(u32 volatile *ptr) +static inline u32 pAtomicLoadU32(u32 volatile *ptr) { return __atomic_load_n(ptr, __ATOMIC_ACQUIRE); } diff --git a/src/platform/platform_windows.c b/src/platform/platform_windows.c index d375c44..02241c3 100644 --- a/src/platform/platform_windows.c +++ b/src/platform/platform_windows.c @@ -56,17 +56,7 @@ b32 pFunctionLoad(const char *name, pLibrary *lib, pFunction *out_fn) return success; } -rawptr pMemAlloc(isize size) -{ - return (rawptr)VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); -} - -rawptr pMemAllocZeroed(isize size) -{ - return _MemAlloc(size); -} - -isize pPageSize() +usize pPageSize() { return 0; } @@ -78,56 +68,6 @@ i32 _Write(void const *str, DWORD std_handle) return success ? (i32)written : -1; } -i32 _Printf(const char *fmt, va_list arg) -{ - char buffer[1024]; - - int sprf_res = stbsp_vsnprintf(&buffer[0], 1024, fmt, arg); - - i32 pr_res; - if (sprf_res < 0) - pr_res = sprf_res; - else - pr_res = _Write(buffer, STD_OUTPUT_HANDLE); - - return pr_res; -} - -i32 _Printfln(const char *fmt, va_list arg) -{ - char buffer[1024]; - - int sprf_res = stbsp_vsnprintf(&buffer[0], 1023, fmt, arg); - - i32 pr_res; - if (sprf_res < 0) - pr_res = sprf_res; - else - { - buffer[sprf_res] = '\n'; - buffer[sprf_res+1] = '\0'; - pr_res = _Write(&buffer, STD_OUTPUT_HANDLE); - } - - return pr_res; -} - -i32 _EPrint(void const *str) -{ - return _Write(str, STD_ERROR_HANDLE); -} - -i32 _EPrintf(const char *fmt, va_list arg) -{ - char buffer[1024]; - - int sprf_res = stbsp_vsnprintf(&buffer[0], 1024, fmt, arg); - - if (sprf_res < 0) return sprf_res; - - return EPrint(&buffer); -} - b32 pWindowInit(const char *window_name) { b32 success = true; @@ -211,3 +151,7 @@ pWindowSize pWindowGetSize() return (pWindowSize){ .w = win32_window.w, .h = win32_window.h }; } +// ::Platform::Windows::Includes::CFile:: + +#include "platform_windows_public.c" + diff --git a/src/platform/platform_windows.h b/src/platform/platform_windows.h index 22449ee..73eb7fd 100644 --- a/src/platform/platform_windows.h +++ b/src/platform/platform_windows.h @@ -3,6 +3,7 @@ #include #include #include +#include // ::Platform::Windows::Defines::Header:: @@ -23,16 +24,17 @@ typedef struct pLibrary HMODULE module; } pLibrary; -typedef struct +typedef struct pFunction { FARPROC fn; } pFunction; -// ::Platform::Windows::Functions::::Header:: +typedef struct pThread +{ + HANDLE handle; +} pThread; -rawptr _MemAlloc(isize size); -rawptr _MemAllocZeroed(isize size); -isize _GetPageSize(); +// ::Platform::Windows::Functions::::Header:: void pWindowEventsGet(); void pWindowEventWaitFor(); diff --git a/src/platform/platform_windows_public.c b/src/platform/platform_windows_public.c index e69de29..9fc3c4b 100644 --- a/src/platform/platform_windows_public.c +++ b/src/platform/platform_windows_public.c @@ -0,0 +1,144 @@ + +// ::Platform::Windows::Memory::Start:: + +rawptr pMemAlloc(usize size) +{ + return (rawptr)VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); +} + +rawptr pMemAllocZeroed(usize size) +{ + rawptr mem = pMemAlloc(size); + MemZero(mem, size); + return mem; +} + +void pMemFree(rawptr ptr, usize size) +{ + Assert(VirtualFree(ptr, size, MEM_RELEASE), "pMemFree failure"); +} + +// ::Platform::Windows::Memory::End:: + + + +// ::Platform::Windows::Print::Start:: + +i32 pWriteStdOut(rawptr buf, i32 len) +{ + return WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), buf, len, NULL, NULL); +} + +i32 pWriteStdErr(rawptr buf, i32 len) +{ + return WriteConsole(GetStdHandle(STD_ERROR_HANDLE), buf, len, NULL, NULL); +} + +// ::Platform::Windows::Print::End:: + + + +// ::Platform::Functions::Directory::Start:: + +b32 pDirNavigate(c8 *dir) +{ + return !(b32)SetCurrentDirectory(dir); +} + +// ::Platform::Functions::Directory::End:: + + + +// ::Platform::Windows::Profiling::Functions::Start:: + +static inline u64 pCPUTimerRead() +{ + return __rdtsc(); +} + +// ::Platform::Windows::Profiling::Functions::End:: + + + +// ::Platform::Windows::Async::Start:: + +static pThread pThreadInit(rawptr proc, rawptr param) +{ + pThread thread = {0}; + CreateThread(NULL, 0, proc, param, 0, NULL); + + return thread; +} + +static void pThreadSuspend(pThread *thread) +{ + SuspendThread(thread->handle); +} + +static void pThreadWake(pThread *thread) +{ + ResumeThread(thread->handle); +} + +static void pThreadKill() +{ + ExitThread(0); +} + +// ::Platform::Windows::Async::End:: + + + +// ::Platform::Windows::Atomics::Start:: + + +static inline void pAtomicSignalFenceSeqCst() +{ + _ReadWriteBarrier(); +} + +static inline u32 pAtomicFetchSubU32(u32 volatile *ptr, u32 count) +{ + LONG decrement = (LONG)count; + return (u32)InterlockedAddAcquire((LONG volatile *)ptr, -decrement) + decrement; +} + +static inline u32 pAtomicFetchIncrU32(u32 volatile *ptr) +{ + return (u32)InterlockedIncrementAcquire((LONG volatile *)ptr) - 1; +} + +static inline void pAtomicIncrU32(u32 volatile *ptr) +{ + InterlockedIncrementRelease((LONG volatile *)ptr); +} + +static inline u32 pAtomicLoadU32(u32 volatile *ptr) +{ + return (u32)InterlockedOrAcquire((LONG volatile *)ptr, 0); +} + +static inline void pAtomicStoreB32(b32 volatile *ptr, b32 value) +{ + _InterlockedExchange_HLERelease((LONG volatile *)ptr, (LONG)value); +} + +static inline b32 pAtomicCompareExchangeB32(b32 volatile *ptr, b32 *expect, b32 desired) +{ + return (b32)InterlockedCompareExchangeAcquire((LONG volatile *)ptr, (LONG)desired, (LONG)*expect); +} + +// ::Platform::Windows::Atomics::End:: + + + +// ::Platform::Windows::Files::Start:: + +static b8 pDirIsVisible(c8 *dir_name) +{ + WIN32_FIND_DATA find_data; + HANDLE handle; + return (handle = FindFirstFile(dir_name, &find_data)) != INVALID_HANDLE_VALUE; +} + +// ::Platform::Windows::Files::End:: diff --git a/src/renderer.c b/src/renderer.c index 081b2d3..e5f5c0b 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -2,13 +2,6 @@ #include "renderer_vulkan.c" #endif -#if STG_OPENGL_RENDERER -#error Not yet implemented -#endif - -#if STG_WEBGL_RENDERER -#error Not yet implemented -#endif #if STG_DX11_RENDERER && __linux__ #include "renderer_d3d11.c" diff --git a/src/renderer.h b/src/renderer.h index dec19c3..808ea2f 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -123,7 +123,6 @@ static void rPushConstantsSet(rPushConst *pc); // ::Renderer::Config::Header:: static void rResolutionSet(u32 x, u32 y); -static void rThreadCountSet(u32 n); // ::Renderer::Rendering::Header:: @@ -138,14 +137,6 @@ static void rPipelineBind(rPipelineHandle handle, rPipelineType type); #include "renderer_vulkan.h" #endif -#if STG_OPENGL_RENDERER -#error Not yet implemented -#endif - -#if STG_WEBGL_RENDERER -#error Not yet implemented -#endif - #if STG_DX11_RENDERER && __linux__ #include "renderer_d3d11.h" #endif diff --git a/src/renderer_vulkan.c b/src/renderer_vulkan.c index 0a363b7..e2457ca 100644 --- a/src/renderer_vulkan.c +++ b/src/renderer_vulkan.c @@ -82,12 +82,12 @@ static inline vBufferAllocPtrArray *vFrameBuffers() static inline b8 *vFrameTexDestroyQueue() { - return v_Renderer.buffers.tex_destroy_queue[vFrameIndex()]; + return v_Renderer.buffers.tex_destroy_queue.data[vFrameIndex()]; } static inline b8 *vFrameNextTexDestroyQueue() { - return v_Renderer.buffers.tex_destroy_queue[vFrameNextIndex()]; + return v_Renderer.buffers.tex_destroy_queue.data[vFrameNextIndex()]; } static inline void vImageCopyToImage(VkCommandBuffer cmd, VkImage src, VkImage dst, VkExtent2D src_ext, VkExtent2D dst_ext) @@ -666,7 +666,7 @@ static b32 vInitInstance() static b32 vRenderDocInit() { - pLibrary lib; pFunction fn; int result; + pLibrary lib; pFunction fn; int result = 0; b32 found = pLibraryLoad(RENDERDOC_LIB, &lib); if (found) @@ -996,10 +996,6 @@ static b32 vInstanceFunctionsInit() { INIT_INST_FN(vkCreateWin32SurfaceKHR); } - #elif __APPLE__ || __MACH__ - #error Not yet implemented - #elif __unix__ && !__linux__ - #error Not yet implemented #endif #ifdef BUILD_DEBUG @@ -1199,35 +1195,22 @@ static b32 vImmediateStructuresInit() b32 success = true; VkResult result; VkDevice device = v_Renderer.handles.device; - vImmHandlesArray *imm = &v_Renderer.imm_handles; + vImmHandles *imm = &v_Renderer.imm; pool_create_info.queueFamilyIndex = v_Renderer.state.vk.tfer_queue_idx; - - if (v_Renderer.async.count >= 4 && !v_Renderer.state.vk.single_queue) - v_Renderer.async.count = 1; - else - v_Renderer.async.count = 0; + result = vkCreateCommandPool(device, &pool_create_info, NULL, &imm->pool); + if (result != VK_SUCCESS) + success = false; - imm->data = MakeArray(v_Renderer.mem.perm_arena, vImmHandles, v_Renderer.async.count); - imm->length = v_Renderer.async.count; - imm->cap = v_Renderer.async.count; - - for (u32 i = 0; i < v_Renderer.async.count && success; i++) - { - result = vkCreateCommandPool(device, &pool_create_info, NULL, &imm->data[i].pool); - if (result != VK_SUCCESS) - success = false; + cmd_buf_info.commandPool = imm->pool; - cmd_buf_info.commandPool = imm->data[i].pool; + result = vkAllocateCommandBuffers(device, &cmd_buf_info, &imm->buffer); + if (result != VK_SUCCESS) + success = false; - result = vkAllocateCommandBuffers(device, &cmd_buf_info, &imm->data[i].buffer); - if (result != VK_SUCCESS) - success = false; - - result = vkCreateFence(device, &fence_create_info, NULL, &imm->data[i].fence); - if (result != VK_SUCCESS) - success = false; - } + result = vkCreateFence(device, &fence_create_info, NULL, &imm->fence); + if (result != VK_SUCCESS) + success = false; return success; } @@ -1649,13 +1632,16 @@ static b32 vBuffersInit() HashTableInit(&buf->buffers, 8); HashTableInit(&buf->images, 8); + buf->tex_destroy_queue.data = MakeArray(arena, b8 *, FRAME_OVERLAP); + buf->tex_destroy_queue.length = FRAME_OVERLAP; + for (u32 i = 0; i < FRAME_OVERLAP; i++) { InitArrayType(buf->frame_buffers[i], arena, vBufferAlloc *, 128); InitArrayType(buf->frame_images[i], arena, vImageView *, 128); - buf->tex_destroy_queue[i] = MakeArray(arena, b8, TEXTURE_ASSET_MAX); - MemZero(buf->tex_destroy_queue, sizeof(b8) * TEXTURE_ASSET_MAX); + buf->tex_destroy_queue.data[i] = MakeArray(arena, b8, TEXTURE_ASSET_MAX); + MemZero(buf->tex_destroy_queue.data[i], sizeof(b8) * TEXTURE_ASSET_MAX); } @@ -1693,40 +1679,22 @@ static b32 vBuffersInit() return success; } -#if __linux__ - static void vLoaderStartThreads() { - if (v_Renderer.async.count == 0) - return; - - u32 count = v_Renderer.async.count; - pthread_t *threads = ArenaAlloc(v_Renderer.mem.perm_arena, sizeof(pthread_t) * count); - - for (u32 i = 0; i < count; i++) - { - v_Renderer.async.thread_idx[i] = i; - pthread_create(&threads[i], NULL, vLoaderStart, &v_Renderer.async.thread_idx[i]); - } + v_Renderer.async.thread = pThreadInit(vLoaderStart, NULL); } -#elif _WIN32 - -# error Threading not yet implemented - -#endif - // ::Vulkan::Init::Functions::End:: // ::Vulkan::Async::Functions::Start:: -static void vTransferUpload(vTransfer **transfers, u32 count, u32 idx) +static void vTransferUpload(vTransfer **transfers, u32 count) { - VkCommandPool pool = v_Renderer.imm_handles.data[idx].pool; - VkCommandBuffer buffer = v_Renderer.imm_handles.data[idx].buffer; - VkFence fence = v_Renderer.imm_handles.data[idx].fence; + VkCommandPool pool = v_Renderer.imm.pool; + VkCommandBuffer buffer = v_Renderer.imm.buffer; + VkFence fence = v_Renderer.imm.fence; VkDevice device = v_Renderer.handles.device; VkQueue queue = v_Renderer.handles.tfer_queue; vMappedBuffer *transfer = &v_Renderer.buffers.transfer; @@ -1850,14 +1818,30 @@ static void vTransferUpload(vTransfer **transfers, u32 count, u32 idx) void *vLoaderStart(void *i) { - u32 index = *(u32 *)i; - pthread_t self = pthread_self(); - pthread_mutex_t mut; - pthread_mutex_init(&mut, NULL); + vLoader(); +} + +#elif _WIN32 + +DWORD WINAPI vLoaderStart(LPVOID thread_data) +{ + vLoader(); + return 0; +} + +#endif + +static void vLoaderWake() +{ + pThreadWake(&v_Renderer.async.thread); +} + +static void vLoader() +{ + pThread self = v_Renderer.async.thread; for (;;) { - TicketMutLock(&v_Renderer.upload.mut); u32 job_count = JobQueueGetCount(&v_Renderer.upload.job_queue); if (job_count > 0) @@ -1875,7 +1859,7 @@ void *vLoaderStart(void *i) TicketMutUnlock(&v_Renderer.upload.mut); - vTransferUpload(transfers, job_count, index); + vTransferUpload(transfers, job_count); for (u32 i = 0; i < job_count; i++) { @@ -1887,35 +1871,21 @@ void *vLoaderStart(void *i) } else if (job_count == 0) { - pAtomicIncrU8(&v_Renderer.async.sleeping); + pAtomicStoreB32(&v_Renderer.async.sleeping, 1); TicketMutUnlock(&v_Renderer.upload.mut); - pthread_mutex_lock(&mut); - pthread_cond_wait(&v_Renderer.async.cond, &mut); - pthread_mutex_unlock(&mut); - pAtomicFetchSubU8(&v_Renderer.async.sleeping, 1); + pThreadSuspend(&self); + pAtomicStoreB32(&v_Renderer.async.sleeping, 0); } else { TicketMutUnlock(&v_Renderer.upload.mut); - pthread_exit(NULL); + pThreadKill(); } } - pthread_exit(NULL); + pThreadKill(); } -static void vLoaderWake() -{ - for (u32 i = 0; i < v_Renderer.async.count; i++) - pthread_cond_signal(&v_Renderer.async.cond); -} - -#elif _WIN32 - -#error not yet implemented - -#endif - // ::Vulkan::Async::Functions::End:: diff --git a/src/renderer_vulkan.h b/src/renderer_vulkan.h index 58d4b79..803d16e 100644 --- a/src/renderer_vulkan.h +++ b/src/renderer_vulkan.h @@ -38,12 +38,6 @@ static char *vulkan_libs[] = { #endif -#if __unix__ && !__linux__ -#error Not yet implemented -#endif - -#define V_THREAD_MAX 1 - #define VERTEX_BUFFER_CAP MB(32) #define INDEX_BUFFER_CAP MB(8) #define TRANSFER_BUFFER_CAP MB(64) @@ -94,10 +88,6 @@ VK_DECLARE(vkGetPhysicalDeviceImageFormatProperties); VK_DECLARE(vkCreateXcbSurfaceKHR); #elif _WIN32 VK_DECLARE(vkCreateWin32SurfaceKHR); -#elif __APPLE__ || __MACH__ -#error Not yet implemented -#elif __unix__ && !__linux__ -#error Not yet implemented #endif @@ -238,6 +228,7 @@ typedef struct vImageView PtrArrayType(vImageView); ArrayType(vImageView); +PtrArrayType(b8); typedef struct vSampler { @@ -306,15 +297,9 @@ typedef struct vFrameHandles typedef struct vAsync { - u32 thread_idx[V_THREAD_MAX]; -#ifdef __linux__ - pthread_t threads[V_THREAD_MAX]; - pthread_cond_t cond; -#elif _WIN32 -# error not yet implemented -#endif - u8 count; - u8 sleeping; + u32 thread_idx; + b32 sleeping; + pThread thread; } vAsync; typedef struct vRHandles @@ -366,7 +351,7 @@ typedef struct vRBuffers HashTable images; vImageViewPtrArray frame_images[FRAME_OVERLAP]; - b8 *tex_destroy_queue[FRAME_OVERLAP]; + b8PtrArray tex_destroy_queue; vMappedBuffer transfer; vMappedBuffer gui_vert; @@ -420,7 +405,7 @@ typedef struct vRenderer vFrameHandles frame_handles[FRAME_OVERLAP]; vState state; vRBuffers buffers; - vImmHandlesArray imm_handles; + vImmHandles imm; vDescBindings desc_bindings[vDT_MAX]; vAsync async; vMemory mem; @@ -527,11 +512,12 @@ static inline void vImageCopyToImage(VkCommandBuffer cmd, VkImage src, VkImage d static void vBufferQueueWait(); static void vLoaderWake(); +static void vLoader(); #ifdef __linux__ void *vLoaderStart(void *thread_data); #elif _WIN32 -# error not yet implemented + DWORD WINAPI vLoaderStart(LPVOID thread_data); #endif // ::Vulkan::ImmediateSubmit::Functions::Header:: diff --git a/src/renderer_vulkan_public.c b/src/renderer_vulkan_public.c index ad04e5d..d0632c1 100644 --- a/src/renderer_vulkan_public.c +++ b/src/renderer_vulkan_public.c @@ -2,7 +2,6 @@ b32 rInit() { - rThreadCountSet(pCPUCountGet()); vArenasInit(); vCustomizePipelines(); @@ -12,7 +11,7 @@ b32 rInit() #ifdef BUILD_DEBUG { vEnableDebug(); - vRenderDocInit(); + //vRenderDocInit(); } #endif @@ -40,7 +39,7 @@ void rDestroy() VkDevice device = v_Renderer.handles.device; VkInstance instance = v_Renderer.handles.inst; vBufferAllocPtrArray *frame_buffers = v_Renderer.buffers.frame_buffers; - vImmHandlesArray imm = v_Renderer.imm_handles; + vImmHandles imm = v_Renderer.imm; VmaAllocator vma_alloc = v_Renderer.handles.vma_alloc; VkSwapchainKHR swapchain = v_Renderer.handles.swapchain; VkPipeline *pipelines = v_Renderer.handles.pipelines; @@ -68,14 +67,9 @@ void rDestroy() vSwapchainDestroy(); - for (u32 i = 0; i < async.count; i++) - { - vImmHandles ih = imm.data[i]; - - vkDestroyFence(device, ih.fence, NULL); - vkFreeCommandBuffers(device, ih.pool, 1, &ih.buffer); - vkDestroyCommandPool(device, ih.pool, NULL); - } + vkDestroyFence(device, imm.fence, NULL); + vkFreeCommandBuffers(device, imm.pool, 1, &imm.buffer); + vkDestroyCommandPool(device, imm.pool, NULL); for (u32 i = 0; i < FRAME_OVERLAP; i++) { @@ -221,7 +215,7 @@ static void vBufferQueueWait() { while (!JobQueueCompleted(&v_Renderer.upload.job_queue)) { - if (v_Renderer.async.sleeping > 0) + if (v_Renderer.async.sleeping) vLoaderWake(); } } @@ -305,11 +299,6 @@ static void rResolutionSet(u32 x, u32 y) v_Renderer.state.renderer.height = y; } -static void rThreadCountSet(u32 n) -{ - v_Renderer.async.count = n; -} - // ::Vulkan::Renderer::Config::Functions::End:: @@ -329,8 +318,10 @@ b32 rFrameBegin() VkSemaphore sc_sem = vFrameSwapSem(); VkSemaphore rndr_sem = vFrameRenderSem(); +#ifdef RDOC_ENABLED if (!v_rdoc_captured) v_rdoc_api->StartFrameCapture(device, pWindowGet()); +#endif // TODO(MA): make this work with VK_PRESENT_MODE_MAILBOX_KHR and remove assignment of present mode to FIFO result = vkWaitForFences(device, 1, &fence, VK_TRUE, 1000000000); @@ -499,10 +490,12 @@ b32 rFrameFinish() v_Renderer.state.renderer.frame_count += 1; +#ifdef RDOC_ENABLED if (!v_rdoc_captured) { v_rdoc_api->EndFrameCapture(v_Renderer.handles.device, pWindowGet()); } +#endif return success; } diff --git a/src/util.c b/src/util.c index ec56617..a41f399 100644 --- a/src/util.c +++ b/src/util.c @@ -8,6 +8,18 @@ static Profiler GLOBAL_PROFILER; // ::Util::Strings::Functions::Start:: +static void StrConcat(c8 *str, c8 *append) +{ + u32 len = StrLen(str); + u32 i = 0; + for (; append[i] != '\0'; i += 1) + { + str[i] = append[i]; + } + + str[i] = '\0'; +} + b32 StrEq(const char *l, const char *r) { for (; *l == *r && *l; l++, r++); return *l == '\0' && *r == '\0'; @@ -313,6 +325,12 @@ static inline void MutUnlock(Mut *mut) pAtomicStoreB32(&mut->lock, 0); } +static inline void TicketMutInit(TicketMut *mut) +{ + mut->ticket = 0; + mut->next_ticket = 1; +} + static inline void TicketMutLock(TicketMut *mut) { u32 ticket = pAtomicFetchIncrU32(&mut->ticket); @@ -334,7 +352,7 @@ static inline u32 JobQueueAdd(JobQueue *queue, u32 count) static inline u32 JobQueueGetCount(JobQueue *queue) { - return AtomicLoadU32(&queue->queued); + return pAtomicLoadU32(&queue->queued); } static inline void JobQueueMarkUnqueued(JobQueue *queue, u32 count) @@ -357,7 +375,7 @@ static inline void JobQueueReset(JobQueue *queue) static inline b32 JobQueueCompleted(JobQueue *queue) { - u32 remaining = AtomicLoadU32(&queue->remaining); + u32 remaining = pAtomicLoadU32(&queue->remaining); return remaining == 0; } diff --git a/src/util.h b/src/util.h index 4485f7d..392ed4a 100644 --- a/src/util.h +++ b/src/util.h @@ -154,6 +154,7 @@ b32 StrEq(const char *l, const char *r); i32 SPrintf(char *buf, rawptr fmt, ...); String8 PreSplitString8(String8 string, String8 delimiter); String8 PreSplitNewString8(Arena *arena, String8 string, String8 delimiter); +static void StrConcat(c8 *str, c8 *append); // ::Util::Memory::Functions::Header::