Single file

- Upload instancers and model indices in separate loops in an
  IndirectCullingGroup
- Reset changed bitset and update last* in separate method
- Don't need to upload instances anymore if the model index changes
This commit is contained in:
Jozufozu 2024-03-24 15:30:22 -05:00
parent ff7130c71c
commit 5775eb863f
2 changed files with 39 additions and 15 deletions

View file

@ -235,8 +235,16 @@ public class IndirectCullingGroup<I extends Instance> {
} }
private void uploadInstances(StagingBuffer stagingBuffer) { private void uploadInstances(StagingBuffer stagingBuffer) {
for (var model : instancers) { for (var instancer : instancers) {
model.uploadInstances(stagingBuffer, buffers.instance.handle(), buffers.modelIndex.handle()); instancer.uploadInstances(stagingBuffer, buffers.instance.handle());
}
for (var instancer : instancers) {
instancer.uploadModelIndices(stagingBuffer, buffers.modelIndex.handle());
}
for (var instancer : instancers) {
instancer.resetChanged();
} }
} }

View file

@ -53,30 +53,36 @@ public class IndirectInstancer<I extends Instance> extends AbstractInstancer<I>
MemoryUtil.memPutFloat(ptr + 20, boundingSphere.w()); MemoryUtil.memPutFloat(ptr + 20, boundingSphere.w());
} }
public void uploadInstances(StagingBuffer stagingBuffer, int instanceVbo, int modelIndexVbo) { public void uploadInstances(StagingBuffer stagingBuffer, int instanceVbo) {
long baseByte = baseInstance * instanceStride; long baseByte = baseInstance * instanceStride;
if (baseInstance != lastBaseInstance) {
uploadAllInstances(stagingBuffer, baseByte, instanceVbo);
} else {
uploadChangedInstances(stagingBuffer, baseByte, instanceVbo);
}
}
public void uploadModelIndices(StagingBuffer stagingBuffer, int modelIndexVbo) {
long modelIndexBaseByte = baseInstance * IndirectBuffers.INT_SIZE; long modelIndexBaseByte = baseInstance * IndirectBuffers.INT_SIZE;
if (shouldUploadAll()) { if (baseInstance != lastBaseInstance || index != lastModelIndex) {
uploadAll(stagingBuffer, baseByte, modelIndexBaseByte, instanceVbo, modelIndexVbo); uploadAllModelIndices(stagingBuffer, modelIndexBaseByte, modelIndexVbo);
} else { } else {
uploadChanged(stagingBuffer, baseByte, modelIndexBaseByte, instanceVbo, modelIndexVbo); uploadChangedModelIndices(stagingBuffer, modelIndexBaseByte, modelIndexVbo);
} }
}
changed.clear(); public void resetChanged() {
lastModelIndex = index; lastModelIndex = index;
lastBaseInstance = baseInstance; lastBaseInstance = baseInstance;
changed.clear();
} }
private boolean shouldUploadAll() { private void uploadChangedInstances(StagingBuffer stagingBuffer, long baseByte, int instanceVbo) {
return baseInstance != lastBaseInstance || index != lastModelIndex;
}
private void uploadChanged(StagingBuffer stagingBuffer, long baseByte, long modelIndexBaseByte, int instanceVbo, int modelIndexVbo) {
changed.forEachSetSpan((startInclusive, endInclusive) -> { changed.forEachSetSpan((startInclusive, endInclusive) -> {
int instanceCount = endInclusive - startInclusive + 1; int instanceCount = endInclusive - startInclusive + 1;
long totalSize = instanceCount * instanceStride; long totalSize = instanceCount * instanceStride;
long modelIndexTotalSize = instanceCount * IndirectBuffers.INT_SIZE;
stagingBuffer.enqueueCopy(totalSize, instanceVbo, baseByte + startInclusive * instanceStride, ptr -> { stagingBuffer.enqueueCopy(totalSize, instanceVbo, baseByte + startInclusive * instanceStride, ptr -> {
for (int i = startInclusive; i <= endInclusive; i++) { for (int i = startInclusive; i <= endInclusive; i++) {
@ -85,6 +91,13 @@ public class IndirectInstancer<I extends Instance> extends AbstractInstancer<I>
ptr += instanceStride; ptr += instanceStride;
} }
}); });
});
}
private void uploadChangedModelIndices(StagingBuffer stagingBuffer, long modelIndexBaseByte, int modelIndexVbo) {
changed.forEachSetSpan((startInclusive, endInclusive) -> {
int instanceCount = endInclusive - startInclusive + 1;
long modelIndexTotalSize = instanceCount * IndirectBuffers.INT_SIZE;
stagingBuffer.enqueueCopy(modelIndexTotalSize, modelIndexVbo, modelIndexBaseByte + startInclusive * IndirectBuffers.INT_SIZE, ptr -> { stagingBuffer.enqueueCopy(modelIndexTotalSize, modelIndexVbo, modelIndexBaseByte + startInclusive * IndirectBuffers.INT_SIZE, ptr -> {
for (int i = startInclusive; i <= endInclusive; i++) { for (int i = startInclusive; i <= endInclusive; i++) {
@ -95,9 +108,8 @@ public class IndirectInstancer<I extends Instance> extends AbstractInstancer<I>
}); });
} }
private void uploadAll(StagingBuffer stagingBuffer, long baseByte, long modelIndexBaseByte, int instanceVbo, int modelIndexVbo) { private void uploadAllInstances(StagingBuffer stagingBuffer, long baseByte, int instanceVbo) {
long totalSize = instances.size() * instanceStride; long totalSize = instances.size() * instanceStride;
long modelIndexTotalSize = instances.size() * IndirectBuffers.INT_SIZE;
stagingBuffer.enqueueCopy(totalSize, instanceVbo, baseByte, ptr -> { stagingBuffer.enqueueCopy(totalSize, instanceVbo, baseByte, ptr -> {
for (I instance : instances) { for (I instance : instances) {
@ -105,6 +117,10 @@ public class IndirectInstancer<I extends Instance> extends AbstractInstancer<I>
ptr += instanceStride; ptr += instanceStride;
} }
}); });
}
private void uploadAllModelIndices(StagingBuffer stagingBuffer, long modelIndexBaseByte, int modelIndexVbo) {
long modelIndexTotalSize = instances.size() * IndirectBuffers.INT_SIZE;
stagingBuffer.enqueueCopy(modelIndexTotalSize, modelIndexVbo, modelIndexBaseByte, ptr -> { stagingBuffer.enqueueCopy(modelIndexTotalSize, modelIndexVbo, modelIndexBaseByte, ptr -> {
for (int i = 0; i < instances.size(); i++) { for (int i = 0; i < instances.size(); i++) {