Skip to content

Commit 7510282

Browse files
committed
Don't discard state where possible
1 parent 6d667cf commit 7510282

File tree

3 files changed

+43
-30
lines changed

3 files changed

+43
-30
lines changed

src/Renderer/ClusteredRenderer.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ void ClusteredRenderer::onRender(float dt)
100100

101101
lights.bindLights(scene);
102102
clusters.bindBuffers(false); // write access, all buffers
103+
103104
bgfx::dispatch(vLightCulling,
104105
lightCullingComputeProgram,
105106
ClusterShader::CLUSTERS_X / ClusterShader::CLUSTERS_X_THREADS,
@@ -112,6 +113,9 @@ void ClusteredRenderer::onRender(float dt)
112113

113114
uint64_t state = BGFX_STATE_DEFAULT & ~BGFX_STATE_CULL_MASK;
114115

116+
lights.bindLights(scene);
117+
clusters.bindBuffers(true /*lightingPass*/); // read access, only light grid and indices
118+
115119
for(const Mesh& mesh : scene->meshes)
116120
{
117121
glm::mat4 model = glm::identity<glm::mat4>();
@@ -122,11 +126,11 @@ void ClusteredRenderer::onRender(float dt)
122126
const Material& mat = scene->materials[mesh.material];
123127
uint64_t materialState = pbr.bindMaterial(mat);
124128
bgfx::setState(state | materialState);
125-
lights.bindLights(scene);
126-
clusters.bindBuffers();
127-
// TODO compute bindings don't seem to be preserved despite excluding BGFX_DISCARD_COMPUTE
128-
bgfx::submit(vLighting, program, 0, BGFX_DISCARD_ALL & ~BGFX_DISCARD_COMPUTE);
129+
// preserve buffer bindings between submit calls
130+
bgfx::submit(vLighting, program, 0, ~BGFX_DISCARD_TEXTURE_SAMPLERS);
129131
}
132+
133+
bgfx::discard(BGFX_DISCARD_ALL);
130134
}
131135

132136
void ClusteredRenderer::onShutdown()

src/Renderer/DeferredRenderer.cpp

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -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

290297
void 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] =

src/Renderer/ForwardRenderer.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ void ForwardRenderer::onRender(float dt)
4141

4242
uint64_t state = BGFX_STATE_DEFAULT & ~BGFX_STATE_CULL_MASK;
4343

44+
lights.bindLights(scene);
45+
4446
for(const Mesh& mesh : scene->meshes)
4547
{
4648
glm::mat4 model = glm::identity<glm::mat4>();
@@ -50,10 +52,11 @@ void ForwardRenderer::onRender(float dt)
5052
bgfx::setIndexBuffer(mesh.indexBuffer);
5153
const Material& mat = scene->materials[mesh.material];
5254
uint64_t materialState = pbr.bindMaterial(mat);
53-
lights.bindLights(scene);
5455
bgfx::setState(state | materialState);
55-
bgfx::submit(vDefault, program);
56+
bgfx::submit(vDefault, program, 0, ~BGFX_DISCARD_TEXTURE_SAMPLERS);
5657
}
58+
59+
bgfx::discard(BGFX_DISCARD_ALL);
5760
}
5861

5962
void ForwardRenderer::onShutdown()

0 commit comments

Comments
 (0)