[video output=day386 member=cmuratori stream_platform=twitch stream_username=handmade_hero project=code title="Implementing a Custom Multisample Resolve" vod_platform=youtube id=RtOLz8xU2tw annotator=Miblo]
[0:22][Recap our depth-peeling-with-multisampling puzzler and set the stage for the day]
[3:52][cheap and easy solution for enabling multisampled antialiasing on the target platform]
[5:30][Describe an old method to perform smoothing, using glHint[ref
    site="docs.GL"
    page="glHint"
    url="http://docs.gl/gl2/glHint"] and glEdgeFlag[ref
        site=Khronos
        page=glEdgeFlag
        url=https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glEdgeFlag.xml]]
[10:19][Consult the OpenGL 3.2 Specification for POLYGON_SMOOTH[ref
    site="OpenGL Registry"
    page="OpenGL 3.2 (Core Profile)"
    url=https://khronos.org/registry/OpenGL/specs/gl/glspec32.core.pdf]]
[12:43][handmade_opengl.cpp: Disable multisampling in OpenGLChangeToSettings()]
[13:32][handmade_opengl.cpp: Try turning on GL_POLYGON_SMOOTH_HINT in OpenGLRenderCommands()]
[14:29][Run the game and see no difference]
[15:59][handmade_opengl.cpp: Reenable multisampling back on in OpenGLChangeToSettings(), and run the game to see that it's much slower]
[17:19][Consider why the multisampling is so much slower]
[19:10][win32_handmade.cpp: Switch to a lower resolution and run the game to see that the frame rate is fine now]
[20:00][Inspect the artifacts caused by the multisampling failing to pick from the correct value for depth peeling]
[22:39][Consult Wikipedia to see if the discard creates a place where things will get sampled more[ref
    site="Wikipedia"
    page="Multisample anti-aliasing"
    url="https://en.wikipedia.org/wiki/Multisample_anti-aliasing"]]
[24:47][Run the game and assess the quality improvement brought by multisampling, if only the depth picking was correct]
[28:25][Consider drawing some structured art to help us diagnose this artifacting]
[30:45][handmade_opengl.cpp: Make CompileZBiasProgram() hard set the ModColor.a to 0.5, and run the game to validate where the artifacts occur]
[33:07][Consider the possibility that we don't have a problem at all, if we include the 1-pixel transparent border, or only evaluate the Z value at the centroid]
[35:42][Consult the OpenGL ES Shading Language specification on the storage qualifiers centroid[ref
    site="OpenGL Registry"
    page="The OpenGL ES Shading Language"
    url=https://khronos.org/registry/OpenGL/specs/es/3.0/GLSL_ES_Specification_3.00.pdf]]
[38:22][handmade_opengl.cpp: Try to make CompileZBiasProgram() preserve the FragZ coordinate across all depth buffers]
[44:15][Run the game to see Z-fighting]
[44:42][handmade_opengl.cpp: Make CompileZBiasProgram() correctly set that FragZ]
[46:20][Run the game and still see the artifacts]
[47:04][handmade_opengl.cpp: Undo those changes in CompileZBiasProgram()]
[50:28][Look closely at the tree bitmap, and consider inserting a 1-pixel border around everything]
[55:50][Read about CLAMP_TO_BORDER in the OpenGL 3.2 spec[ref
    site="OpenGL Registry"
    page="OpenGL 3.2 (Core Profile)"
    url=https://khronos.org/registry/OpenGL/specs/gl/glspec32.core.pdf]]
[58:11][Read about gl_FragDepth in the OpenGL Shading Language 4.3 spec[ref
    site="OpenGL Registry"
    page="The OpenGL Shading Language"
    url="https://khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.4.30.pdf"]]
[1:04:11][Consider our two things at play: We only get artifacts where multisampling occurs at the edges of primitives; perhaps the resolve is picking a bad Z value]
[1:07:34][handmade_opengl.cpp: Consider how to fix CompileResolveMultisample()]
[1:12:44][handmade_opengl.cpp: Enable CompileResolveMultisample() to compute CombinedColor, and UseProgramBegin() to set up the color and depth samplers]
[1:15:50][handmade_opengl.cpp: Make OpenGLRenderCommands() setup the framebuffers to pass to ResolveMultisample(), and fix compile errors]
[1:21:39][handmade_opengl.cpp: Determine that the (f32)SampleCount line in CompileResolveMultisample() is causing the error]
[1:24:07][handmade_opengl.cpp: Continue fixing compile errors in CompileResolveMultisample()]
[1:25:24][Run successfully, but see nothing]
[1:26:35][handmade_opengl.cpp: Make UseProgramBegin() set the Prog->SampleCount for CompileResolveMultisample() to use]
[1:28:35][Run the game to see that the alpha value isn't getting written properly, and investigate why]
[1:30:23][handmade_opengl.cpp: Make CompileResolveMultisample() disable GL_DEPTH_TEST, and run the game to see our old artifacts gone, but a new one present]
[1:32:41][win32_handmade.cpp: Switch to a higher resolution, and run the game to see that this is still slow]
[1:35:16][handmade_opengl.cpp: Assess OpenGLRenderCommands() and note that multisampling is not actually off]
[1:37:25][Run the game to see that it looks the same whether multisampling is enabled or not]
[1:38:06][handmade_opengl.cpp: Disable multisampling in OpenGLChangeToSettings() and run the game to see the debug information]
[1:39:12][handmade_platform.h: Make DefaultRenderCommands() set the MultisamplingHint to false, and run the game to see that the multisampling is responsible for the debug system disappearing]
[1:41:17][handmade_opengl.cpp: Determine that there's a problem in ResolveMultisample(), and investigate what]
[1:43:27][handmade_opengl.cpp: Make ResolveMultisample() read from the correct framebuffer]
[1:44:38][handmade_opengl.cpp: Try making OpenGLRenderCommands() follow both multisampling paths and run the game to verify that it is a state-based problem]
[1:45:26][handmade_opengl.cpp: Reorder the OpenGL calls in ResolveMultisample() so that they are last-in-first-out]
[1:47:05][Run the game to see that it works]
[1:48:59][Q&A][:speech]
[1:49:30][@nyeecola][Casey, you often argue that we don't need to free memory and clean up upon exiting the program. Does the same reasoning apply to glDeleteProgram() and others? I saw you use that and wondered what is the reasoning behind it]
[1:51:31][@calphorus][Casting in GLSL is done: f32(Value) instead of (f32)Value]
[1:53:42][@grubbyjuice][Is there a vim version of your colorscheme?]
[1:53:59][@uplinkcoder][Could you try using Mesa for debugging?]
[1:55:29][@grubbyjuice][How often do we need to free and allocate memory compared to the early 2000s?]
[1:55:56][@jhendrichj][What video card do you use?]
[1:56:18][Compare the ATI FirePro V8700[ref
    site="Wikipedia"
    page="List of AMD graphics processing units"
    url=https://en.wikipedia.org/wiki/List_of_AMD_graphics_processing_units#FirePro_3D_Series_.28V000.29] with a modern GPU[ref
    site="Wikipedia"
    page="List of Nvidia graphics processing units"
    url=https://en.wikipedia.org/wiki/List_of_Nvidia_graphics_processing_units#GeForce_10_series]]
[2:01:16][@aradel87][Slightly off topic, I recently found out that AVE exists, for SSE there are pretty clear mathermatical applications for it such as mat mul. Do you see the benefits of using AVE and in which context?]
[2:02:12][@grubbyjuice][Q: What is the name of your colorscheme?]
[2:02:32][@uplinkcoder][He meant AVX[ref
    site="Valve"
    page="Steam Hardware Survey"
    url="http://store.steampowered.com/hwsurvey"]]
[2:06:57][A few words on the AVX512 instruction set and Larrabee][:speech]
[2:12:45][Wrap it up][:speech]
[/video]
