diff --git a/meson.build b/meson.build index 373fd5c..bd7404a 100644 --- a/meson.build +++ b/meson.build @@ -3,7 +3,7 @@ project('rtengine', ['c', 'cpp'], 'b_sanitize=address', 'c_std=c17', 'cpp_std=c++20', - 'warning_level=3', + 'warning_level=2', 'werror=true', 'b_vscrt=static_from_buildtype', 'default_library=static', @@ -51,6 +51,18 @@ if host_machine.system() == 'linux' add_project_arguments(['-D_GNU_SOURCE'], language : ['c', 'cpp']) endif + +# Handle Linux to Windows cross compilation. +# By default, mingw does not find its own windows headers... +if build_machine.system() == 'linux' and host_machine.system() == 'windows' + message('Adding /usr/share/mingw-w64/include to the project include path.') + add_project_arguments(['-isystem/usr/share/mingw-w64/include', + '-DRT_CROSS_LINUX_WINDOWS', + '-D_WIN32_WINNT=0x600'], + language: ['c', 'cpp'], + native: false) +endif + fs = import('fs') # Gather dependencies @@ -99,7 +111,7 @@ else endif # Unit/Integration test driver -# subdir('tests') +subdir('tests') # Declare dependencies, to enable using the engine as a subproject engine_dep = declare_dependency(link_with : engine_link_libs, @@ -120,3 +132,14 @@ if get_option('game_as_subdir') depends : engine_libs) endforeach endif + +# For Cross builds, we need libgcc from mingw +if build_machine.system() == 'linux' and host_machine.system() == 'windows' + custom_target('copy libgcc', + input : '/usr/lib/gcc/x86_64-w64-mingw32/10-win32/libgcc_s_seh-1.dll', + output : 'libgcc_s_seh-1.dll', + command : [copy_util, '@INPUT@', '@OUTPUT@'], + build_by_default : true) +endif + + diff --git a/meson_options.txt b/meson_options.txt index c0310be..1e38d23 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -4,4 +4,5 @@ option('error_report_debugbreak', type : 'boolean', value : true, description : option('enable_dxc_shader_compiler', type : 'boolean', value : true, description : 'Enables building the dxc-based shader compiler.') option('enable_dx11_shader_compiler', type : 'boolean', value : true, description : 'Enables building the dx11-bases shader compiler.') option('game_as_subdir', type : 'boolean', value : false, description : 'If true, adds the directory "src/game" to the build.') -option('build_dx11', type : 'boolean', value : true, description : 'Enables/disables the build of the dx11 renderer.') \ No newline at end of file +option('build_dx11', type : 'boolean', value : true, description : 'Enables/disables the build of the dx11 renderer.') +option('build_experiments', type : 'boolean', value : false, description : 'Enables/disables building the experiments in src/experimental.') diff --git a/scripts/download_dxc.sh b/scripts/download_dxc.sh index 3ea7887..2d7fbef 100755 --- a/scripts/download_dxc.sh +++ b/scripts/download_dxc.sh @@ -1,7 +1,7 @@ #!/bin/bash file="linux_dxc_2023_08_14.x86_64.tar.gz" -if [! -d contrib]; then +if [ ! -d contrib ]; then echo "Could not find 'contrib'. Make sure to run this script from the projects root directory." exit 1; fi diff --git a/scripts/download_dxc_cross.sh b/scripts/download_dxc_cross.sh old mode 100644 new mode 100755 index e7d2240..324b1bc --- a/scripts/download_dxc_cross.sh +++ b/scripts/download_dxc_cross.sh @@ -1,7 +1,7 @@ #!/bin/bash file="dxc_2023_08_14.zip" -if [! -d contrib]; then +if [ ! -d contrib ]; then echo "Could not find 'contrib'. Make sure to run this script from the projects root directory." exit 1; fi diff --git a/scripts/download_shaderc.sh b/scripts/download_shaderc.sh new file mode 100755 index 0000000..51e4514 --- /dev/null +++ b/scripts/download_shaderc.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Downloads shaderc from github into contrib/ +# +# Last changed: 24/11/23 (DD/MM/YY) +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +SHADERC_VER=v2023.7 +SHADERC_REPO=https://github.com/google/shaderc.git + +# Check if we are beeing run from scripts/ or from root +if [ ! -f meson.build ]; then + cd .. +fi + +git clone --quiet $SHADERC_REPO contrib/shaderc +pushd contrib/shaderc +git checkout --quiet $SHADERC_VER +python3 ./utils/git-sync-deps +rmdir -rf .git + +mkdir build-linux +pushd build-linux +cmake .. +cmake --build . --config Release +popd + +popd diff --git a/src/app_framework/app.c b/src/app_framework/app.c index eb6af87..c27ba4b 100644 --- a/src/app_framework/app.c +++ b/src/app_framework/app.c @@ -15,7 +15,7 @@ RT_CVAR_I(rt_WindowHeight, "Window height. Default: 768", 768); #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN -#include +#include static LRESULT CALLBACK win32WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { @@ -100,7 +100,7 @@ RT_DLLEXPORT int rtWin32Entry(HINSTANCE hInstance, { RECT r; GetClientRect(wnd, &r); - window_width = r.right; + window_width = r.right; window_height = r.bottom; } rt_renderer_init_info renderer_info = {.hWnd = wnd, diff --git a/src/asset_compiler/dxc_shader_compiler.cpp b/src/asset_compiler/dxc_shader_compiler.cpp index b93db6f..08a7cb9 100644 --- a/src/asset_compiler/dxc_shader_compiler.cpp +++ b/src/asset_compiler/dxc_shader_compiler.cpp @@ -1,11 +1,17 @@ #ifdef _WIN32 // Required by dxcapi.h, does not work with WIN32_LEAN_AND_MEAN -#include +#include #endif #if defined(__GNUC__) || defined(__clang__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wattributes" #endif + +#ifdef RT_CROSS_LINUX_WINDOWS +#include +#endif + #include #if defined(__GNUC__) || defined(__clang__) #pragma GCC diagnostic pop diff --git a/src/meson.build b/src/meson.build index 7d8f3d1..a529178 100644 --- a/src/meson.build +++ b/src/meson.build @@ -5,4 +5,6 @@ subdir('app_framework') subdir('renderer/common') subdir('renderer/dx11') -subdir('experimental') +if get_option('build_experiments') + subdir('experimental') +endif diff --git a/src/runtime/aio.c b/src/runtime/aio.c index d7e86b1..9b94af0 100644 --- a/src/runtime/aio.c +++ b/src/runtime/aio.c @@ -4,7 +4,7 @@ #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN -#include +#include void Win32ErrorToString(DWORD last_error, char *out, int bufsize); diff --git a/src/runtime/assert.c b/src/runtime/assert.c index afd6d53..377c669 100644 --- a/src/runtime/assert.c +++ b/src/runtime/assert.c @@ -1,9 +1,9 @@ -#include "runtime.h" #include "config.h" +#include "runtime.h" #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN -#include +#include #endif #include @@ -29,7 +29,6 @@ RT_DLLEXPORT int rtAssertHandler(const char *expr, const char *msg, const char * line); outmessage[511] = '\0'; - DWORD action = MessageBoxA(NULL, outmessage, "Assertion Failed", MB_YESNOCANCEL | MB_ICONERROR); if (action == IDYES) { return ASSERT_HANDLER_DBGBREAK; @@ -42,4 +41,4 @@ RT_DLLEXPORT int rtAssertHandler(const char *expr, const char *msg, const char * } #endif return ASSERT_HANDLER_CONTINUE; -} \ No newline at end of file +} diff --git a/src/runtime/cross_sal.h b/src/runtime/cross_sal.h new file mode 100644 index 0000000..7f24675 --- /dev/null +++ b/src/runtime/cross_sal.h @@ -0,0 +1,17 @@ +#ifndef RT_CROSS_SAL_H +#define RT_CROSS_SAL_H + +/* mingw-w64 seems to miss some SAL annotations that are used by dxc etc. + * This header adds these. + */ + +#ifndef RT_CROSS_LINUX_WINDOWS +#pragma warning Are you sure that you want to include this file ? +#endif + +#define _Maybenull_ +#define _In_opt_count_(n) +#define _In_bytecount_(n) +#define _In_count_(n) + +#endif diff --git a/src/runtime/dynamic_libs.c b/src/runtime/dynamic_libs.c index 2eed745..d31fe66 100644 --- a/src/runtime/dynamic_libs.c +++ b/src/runtime/dynamic_libs.c @@ -2,7 +2,7 @@ #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN -#include +#include RT_DLLEXPORT rt_dynlib rtOpenCallerLib(void) { return (rt_dynlib)GetModuleHandleW(NULL); diff --git a/src/runtime/error_report.c b/src/runtime/error_report.c index 96db41e..58e760c 100644 --- a/src/runtime/error_report.c +++ b/src/runtime/error_report.c @@ -6,7 +6,7 @@ #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN -#include +#include #define DbgBreak DebugBreak() #elif defined(__GNUC__) diff --git a/src/runtime/fsutils.c b/src/runtime/fsutils.c index 8aeab88..89023df 100644 --- a/src/runtime/fsutils.c +++ b/src/runtime/fsutils.c @@ -5,7 +5,7 @@ #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN -#include +#include struct rt_scandir_handle_s { HANDLE handle; diff --git a/src/runtime/meson.build b/src/runtime/meson.build index 9c15ecf..c15405b 100644 --- a/src/runtime/meson.build +++ b/src/runtime/meson.build @@ -8,6 +8,7 @@ runtime_lib = library('rt', 'buffer_manager.h', 'compression.h', 'config.h', + 'cross_sal.h', 'ds.h', 'dynamic_libs.h', 'file_tab.h', diff --git a/src/runtime/pch/rt_pch.h b/src/runtime/pch/rt_pch.h index cca9941..80a5e05 100644 --- a/src/runtime/pch/rt_pch.h +++ b/src/runtime/pch/rt_pch.h @@ -1,16 +1,16 @@ #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #define NOMINMAX -#include #include +#include #endif /* C standard library*/ +#include +#include #include #include #include -#include -#include /* Runtime */ -#include "runtime/runtime.h" \ No newline at end of file +#include "runtime/runtime.h" diff --git a/src/runtime/sprint.c b/src/runtime/sprint.c index 2dfd672..8d4d3d2 100644 --- a/src/runtime/sprint.c +++ b/src/runtime/sprint.c @@ -10,17 +10,28 @@ #endif #if ENABLE_STB_SPRINTF + +#if defined(_MSC_VER) #pragma warning(push, 0) +#elif defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-compare" +#endif #define STB_SPRINTF_IMPLEMENTATION #define STB_SPRINTF_STATIC + #include + +#if defined(_MSC_VER) #pragma warning(pop) +#elif defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic pop +#endif #else #include #endif -RT_DLLEXPORT int rtSPrint(char *dest, size_t n, const char *fmt, ...) -{ +RT_DLLEXPORT int rtSPrint(char *dest, size_t n, const char *fmt, ...) { va_list ap; va_start(ap, fmt); #if ENABLE_STB_SPRINTF @@ -34,8 +45,7 @@ RT_DLLEXPORT int rtSPrint(char *dest, size_t n, const char *fmt, ...) return r; } -RT_DLLEXPORT int rtVSPrint(char *dest, size_t n, const char *fmt, va_list ap) -{ +RT_DLLEXPORT int rtVSPrint(char *dest, size_t n, const char *fmt, va_list ap) { #if ENABLE_STB_SPRINTF return stbsp_vsnprintf(dest, (int)n, fmt, ap); #else @@ -44,4 +54,4 @@ RT_DLLEXPORT int rtVSPrint(char *dest, size_t n, const char *fmt, va_list ap) dest[n - 1] = '\0'; return r; #endif -} \ No newline at end of file +} diff --git a/src/runtime/text.c b/src/runtime/text.c index 966589f..239b3b7 100644 --- a/src/runtime/text.c +++ b/src/runtime/text.c @@ -4,7 +4,7 @@ #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN -#include +#include #elif defined(__linux__) #include diff --git a/src/runtime/threading_cond.c b/src/runtime/threading_cond.c index 26c2d72..81cd578 100644 --- a/src/runtime/threading_cond.c +++ b/src/runtime/threading_cond.c @@ -68,7 +68,8 @@ RT_DLLEXPORT void rtWaitOnConditionVar(rt_condition_var *var) { #elif defined(_WIN32) #define WIN32_LEAN_AND_MEAN -#include +#include + struct rt_condition_var_s { CRITICAL_SECTION critical_section; CONDITION_VARIABLE cond; diff --git a/src/runtime/threading_mutex.c b/src/runtime/threading_mutex.c index 4871487..0019d05 100644 --- a/src/runtime/threading_mutex.c +++ b/src/runtime/threading_mutex.c @@ -3,7 +3,7 @@ #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN -#include +#include struct rt_mutex_s { HANDLE handle; @@ -92,7 +92,7 @@ RT_DLLEXPORT bool rtUnlockMutex(rt_mutex *mutex) { return false; } mutex->owner = 0; - bool result = ReleaseMutex(mutex->handle) != 0; + bool result = ReleaseMutex(mutex->handle) != 0; if (!result) mutex->owner = caller; return result; diff --git a/src/runtime/threading_thread.c b/src/runtime/threading_thread.c index cb9cc48..725ef66 100644 --- a/src/runtime/threading_thread.c +++ b/src/runtime/threading_thread.c @@ -4,7 +4,7 @@ #if defined(_WIN32) #define WIN32_LEAN_AND_MEAN -#include +#include struct rt_thread_s { HANDLE handle; @@ -83,9 +83,11 @@ RT_DLLEXPORT rt_thread *rtSpawnThread(rt_thread_entry_fn *entry, void *param, co thrd = NULL; } +#ifndef RT_CROSS_LINUX_WINDOWS WCHAR wname[64]; if (thrd && name && rtUTF8ToWStr(name, wname, sizeof(wname)) == RT_SUCCESS) SetThreadDescription(thrd->handle, wname); +#endif } else { rtReportError("core", "Ran out of thread objects"); diff --git a/src/runtime/timing.c b/src/runtime/timing.c index 795588a..24cb24b 100644 --- a/src/runtime/timing.c +++ b/src/runtime/timing.c @@ -2,7 +2,7 @@ #if defined(_WIN32) #define WIN32_LEAN_AND_MEAN -#include +#include static uint64_t _QPC_freq = 0u; @@ -11,11 +11,12 @@ rt_result InitTiming(void) { if (!QueryPerformanceFrequency(&qpc_freq)) { return RT_UNKNOWN_ERROR; } - _QPC_freq = (uint64_t)qpc_freq.QuadPart; + _QPC_freq = (uint64_t)qpc_freq.QuadPart; double resolution = 1e6 * 1.0 / (double)_QPC_freq; rtLog("TIMING", "QPC Frequency: %llu ticks per second Resolution: %.2lf us", - _QPC_freq, resolution); + _QPC_freq, + resolution); return RT_SUCCESS; } @@ -23,7 +24,7 @@ rt_result InitTiming(void) { RT_DLLEXPORT rt_timestamp rtTimeNow(void) { LARGE_INTEGER qpc; QueryPerformanceCounter(&qpc); - return (rt_timestamp){.ticks = qpc.QuadPart, .ticks_per_second = _QPC_freq }; + return (rt_timestamp){.ticks = qpc.QuadPart, .ticks_per_second = _QPC_freq}; } RT_DLLEXPORT rt_time_delta rtTimeBetween(rt_timestamp a, rt_timestamp b) { @@ -33,4 +34,4 @@ RT_DLLEXPORT rt_time_delta rtTimeBetween(rt_timestamp a, rt_timestamp b) { return b_secs - a_secs; } -#endif \ No newline at end of file +#endif diff --git a/tests/meson.build b/tests/meson.build index 776d979..cd5d616 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -1,7 +1,4 @@ test_link_libs = [runtime_lib] -if get_option('default_library') == 'static' - test_link_libs += null_renderer_lib -endif rttest_exe = executable('rttest', 'rttest.c', diff --git a/tests/rttest.c b/tests/rttest.c index a01d26c..11ccfd0 100644 --- a/tests/rttest.c +++ b/tests/rttest.c @@ -1,3 +1,4 @@ +#include #include #include "runtime/config.h" @@ -5,12 +6,6 @@ #include "runtime/mem_arena.h" #include "runtime/runtime.h" -#include "gfx/gfx.h" -#include "gfx/render_list.h" -#include "gfx/renderer_api.h" - -extern rt_cvar rt_Renderer; - /* Check basic relative pointer behaviour */ static rt_result RelPtrTest(void) { char buf[sizeof(rt_relptr) + sizeof(unsigned int)]; @@ -46,6 +41,7 @@ static rt_result NegRelPtrTest(void) { return RT_SUCCESS; } +#if 0 static rt_result SetupRenderListFixture(void) { rt_result res = rtInitRuntime(); if (res != RT_SUCCESS) @@ -120,6 +116,7 @@ static rt_result PushLongRenderList(void) { } return RT_SUCCESS; } +#endif static rt_result HashTableBasics(void) { { @@ -140,14 +137,14 @@ static rt_result HashTableBasics(void) { if (!arena_res.ok) return RT_OUT_OF_MEMORY; rt_arena arena = arena_res.arena; - void *mem = rtArenaPush(&arena, RT_HASH_TABLE_MEMORY_REQUIRED(64)); + void *mem = rtArenaPush(&arena, RT_HASH_TABLE_MEMORY_REQUIRED(64)); if (!mem) return RT_OUT_OF_MEMORY; rt_hashtable ht = rtCreateHashtable(64, mem, rtHashtableGrowMemoryFromArena, &arena); for (uint64_t i = 0; i < 64; ++i) { - if (rtHashtableInsert(&ht, 256+i, i) != RT_SUCCESS) + if (rtHashtableInsert(&ht, 256 + i, i) != RT_SUCCESS) return RT_UNKNOWN_ERROR; - uint64_t found = rtHashtableLookup(&ht, 256+i, UINT64_MAX); + uint64_t found = rtHashtableLookup(&ht, 256 + i, UINT64_MAX); if (found != i) return RT_INVALID_VALUE; } @@ -188,8 +185,8 @@ typedef struct { /* X-Macro to create named fixtures */ /* Add more fixtures here*/ -#define TEST_FIXTURE_LIST \ - TEST_FIXTURE(render_list_fixture, SetupRenderListFixture, TeardownRenderListFixture) +#define TEST_FIXTURE_LIST +// TEST_FIXTURE(render_list_fixture, SetupRenderListFixture, TeardownRenderListFixture) #define TEST_FIXTURE(n, setup_fn, teardown_fn) \ rt_test_fixture n = {.name = #n, \ @@ -205,8 +202,8 @@ static rt_test_fixture *_test_fixtures[] = {TEST_FIXTURE_LIST}; static rt_test_case _test_cases[] = {TEST_CASE(RelPtrTest), TEST_CASE(NegRelPtrTest), - TEST_CASE_FIXTURE(PushRenderList, render_list_fixture), - TEST_CASE_FIXTURE(PushLongRenderList, render_list_fixture), + /*TEST_CASE_FIXTURE(PushRenderList, render_list_fixture), + TEST_CASE_FIXTURE(PushLongRenderList, render_list_fixture),*/ TEST_CASE(HashTableBasics)}; int main() { @@ -241,8 +238,10 @@ int main() { } } - /* Teardown fixtures */ - for (size_t i = 0; i < RT_ARRAY_COUNT(_test_fixtures); ++i) { + /* Teardown fixtures. + * The +1 is necessary to avoid comparing i=0 < 0, which causes a compile + * error */ + for (size_t i = 0; (i + 1) < (RT_ARRAY_COUNT(_test_fixtures) + 1); ++i) { if (_test_fixtures[i]->is_initialized) { printf("[TEARDOWN %s] ... ", _test_fixtures[i]->name); _test_fixtures[i]->teardown();