[video output=day435 member=cmuratori stream_platform=twitch stream_username=handmade_hero project=code title="Removing the CRT from the Win32 Loader" vod_platform=youtube id=sE4tUVaxiV0 annotator=Miblo]
[0:06][Recap and set the stage for the day removing the C Runtime Library][:library :speech]
[0:52][Read our linker flags in build.bat][:library :research]
[3:02][Inspect our executable in depends[ref
    site="Dependency Walker"
    url=http://dependencywalker.com/] to see what we're linking with][:admin :library]
[7:54][Replace the -MTd switch with -MD in our CommonCompilerFlags[ref
    site=MSDN
    page="/MD, /MT, /LD (Use Run-Time Library)"
    url=https://msdn.microsoft.com/en-us/library/2kzt1wy3.aspx]]
[10:54][Inspect this executable in depends to see VCRUNTIME140.DLL in there][:admin :library]
[14:00][NODEFAULTLIB[ref
    site=MSDN
    page="/NODEFAULTLIB (Ignore Libraries)"
    url=https://msdn.microsoft.com/en-us/library/3tz4da4a.aspx]][:research]
[15:12][Add /NODEFAULTLIB to our 64-bit win32_handmade.cpp compilation line and move -MTd down to there][:library]
[17:28][On the trend of compilers to essentially try and force the use of the CRT, and how to get around this][:library :rant :speech]
[19:20][Determine which functions from the CRT we need to replace][:library :research]
[21:56][Read 'How to avoid C/C++ runtime on Windows' by @mmozeiko[ref
    site="Handmade Hero Forums"
    page="Guide - How to avoid C/C++ runtime on Windows"
    url=https://hero.handmade.network/forums/code-discussion/t/94-guide_-_how_to_avoid_c_c++_runtime_on_windows] on allocating large arrays / structures on stack (>4KB)][:library :memory :research]
[31:04][Add -STACK:0x100000,0x100000, -GS- and -Gs9999999 to our CommonCompilerFlags[ref
    site="Handmade Hero Forums"
    page="Guide - How to avoid C/C++ runtime on Windows"
    url=https://hero.handmade.network/forums/code-discussion/t/94-guide_-_how_to_avoid_c_c++_runtime_on_windows][ref
        site=MSDN
        page="/Gs (Control Stack Checking Calls)"
        url=https://msdn.microsoft.com/en-us/library/9598wk25.aspx]][:library :memory]
[35:55][Grab the function signature of memset() from vcruntime_string.h, and write our own implementation in a new file using #pragma intrinsic[ref
    site=MSDN
    page="intrinsic"
    url=https://msdn.microsoft.com/en-us/library/tzkfha43.aspx]][:library :memory]
[46:36][Change our memset() to use #pragma function[ref
    site="Handmade Hero Forums"
    page="Guide - How to avoid C/C++ runtime on Windows"
    url=https://hero.handmade.network/forums/code-discussion/t/94-guide_-_how_to_avoid_c_c++_runtime_on_windows]][:library :memory]
[48:15][Hunt for _fltused in the CRT][:library :mathematics :research]
[50:57][Grab the int _fltused from fltused.cpp][:library :mathematics]
[52:14][Find WinMainCRTStartup][:library :"platform layer" :research]
[58:52][Pull in the declaration of WinMainCRTStartup][:library :"platform layer"]
[1:02:02][Read about the /ENTRY[ref
    site=MSDN
    page="/ENTRY (Entry-Point Symbol)"
    url=https://msdn.microsoft.com/en-us/library/f9t8842e.aspx] and /SUBSYSTEM[ref
        site=MSDN
        page="/SUBSYSTEM (Specify Subsystem)"
        url=https://docs.microsoft.com/en-us/cpp/build/reference/subsystem-specify-subsystem] flags][:library :"platform layer" :research]
[1:04:31][Add /SUBSYSTEM:windows to our win32_handmade.cpp compilation line][:"platform layer"]
[1:07:55][:Run the game to see that we're running just fine without the CRT][:library]
[1:08:25][Add /NODEFAULTLIB to our handmade.cpp compilation line and compile to see that we are only missing the transcendental :mathematics functions, sinf(), cosf() and atan2f()][:library]
[1:13:37][Inspect the :asm of cosf() with the determination to write our own][:mathematics :research]
[1:15:54][Why we did all of this: for sampling the hemisphere][:lighting :rendering :statistics]
[1:16:53][Remove /NODEFAULTLIB from our handmade.cpp compilation line for now][:library]
[1:17:24][Read through our hemisphere sampling code in ComputeLightPropagation()][:lighting :rendering :research]
[1:18:28][:Run the game to show our sampling :"debug visualisation"][:lighting :rendering]
[1:18:53][Remove cruft – including EntropyCounter from lighting_solution – from the :lighting code][:lighting :rendering]
[1:20:56][:Run the game, hit Alt-F4 and note that the game is still running]
[1:21:46][Make WinMainCRTStartup() call ExitProcess()][:"platform layer"]
[1:22:29][:Run the game, hit Alt-F4 and successfully exit out][:"platform layer"]
[1:22:45][Investigate ceilf() and floorf() from our debug build][:library :mathematics :research]
[1:26:13][Crash in ComputeLightPropagation() and consult the :asm to try and determine why][:lighting :memory :rendering :run]
[1:31:50][Realise that threads initialised by us, subsequent to the first one initialised by Windows, were overflowing the stack[ref
    site=MSDN
    page="Thread Stack Size"
    url=https://msdn.microsoft.com/en-us/library/windows/desktop/ms686774.aspx]][:memory :speech :threading]
[1:36:18][Make Win32MakeQueue() pass 1 megabyte as dwStackSize to CreateThread()][:memory :threading]
[1:36:43][:Run the game and try to determine how much stack space ComputeLightPropagation() could need][:memory :threading]
[1:47:08][Note that our HitPointIndex is out of bounds, and investigate how][:lighting :memory :rendering :run]
[1:50:28][:Run the game until we crash in ComputeLightPropagation() and try to recover the HitBox and BoxSurfaceIndex information with help from the :asm][:lighting :memory :rendering]
[1:57:32][Investigate how BoxSurfaceIndex could get set to 6][:lighting :rendering :research]
[2:00:29][Assert (unfortunately in the #if 0 code) in RayCast() that Positive == 1 or 0, and that BoxSurfaceIndex is less than 6][:lighting :rendering]
[2:01:10][:Run the game until we crash][:lighting :rendering]
[2:02:43][Assert in the correct part of RayCast() that BoxSurfaceIndex is less that 6][:lighting :optimisation :rendering]
[2:05:46][:Run the game, hit the assertion on our third lane, and note that a BoxSurfaceIndex > 5 could be produced if a box has no size][:asm :lighting :optimisation :rendering]
[2:16:10][Make RayCast() keep a running total of box surface hits in a RunningMask in order to correctly determine the BoxSurfaceIndex()[ref
    site=Intel
    page="Intel Intrinsics Guide"
    url=https://software.intel.com/sites/landingpage/IntrinsicsGuide/]][:lighting :optimisation :rendering]
[2:30:13][:Run the game and try unsuccessfully to trigger our BoxSurfaceIndex assertions][:lighting :optimisation :rendering]
[2:32:32][Q&A][:speech]
[2:33:17][@desuused][Q: Can we use six separate bits to represent hits with each box wall, then take the highest bit to determine which individual box hit we'll use? (see: _mm_lzcnt_epi32[ref
    site=Intel
    page="Intel Intrinsics Guide"
    url=https://software.intel.com/sites/landingpage/IntrinsicsGuide/])][:lighting :optimisation :rendering]
[2:37:00][@ginger_bill][@cmuratori, RETURN THE ORIGINAL DESTINATION!!!!!]
[2:37:22][Make memset() return _Dst][:memory]
[2:38:21][@yurasniper][Q: Would it be better to make hemisphere sampling visualization as an actual hemisphere with dots rendered on it?][:"debug visualisation" :lighting :rendering :statistics]
[2:38:46][Reduce the length of the debug lines in LightingTest()][:"debug visualisation" :lighting :rendering :statistics]
[2:39:26][:Run the game to see this :"debug visualisation"][:lighting :rendering :statistics]
[2:40:01][Make LightingTest() use PushCube() instead][:"debug visualisation" :lighting :rendering :statistics]
[2:42:06][:Run the game to see the cubes][:"debug visualisation" :lighting :rendering :statistics]
[2:42:31][Enable LightingTest() to display a stationary sampling pattern][:"debug visualisation" :lighting :rendering :statistics]
[2:43:09][:Run the game to see the static :"debug visualisation"][:lighting :rendering :statistics]
[2:44:06][@mmozeiko][Q: Why do you do *(unsigned char*)&_Val instead of (unsigned char)_Val in memset?][:memory]
[2:46:11][@areriff][Q: Off-topic: What harm do you think could happen if you click on that yellow flag to upgrade MSVC? No breaking change has been introduce since this new machine, just lots of compiler upgrades]
[2:47:55][@filiadelski][Q: Is the stack size set on the command line for the entire stack or for each stack frame?][:memory :threading]
[2:48:35][@mmozeiko][Q: Another thing to mention when using /stack to get 1MB stack vs 4kb probing, is that all threads also will have this stack size by default. It could be an issue if somebody is creating and keeping hundreds of threads live][:memory :threading]
[2:48:59][@alexkelbo][Q: Also you once said that in your projects you don't include windows.h and other windows-related h-files. How would we go about doing that?][:library]
[2:49:49][@mextrox][Q: I hope this is not too far off-topic. Recently I have thought about a hook-based execution / :memory management system. Where when you allocate memory you can tell in the next line when it should be freed. There would be as many hooks as you like, for example: afterFrameHook or levelLoadHook or stuff like this. The hooks internally would be a collection of lambdas so they can capture the address that]
[2:51:30][@conspicoussquirrel][Q: What are your thoughts on using macro's in C to make writing certain repeated patterns shorter? For example, encapsulating extremely common patterns like: #define DO(f,n) = for(int i = 0;i<n;i++)f;]
[2:52:24][@klemensbaum][Q: Sorry off-topic, but since you worked at Microsoft, would you recommend working at Microsoft nowadays, for a new grad?]
[3:02:58][@wolverinegator][Q: Do we still need a separate translation unit for the MSVC stuff? In my projects I had no problems having it in one unit]
[3:03:52][@nxsy][So, if you’re joining FB, ask me. If google, ask @quartertron. I’m sure there are more people in the community for the others]
[3:05:08][@naysayer88][@cmuratori You are so jealous that I get to go to GDC next week and see all the great talks]
[3:06:40][Close down with a reminder of @mmozeiko's guide 'How to avoid C/C++ runtime on Windows'[ref
    site="Handmade Hero Forums"
    page="Guide - How to avoid C/C++ runtime on Windows"
    url=https://hero.handmade.network/forums/code-discussion/t/94-guide_-_how_to_avoid_c_c++_runtime_on_windows]][:speech]
[/video]
