@@ -194,7 +194,7 @@ void DeferredRenderer::onRender(float dt)
194194 for (const Mesh& mesh : scene->meshes )
195195 {
196196 const Material& mat = scene->materials [mesh.material ];
197- // transparent materials are rendered in a seperate forward pass (view vTransparent)
197+ // transparent materials are rendered in a separate forward pass (view vTransparent)
198198 if (!mat.blend )
199199 {
200200 glm::mat4 model = glm::identity<glm::mat4>();
@@ -208,41 +208,48 @@ void DeferredRenderer::onRender(float dt)
208208 }
209209 }
210210
211- // render lights to framebuffer
212- // cull with light geometry
213- // - axis-aligned bounding box (TODO? sphere for point lights)
214- // - read depth from geometry pass
215- // - reverse depth test
216- // - render backfaces
217- // - this shades all pixels between camera and backfaces
218- // accumulate light contributions (blend mode add)
219- // TODO? tiled-deferred is probably faster for small lights
220- // https://software.intel.com/sites/default/files/m/d/4/1/d/8/lauritzen_deferred_shading_siggraph_2010.pdf
221-
222211 // copy G-Buffer depth attachment to depth texture for sampling in the light pass
223212 // we can't attach it to the frame buffer and read it in the shader (unprojecting world position) at the same time
224213 // blit happens before any compute or draw calls
225214 bgfx::blit (vFullscreenLight, lightDepthTexture, 0 , 0 , bgfx::getTexture (gBuffer , GBufferAttachment::Depth));
226215
216+ // bind these once for all following submits
217+ // excluding BGFX_DISCARD_TEXTURE_SAMPLERS from the discard flags passed to submit makes sure
218+ // they don't get unbound
219+ bindGBuffer ();
220+ lights.bindLights (scene);
221+
227222 // ambient light + emissive
228223
229224 // full screen triangle
230225 // could also attach the accumulation buffer as a render target and write out during the geometry pass
231226 // this is a bit cleaner
232227
233- // move triangle to far plane
228+ // move triangle to far plane (z = 1)
234229 // only render if the geometry is in front so we leave the background untouched
235230 glm::mat4 model = glm::identity<glm::mat4>();
236231 model = glm::translate (model, glm::vec3 (0 .0f , 0 .0f , 1 .0f ));
237232 bgfx::setTransform (glm::value_ptr (model));
238233 bgfx::setVertexBuffer (0 , blitTriangleBuffer);
239- bindGBuffer ();
240- lights.bindLights (scene);
241234 bgfx::setState (BGFX_STATE_WRITE_RGB | BGFX_STATE_DEPTH_TEST_GREATER | BGFX_STATE_CULL_CW);
242- bgfx::submit (vFullscreenLight, fullscreenProgram);
235+ bgfx::submit (vFullscreenLight, fullscreenProgram, 0 , ~BGFX_DISCARD_TEXTURE_SAMPLERS );
243236
244237 // point lights
245238
239+ // render lights to framebuffer
240+ // cull with light geometry
241+ // - axis-aligned bounding box (TODO? sphere for point lights)
242+ // - read depth from geometry pass
243+ // - reverse depth test
244+ // - render backfaces
245+ // - this shades all pixels between camera and backfaces
246+ // accumulate light contributions (blend mode add)
247+ // TODO? tiled-deferred is probably faster for small lights
248+ // https://software.intel.com/sites/default/files/m/d/4/1/d/8/lauritzen_deferred_shading_siggraph_2010.pdf
249+
250+ bgfx::setVertexBuffer (0 , pointLightVertexBuffer);
251+ bgfx::setIndexBuffer (pointLightIndexBuffer);
252+
246253 for (size_t i = 0 ; i < scene->pointLights .lights .size (); i++)
247254 {
248255 // position light geometry (bounding box)
@@ -256,15 +263,14 @@ void DeferredRenderer::onRender(float dt)
256263 glm::mat4 translate = glm::translate (glm::identity<glm::mat4>(), light.position );
257264 glm::mat4 model = translate * scale;
258265 bgfx::setTransform (glm::value_ptr (model));
259- bgfx::setVertexBuffer (0 , pointLightVertexBuffer);
260- bgfx::setIndexBuffer (pointLightIndexBuffer);
261266 float lightIndexVec[4 ] = { (float )i };
262267 bgfx::setUniform (lightIndexVecUniform, lightIndexVec);
263- bindGBuffer ();
264- lights.bindLights (scene);
265268 bgfx::setState (BGFX_STATE_WRITE_RGB | BGFX_STATE_DEPTH_TEST_GEQUAL | BGFX_STATE_CULL_CCW |
266269 BGFX_STATE_BLEND_ADD);
267- bgfx::submit (vLight, pointLightProgram);
270+ bgfx::submit (vLight,
271+ pointLightProgram,
272+ 0 ,
273+ ~(BGFX_DISCARD_VERTEX_STREAMS | BGFX_DISCARD_INDEX_BUFFER | BGFX_DISCARD_TEXTURE_SAMPLERS));
268274 }
269275
270276 // transparent
@@ -280,11 +286,12 @@ void DeferredRenderer::onRender(float dt)
280286 bgfx::setVertexBuffer (0 , mesh.vertexBuffer );
281287 bgfx::setIndexBuffer (mesh.indexBuffer );
282288 uint64_t materialState = pbr.bindMaterial (mat);
283- lights.bindLights (scene);
284289 bgfx::setState (state | materialState);
285- bgfx::submit (vTransparent, transparencyProgram);
290+ bgfx::submit (vTransparent, transparencyProgram, 0 , ~BGFX_DISCARD_TEXTURE_SAMPLERS );
286291 }
287292 }
293+
294+ bgfx::discard (BGFX_DISCARD_ALL);
288295}
289296
290297void DeferredRenderer::onShutdown ()
@@ -330,7 +337,6 @@ bgfx::FrameBufferHandle DeferredRenderer::createGBuffer()
330337 bgfx::BackbufferRatio::Equal, false , 1 , gBufferAttachmentFormats [i], BGFX_TEXTURE_RT | samplerFlags);
331338 }
332339
333- // not write only
334340 bgfx::TextureFormat::Enum depthFormat = findDepthFormat (BGFX_TEXTURE_RT | samplerFlags);
335341 assert (depthFormat != bgfx::TextureFormat::Count);
336342 textures[Depth] =
0 commit comments