Changing to Single Dispatch Per Pass (Part 2)
?
?

Keyboard Navigation

Global Keys

[, < / ], > Jump to previous / next episode
W, K, P / S, J, N Jump to previous / next marker
t / T Toggle theatre / SUPERtheatre mode
V Revert filter to original state Y Select link (requires manual Ctrl-c)

Menu toggling

q Quotes r References f Filter y Link c Credits

In-Menu Movement

a
w
s
d
h j k l


Quotes and References Menus

Enter Jump to timecode

Quotes, References and Credits Menus

o Open URL (in new tab)

Filter Menu

x, Space Toggle category and focus next
X, ShiftSpace Toggle category and focus previous
v Invert topics / media as per focus

Filter and Link Menus

z Toggle filter / linking mode

Credits Menu

Enter Open URL (in new tab)
0:00Recap our switch to texture vertex indices
🗩
0:00Recap our switch to texture vertex indices
🗩
0:00Recap our switch to texture vertex indices
🗩
1:36Augment game_render_commands with an IndexArray, with a few words on the GPU's ability to cache vertex shader transforms
1:36Augment game_render_commands with an IndexArray, with a few words on the GPU's ability to cache vertex shader transforms
1:36Augment game_render_commands with an IndexArray, with a few words on the GPU's ability to cache vertex shader transforms
7:29Remove renderer_texture_group and renderer_memory_layout, and pass our new IndexArray down the pipe, also augmenting open_gl with IndexArray and MaxIndexCount
7:29Remove renderer_texture_group and renderer_memory_layout, and pass our new IndexArray down the pipe, also augmenting open_gl with IndexArray and MaxIndexCount
7:29Remove renderer_texture_group and renderer_memory_layout, and pass our new IndexArray down the pipe, also augmenting open_gl with IndexArray and MaxIndexCount
14:00Run the Renderer Test successfully
🏃
14:00Run the Renderer Test successfully
🏃
14:00Run the Renderer Test successfully
🏃
14:12Reduce the MaxQuadCountPerFrame in RenderTest() and the (grass) CoverIndex in PushSimpleScene(), with a few words on breaking the problem into steps
14:12Reduce the MaxQuadCountPerFrame in RenderTest() and the (grass) CoverIndex in PushSimpleScene(), with a few words on breaking the problem into steps
14:12Reduce the MaxQuadCountPerFrame in RenderTest() and the (grass) CoverIndex in PushSimpleScene(), with a few words on breaking the problem into steps
16:30Run the Renderer Test with our single vertex buffer working
🏃
16:30Run the Renderer Test with our single vertex buffer working
🏃
16:30Run the Renderer Test with our single vertex buffer working
🏃
16:51Augment render_entry_textured_quads with IndexArrayOffset for OpenGLEndFrame() to use the index buffer passed in
16:51Augment render_entry_textured_quads with IndexArrayOffset for OpenGLEndFrame() to use the index buffer passed in
16:51Augment render_entry_textured_quads with IndexArrayOffset for OpenGLEndFrame() to use the index buffer passed in
20:19Change OpenGLEndFrame() to call glBufferData() once, instead of while processing every render command
20:19Change OpenGLEndFrame() to call glBufferData() once, instead of while processing every render command
20:19Change OpenGLEndFrame() to call glBufferData() once, instead of while processing every render command
22:17Run it to see problems with the depth peeling
🏃
22:17Run it to see problems with the depth peeling
🏃
22:17Run it to see problems with the depth peeling
🏃
22:44Make OpenGLInit() generate a separate CompositeVertexBuffer and ScreenFillVertexBuffer1
22:44Make OpenGLInit() generate a separate CompositeVertexBuffer and ScreenFillVertexBuffer1
22:44Make OpenGLInit() generate a separate CompositeVertexBuffer and ScreenFillVertexBuffer1
28:52Run it with the depth peel working correctly
🏃
28:52Run it with the depth peel working correctly
🏃
28:52Run it with the depth peel working correctly
🏃
29:03Revert the MaxQuadCountPerFrame in RenderTest() and the (grass) CoverIndex in PushSimpleScene() to their original high values
29:03Revert the MaxQuadCountPerFrame in RenderTest() and the (grass) CoverIndex in PushSimpleScene() to their original high values
29:03Revert the MaxQuadCountPerFrame in RenderTest() and the (grass) CoverIndex in PushSimpleScene() to their original high values
29:55Run it to see that it is much zippier
🏃
29:55Run it to see that it is much zippier
🏃
29:55Run it to see that it is much zippier
🏃
30:34Temporarily disable the lighting
30:34Temporarily disable the lighting
30:34Temporarily disable the lighting
31:15Run it to see that it didn't affect it much
🏃
31:15Run it to see that it didn't affect it much
🏃
31:15Run it to see that it didn't affect it much
🏃
31:51Make RenderLoop() disable the lighting
31:51Make RenderLoop() disable the lighting
31:51Make RenderLoop() disable the lighting
33:17Run it and gauge the performance with the lighting disabled
🏃
33:17Run it and gauge the performance with the lighting disabled
🏃
33:17Run it and gauge the performance with the lighting disabled
🏃
35:40Turn off all the grass and augment open_gl with an IndexBuffer for OpenGLEndFrame() to use, rather than initialising Indices itself2,3
35:40Turn off all the grass and augment open_gl with an IndexBuffer for OpenGLEndFrame() to use, rather than initialising Indices itself2,3
35:40Turn off all the grass and augment open_gl with an IndexBuffer for OpenGLEndFrame() to use, rather than initialising Indices itself2,3
45:31Make PushQuad() fill our new IndexBuffer with the VertIndex
45:31Make PushQuad() fill our new IndexBuffer with the VertIndex
45:31Make PushQuad() fill our new IndexBuffer with the VertIndex
49:08Run it without crashing, but also without seeing anything
🏃
49:08Run it without crashing, but also without seeing anything
🏃
49:08Run it without crashing, but also without seeing anything
🏃
49:37Fix OpenGLEndFrame() to pass GL_UNSIGNED_SHORT to glDrawElements()
49:37Fix OpenGLEndFrame() to pass GL_UNSIGNED_SHORT to glDrawElements()
49:37Fix OpenGLEndFrame() to pass GL_UNSIGNED_SHORT to glDrawElements()
50:36Run it to see that our triangle must be wound wrong
🏃
50:36Run it to see that our triangle must be wound wrong
🏃
50:36Run it to see that our triangle must be wound wrong
🏃
50:46Triangle winding
🖌
50:46Triangle winding
🖌
50:46Triangle winding
🖌
51:25Fix the vertex winding in PushQuad()
51:25Fix the vertex winding in PushQuad()
51:25Fix the vertex winding in PushQuad()
51:29Run it to see that it looks about right
🏃
51:29Run it to see that it looks about right
🏃
51:29Run it to see that it looks about right
🏃
51:38Let OpenGLEndFrame() texture our quads with their bitmaps
51:38Let OpenGLEndFrame() texture our quads with their bitmaps
51:38Let OpenGLEndFrame() texture our quads with their bitmaps
51:58Run it to see that it looks about right
🏃
51:58Run it to see that it looks about right
🏃
51:58Run it to see that it looks about right
🏃
52:05Switch OpenGLEndFrame() to perform one draw call per scene, using the white bitmap for each sprite
52:05Switch OpenGLEndFrame() to perform one draw call per scene, using the white bitmap for each sprite
52:05Switch OpenGLEndFrame() to perform one draw call per scene, using the white bitmap for each sprite
53:21Run it to see that our performance has improved
🏃
53:21Run it to see that our performance has improved
🏃
53:21Run it to see that our performance has improved
🏃
54:56Re-enable all the grass with a view to overcoming the unsigned short vertex buffer index limit
54:56Re-enable all the grass with a view to overcoming the unsigned short vertex buffer index limit
54:56Re-enable all the grass with a view to overcoming the unsigned short vertex buffer index limit
55:40Run it and hit our VI == VertIndex assertion
🏃
55:40Run it and hit our VI == VertIndex assertion
🏃
55:40Run it and hit our VI == VertIndex assertion
🏃
56:23Enable GetCurrentQuads() and PushQuad() to handle more than 65535 / 4 quads using glDrawElementsBaseVertex()4,5
56:23Enable GetCurrentQuads() and PushQuad() to handle more than 65535 / 4 quads using glDrawElementsBaseVertex()4,5
56:23Enable GetCurrentQuads() and PushQuad() to handle more than 65535 / 4 quads using glDrawElementsBaseVertex()4,5
1:04:41Run it to see that it looks good
🏃
1:04:41Run it to see that it looks good
🏃
1:04:41Run it to see that it looks good
🏃
1:05:29Let OpenGLEndFrame() texture our quads with the grass bitmap
1:05:29Let OpenGLEndFrame() texture our quads with the grass bitmap
1:05:29Let OpenGLEndFrame() texture our quads with the grass bitmap
1:06:06Run it to see that we now don't have any performance spikes
🏃
1:06:06Run it to see that we now don't have any performance spikes
🏃
1:06:06Run it to see that we now don't have any performance spikes
🏃
1:08:30Begin to switch the renderer over to use texture arrays, first enabling the vertex shader to understand the notion of a vertex index
1:08:30Begin to switch the renderer over to use texture arrays, first enabling the vertex shader to understand the notion of a vertex index
1:08:30Begin to switch the renderer over to use texture arrays, first enabling the vertex shader to understand the notion of a vertex index
1:18:44Run it successfully
🏃
1:18:44Run it successfully
🏃
1:18:44Run it successfully
🏃
1:18:51Switch OpenGLAllocateTexture() to specify a feed-forward texture array, calling glTexSubImage3D()6,7
1:18:51Switch OpenGLAllocateTexture() to specify a feed-forward texture array, calling glTexSubImage3D()6,7
1:18:51Switch OpenGLAllocateTexture() to specify a feed-forward texture array, calling glTexSubImage3D()6,7
1:38:09Switch Handmade Hero over to use the renderer's new texture array
1:38:09Switch Handmade Hero over to use the renderer's new texture array
1:38:09Switch Handmade Hero over to use the renderer's new texture array
1:45:01Run it and hit an OpenGL error: "Texture name does not refer to a texture object generated by OpenGL"
🏃
1:45:01Run it and hit an OpenGL error: "Texture name does not refer to a texture object generated by OpenGL"
🏃
1:45:01Run it and hit an OpenGL error: "Texture name does not refer to a texture object generated by OpenGL"
🏃
1:46:08Temporarily add a TextureHandles array to the open_gl struct
1:46:08Temporarily add a TextureHandles array to the open_gl struct
1:46:08Temporarily add a TextureHandles array to the open_gl struct
1:48:42Run it to see our tree-texture scene
🏃
1:48:42Run it to see our tree-texture scene
🏃
1:48:42Run it to see our tree-texture scene
🏃
1:49:00Remove the TextureHandles in favour of sampling slices into the lone texture array8,9,10,11
1:49:00Remove the TextureHandles in favour of sampling slices into the lone texture array8,9,10,11
1:49:00Remove the TextureHandles in favour of sampling slices into the lone texture array8,9,10,11
2:02:05Run it and hit an OpenGL error: "Invalid texture format"
🏃
2:02:05Run it and hit an OpenGL error: "Invalid texture format"
🏃
2:02:05Run it and hit an OpenGL error: "Invalid texture format"
🏃
2:03:38Prevent OpenGLInit() from allocating the WhiteBitmap, and make it specify a texture level of 1 when calling glTexStorage2D()
2:03:38Prevent OpenGLInit() from allocating the WhiteBitmap, and make it specify a texture level of 1 when calling glTexStorage2D()
2:03:38Prevent OpenGLInit() from allocating the WhiteBitmap, and make it specify a texture level of 1 when calling glTexStorage2D()
2:04:29Run it to see it all working with the correct textures, just that they are not always correctly sized12
🏃
2:04:29Run it to see it all working with the correct textures, just that they are not always correctly sized12
🏃
2:04:29Run it to see it all working with the correct textures, just that they are not always correctly sized12
🏃
2:07:26Run Handmade Hero to see that it has issues
🏃
2:07:26Run Handmade Hero to see that it has issues
🏃
2:07:26Run Handmade Hero to see that it has issues
🏃
2:08:09Remove the WhiteBitmap from the renderer in favour of allowing the game itself to specify it if needed
2:08:09Remove the WhiteBitmap from the renderer in favour of allowing the game itself to specify it if needed
2:08:09Remove the WhiteBitmap from the renderer in favour of allowing the game itself to specify it if needed
2:11:56Enable AllocateGameAssets() in Handmade Hero to create its needed WhiteBitmap
2:11:56Enable AllocateGameAssets() in Handmade Hero to create its needed WhiteBitmap
2:11:56Enable AllocateGameAssets() in Handmade Hero to create its needed WhiteBitmap
2:15:24Augment the renderer_texture with Width and Height for PushQuad() to use and so fix the texture sizing, renaming TextureHandle() to ReferToTexture()
2:15:24Augment the renderer_texture with Width and Height for PushQuad() to use and so fix the texture sizing, renaming TextureHandle() to ReferToTexture()
2:15:24Augment the renderer_texture with Width and Height for PushQuad() to use and so fix the texture sizing, renaming TextureHandle() to ReferToTexture()
2:27:13Make PushQuad() scale the texture UVs based on their sizes
2:27:13Make PushQuad() scale the texture UVs based on their sizes
2:27:13Make PushQuad() scale the texture UVs based on their sizes
2:29:14Run the Renderer Test and Handmade Hero to see that the textures are correctly sized
🏃
2:29:14Run the Renderer Test and Handmade Hero to see that the textures are correctly sized
🏃
2:29:14Run the Renderer Test and Handmade Hero to see that the textures are correctly sized
🏃
2:29:37Define TEXTURE_ARRAY_DIM
2:29:37Define TEXTURE_ARRAY_DIM
2:29:37Define TEXTURE_ARRAY_DIM
2:30:42Run it, doing texture arrays
🏃
2:30:42Run it, doing texture arrays
🏃
2:30:42Run it, doing texture arrays
🏃
2:31:22Q&A
🗩
2:31:22Q&A
🗩
2:31:22Q&A
🗩
2:31:46lkalinovcic Q: Are there any benefits to using PBOs for async texture transfers these days? I've heard that drivers copy texture data into their internal memory anyway, so the call returns immediately and behaves as if it were asynchronous
🗪
2:31:46lkalinovcic Q: Are there any benefits to using PBOs for async texture transfers these days? I've heard that drivers copy texture data into their internal memory anyway, so the call returns immediately and behaves as if it were asynchronous
🗪
2:31:46lkalinovcic Q: Are there any benefits to using PBOs for async texture transfers these days? I've heard that drivers copy texture data into their internal memory anyway, so the call returns immediately and behaves as if it were asynchronous
🗪
2:34:27mmozeiko Q: In GL Core Profile you need to generate all "names" (textures, buffers, FBO, ...). Only in Compatibility Profile you are allowed to provide your own "name" values
🗪
2:34:27mmozeiko Q: In GL Core Profile you need to generate all "names" (textures, buffers, FBO, ...). Only in Compatibility Profile you are allowed to provide your own "name" values
🗪
2:34:27mmozeiko Q: In GL Core Profile you need to generate all "names" (textures, buffers, FBO, ...). Only in Compatibility Profile you are allowed to provide your own "name" values
🗪
2:34:49lkalinovcic Q: Unrelated: What's the recommended way to deal with Windows doing an infinite WindowProc loop while moving or resizing a window? My current approach is to jump in and out of the event processing loop with fibers. Is there something less hacky?
🗪
2:34:49lkalinovcic Q: Unrelated: What's the recommended way to deal with Windows doing an infinite WindowProc loop while moving or resizing a window? My current approach is to jump in and out of the event processing loop with fibers. Is there something less hacky?
🗪
2:34:49lkalinovcic Q: Unrelated: What's the recommended way to deal with Windows doing an infinite WindowProc loop while moving or resizing a window? My current approach is to jump in and out of the event processing loop with fibers. Is there something less hacky?
🗪
2:36:14mmozeiko Q: You probably would want to replace glTexStorage3D() call with glTexImage3D(). TexStorage is from OpenGL 4.2 version (or ARB_texture_storage extension). TexStorage differs from TexImage in a way that its texture properties (size / format) are immutable – it cannot be changed once texture is created. It may help performance but often it does not change
🗪
2:36:14mmozeiko Q: You probably would want to replace glTexStorage3D() call with glTexImage3D(). TexStorage is from OpenGL 4.2 version (or ARB_texture_storage extension). TexStorage differs from TexImage in a way that its texture properties (size / format) are immutable – it cannot be changed once texture is created. It may help performance but often it does not change
🗪
2:36:14mmozeiko Q: You probably would want to replace glTexStorage3D() call with glTexImage3D(). TexStorage is from OpenGL 4.2 version (or ARB_texture_storage extension). TexStorage differs from TexImage in a way that its texture properties (size / format) are immutable – it cannot be changed once texture is created. It may help performance but often it does not change
🗪
2:36:58Replace glTexStorage3D() with glTexImage3D()13
2:36:58Replace glTexStorage3D() with glTexImage3D()13
2:36:58Replace glTexStorage3D() with glTexImage3D()13
2:40:04vateferfout Q: Do you still multiply the offset in the glDrawElementsBaseVertex() call? Because I never do it and never had any problem, so I don't understand what's going on14,15
🗪
2:40:04vateferfout Q: Do you still multiply the offset in the glDrawElementsBaseVertex() call? Because I never do it and never had any problem, so I don't understand what's going on14,15
🗪
2:40:04vateferfout Q: Do you still multiply the offset in the glDrawElementsBaseVertex() call? Because I never do it and never had any problem, so I don't understand what's going on14,15
🗪
2:44:19mmozeiko Q: Please show glTexSubImage3D() call that fails
🗪
🏃
2:44:19mmozeiko Q: Please show glTexSubImage3D() call that fails
🗪
🏃
2:44:19mmozeiko Q: Please show glTexSubImage3D() call that fails
🗪
🏃
2:47:38mmozeiko Q: It needs to be GL_RGBA or whatever (value does not matter, because it is for last argument pixel data, which is NULL, so no data specified)
🗪
2:47:38mmozeiko Q: It needs to be GL_RGBA or whatever (value does not matter, because it is for last argument pixel data, which is NULL, so no data specified)
🗪
2:47:38mmozeiko Q: It needs to be GL_RGBA or whatever (value does not matter, because it is for last argument pixel data, which is NULL, so no data specified)
🗪
2:48:28mmozeiko Q: "does not matter", as long as it is valid, nonzero
🗪
2:48:28mmozeiko Q: "does not matter", as long as it is valid, nonzero
🗪
2:48:28mmozeiko Q: "does not matter", as long as it is valid, nonzero
🗪
2:49:49cemuzunlar Q: I think glTexImage3D() is the failing call. Can you please check the call stack again at crash time?
🗪
2:49:49cemuzunlar Q: I think glTexImage3D() is the failing call. Can you please check the call stack again at crash time?
🗪
2:49:49cemuzunlar Q: I think glTexImage3D() is the failing call. Can you please check the call stack again at crash time?
🗪
2:51:45Wrap it up with the determination to find out why we can't use glTexImage3D() here in OpenGLInit(), and a plug of Casey and Chris Hecker's upcoming talks at Busan Indie Connect Festival 201816
🗩
2:51:45Wrap it up with the determination to find out why we can't use glTexImage3D() here in OpenGLInit(), and a plug of Casey and Chris Hecker's upcoming talks at Busan Indie Connect Festival 201816
🗩
2:51:45Wrap it up with the determination to find out why we can't use glTexImage3D() here in OpenGLInit(), and a plug of Casey and Chris Hecker's upcoming talks at Busan Indie Connect Festival 201816
🗩