mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-03-03 22:24:40 +01:00
If you say so
- Only do OIT for materials marked ORDER_INDEPENDENT - Clean up some of the indirect frame logic, early out if there's nothing to do
This commit is contained in:
parent
c1ae6256e5
commit
026eb90566
3 changed files with 59 additions and 58 deletions
|
@ -146,7 +146,7 @@ public final class MaterialRenderState {
|
|||
RenderSystem.enableBlend();
|
||||
RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.DST_COLOR, GlStateManager.DestFactor.SRC_COLOR, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO);
|
||||
}
|
||||
case TRANSLUCENT, ORDER_INDEPENDENT -> {
|
||||
case TRANSLUCENT -> {
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ public class IndirectCullingGroup<I extends Instance> {
|
|||
private final List<IndirectInstancer<I>> instancers = new ArrayList<>();
|
||||
private final List<IndirectDraw> indirectDraws = new ArrayList<>();
|
||||
private final List<MultiDraw> multiDraws = new ArrayList<>();
|
||||
private final List<MultiDraw> transparentDraws = new ArrayList<>();
|
||||
private final List<MultiDraw> oitDraws = new ArrayList<>();
|
||||
|
||||
private final IndirectPrograms programs;
|
||||
private final GlProgram cullProgram;
|
||||
|
@ -57,7 +57,7 @@ public class IndirectCullingGroup<I extends Instance> {
|
|||
cullProgram = programs.getCullingProgram(instanceType);
|
||||
}
|
||||
|
||||
public void flushInstancers() {
|
||||
public boolean flushInstancers() {
|
||||
instanceCountThisFrame = 0;
|
||||
int modelIndex = 0;
|
||||
for (var iterator = instancers.iterator(); iterator.hasNext(); ) {
|
||||
|
@ -79,13 +79,17 @@ public class IndirectCullingGroup<I extends Instance> {
|
|||
if (indirectDraws.removeIf(IndirectDraw::deleted)) {
|
||||
needsDrawSort = true;
|
||||
}
|
||||
|
||||
var out = indirectDraws.isEmpty();
|
||||
|
||||
if (out) {
|
||||
delete();
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
public void upload(StagingBuffer stagingBuffer) {
|
||||
if (nothingToDo()) {
|
||||
return;
|
||||
}
|
||||
|
||||
buffers.updateCounts(instanceCountThisFrame, instancers.size(), indirectDraws.size());
|
||||
|
||||
// Upload only instances that have changed.
|
||||
|
@ -107,10 +111,6 @@ public class IndirectCullingGroup<I extends Instance> {
|
|||
}
|
||||
|
||||
public void dispatchCull() {
|
||||
if (nothingToDo()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Uniforms.bindAll();
|
||||
cullProgram.bind();
|
||||
|
||||
|
@ -119,21 +119,17 @@ public class IndirectCullingGroup<I extends Instance> {
|
|||
}
|
||||
|
||||
public void dispatchApply() {
|
||||
if (nothingToDo()) {
|
||||
return;
|
||||
}
|
||||
|
||||
buffers.bindForApply();
|
||||
glDispatchCompute(GlCompat.getComputeGroupCount(indirectDraws.size()), 1, 1);
|
||||
}
|
||||
|
||||
private boolean nothingToDo() {
|
||||
return indirectDraws.isEmpty() || instanceCountThisFrame == 0;
|
||||
public boolean hasOitDraws() {
|
||||
return !oitDraws.isEmpty();
|
||||
}
|
||||
|
||||
private void sortDraws() {
|
||||
multiDraws.clear();
|
||||
transparentDraws.clear();
|
||||
oitDraws.clear();
|
||||
// sort by visual type, then material
|
||||
indirectDraws.sort(DRAW_COMPARATOR);
|
||||
|
||||
|
@ -143,7 +139,7 @@ public class IndirectCullingGroup<I extends Instance> {
|
|||
// if the next draw call has a different VisualType or Material, start a new MultiDraw
|
||||
if (i == indirectDraws.size() - 1 || incompatibleDraws(draw1, indirectDraws.get(i + 1))) {
|
||||
var dst = draw1.material()
|
||||
.transparency() == Transparency.TRANSLUCENT ? transparentDraws : multiDraws;
|
||||
.transparency() == Transparency.ORDER_INDEPENDENT ? oitDraws : multiDraws;
|
||||
dst.add(new MultiDraw(draw1.material(), draw1.isEmbedded(), start, i + 1));
|
||||
start = i + 1;
|
||||
}
|
||||
|
@ -178,7 +174,7 @@ public class IndirectCullingGroup<I extends Instance> {
|
|||
}
|
||||
|
||||
public void submitSolid() {
|
||||
if (nothingToDo()) {
|
||||
if (multiDraws.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -204,7 +200,7 @@ public class IndirectCullingGroup<I extends Instance> {
|
|||
}
|
||||
|
||||
public void submitTransparent(PipelineCompiler.OitMode oit) {
|
||||
if (nothingToDo()) {
|
||||
if (oitDraws.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -214,7 +210,7 @@ public class IndirectCullingGroup<I extends Instance> {
|
|||
|
||||
GlProgram lastProgram = null;
|
||||
|
||||
for (var multiDraw : transparentDraws) {
|
||||
for (var multiDraw : oitDraws) {
|
||||
var drawProgram = programs.getIndirectProgram(instanceType, multiDraw.embedded ? ContextShader.EMBEDDED : ContextShader.DEFAULT, multiDraw.material, oit);
|
||||
if (drawProgram != lastProgram) {
|
||||
lastProgram = drawProgram;
|
||||
|
@ -290,16 +286,6 @@ public class IndirectCullingGroup<I extends Instance> {
|
|||
buffers.delete();
|
||||
}
|
||||
|
||||
public boolean checkEmptyAndDelete() {
|
||||
var out = indirectDraws.isEmpty();
|
||||
|
||||
if (out) {
|
||||
delete();
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
private record MultiDraw(Material material, boolean embedded, int start, int end) {
|
||||
private void submit(GlProgram drawProgram) {
|
||||
GlCompat.safeMultiDrawElementsIndirect(drawProgram, GL_TRIANGLES, GL_UNSIGNED_INT, this.start, this.end, IndirectBuffers.DRAW_COMMAND_STRIDE);
|
||||
|
|
|
@ -85,13 +85,11 @@ public class IndirectDrawManager extends DrawManager<IndirectInstancer<?>> {
|
|||
public void render(LightStorage lightStorage, EnvironmentStorage environmentStorage) {
|
||||
super.render(lightStorage, environmentStorage);
|
||||
|
||||
for (var group : cullingGroups.values()) {
|
||||
group.flushInstancers();
|
||||
}
|
||||
|
||||
// Flush instance counts, page mappings, and prune empty groups.
|
||||
cullingGroups.values()
|
||||
.removeIf(IndirectCullingGroup::checkEmptyAndDelete);
|
||||
.removeIf(IndirectCullingGroup::flushInstancers);
|
||||
|
||||
// Instancers may have been emptied in the above call, now remove them here.
|
||||
instancers.values()
|
||||
.removeIf(instancer -> instancer.instanceCount() == 0);
|
||||
|
||||
|
@ -99,6 +97,12 @@ public class IndirectDrawManager extends DrawManager<IndirectInstancer<?>> {
|
|||
|
||||
stagingBuffer.reclaim();
|
||||
|
||||
// Genuinely nothing to do, we can just early out.
|
||||
// Still process the mesh pool and reclaim fenced staging regions though.
|
||||
if (cullingGroups.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
lightBuffers.flush(stagingBuffer, lightStorage);
|
||||
|
||||
matrixBuffer.flush(stagingBuffer, environmentStorage);
|
||||
|
@ -146,33 +150,44 @@ public class IndirectDrawManager extends DrawManager<IndirectInstancer<?>> {
|
|||
group.submitSolid();
|
||||
}
|
||||
|
||||
oitFramebuffer.prepare();
|
||||
|
||||
oitFramebuffer.depthRange();
|
||||
|
||||
// Let's avoid invoking the oit chain if we don't have anything to do
|
||||
boolean useOit = false;
|
||||
for (var group : cullingGroups.values()) {
|
||||
group.submitTransparent(PipelineCompiler.OitMode.DEPTH_RANGE);
|
||||
if (group.hasOitDraws()) {
|
||||
useOit = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
oitFramebuffer.renderTransmittance();
|
||||
if (useOit) {
|
||||
oitFramebuffer.prepare();
|
||||
|
||||
for (var group : cullingGroups.values()) {
|
||||
group.submitTransparent(PipelineCompiler.OitMode.GENERATE_COEFFICIENTS);
|
||||
oitFramebuffer.depthRange();
|
||||
|
||||
for (var group : cullingGroups.values()) {
|
||||
group.submitTransparent(PipelineCompiler.OitMode.DEPTH_RANGE);
|
||||
}
|
||||
|
||||
oitFramebuffer.renderTransmittance();
|
||||
|
||||
for (var group : cullingGroups.values()) {
|
||||
group.submitTransparent(PipelineCompiler.OitMode.GENERATE_COEFFICIENTS);
|
||||
}
|
||||
|
||||
oitFramebuffer.renderDepthFromTransmittance();
|
||||
|
||||
// Need to bind this again because we just drew a full screen quad for OIT.
|
||||
vertexArray.bindForDraw();
|
||||
|
||||
oitFramebuffer.shade();
|
||||
|
||||
for (var group : cullingGroups.values()) {
|
||||
group.submitTransparent(PipelineCompiler.OitMode.EVALUATE);
|
||||
}
|
||||
|
||||
oitFramebuffer.composite();
|
||||
}
|
||||
|
||||
oitFramebuffer.renderDepthFromTransmittance();
|
||||
|
||||
// Need to bind this again because we just drew a full screen quad for OIT.
|
||||
vertexArray.bindForDraw();
|
||||
|
||||
oitFramebuffer.shade();
|
||||
|
||||
for (var group : cullingGroups.values()) {
|
||||
group.submitTransparent(PipelineCompiler.OitMode.EVALUATE);
|
||||
}
|
||||
|
||||
oitFramebuffer.composite();
|
||||
|
||||
MaterialRenderState.reset();
|
||||
TextureBinder.resetLightAndOverlay();
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue