It dobedobedoba be partially working

This commit is contained in:
mcrcortex
2024-04-14 02:09:39 +10:00
parent 2b77800ed9
commit a25447a92b
6 changed files with 220 additions and 33 deletions

View File

@@ -63,17 +63,17 @@ public class Gl46MeshletsFarWorldRenderer extends AbstractFarWorldRenderer<Gl46M
this.meshletBuffer = new GlBuffer(4*1000000);//TODO: Make max meshlet count configurable, not just 1 million (even tho thats a max of 126 million quads per frame) this.meshletBuffer = new GlBuffer(4*1000000);//TODO: Make max meshlet count configurable, not just 1 million (even tho thats a max of 126 million quads per frame)
} }
protected void bindResources(Gl46MeshletViewport viewport) { protected void bindResources(Gl46MeshletViewport viewport, boolean bindToDrawIndirect) {
glBindBufferBase(GL_UNIFORM_BUFFER, 0, this.uniformBuffer.id); glBindBufferBase(GL_UNIFORM_BUFFER, 0, this.uniformBuffer.id);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, this.geometry.geometryId()); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, this.geometry.geometryId());
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, this.glDrawIndirect.id); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, bindToDrawIndirect?0:this.glDrawIndirect.id);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, this.meshletBuffer.id); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, this.meshletBuffer.id);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, this.geometry.metaId()); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, this.geometry.metaId());
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, viewport.visibilityBuffer.id); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, viewport.visibilityBuffer.id);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 6, this.models.getBufferId()); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 6, this.models.getBufferId());
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 7, this.models.getColourBufferId()); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 7, this.models.getColourBufferId());
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 8, this.lightDataBuffer.id);//Lighting LUT glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 8, this.lightDataBuffer.id);//Lighting LUT
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, this.glDrawIndirect.id); glBindBuffer(GL_DRAW_INDIRECT_BUFFER, bindToDrawIndirect?this.glDrawIndirect.id:0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, SharedIndexBuffer.INSTANCE.id()); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, SharedIndexBuffer.INSTANCE.id());
//Bind the texture atlas //Bind the texture atlas
@@ -115,6 +115,7 @@ public class Gl46MeshletsFarWorldRenderer extends AbstractFarWorldRenderer<Gl46M
glDisable(GL_BLEND); glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
RenderLayer.getCutoutMipped().startDrawing();
this.updateUniformBuffer(viewport); this.updateUniformBuffer(viewport);
UploadStream.INSTANCE.commit(); UploadStream.INSTANCE.commit();
@@ -123,21 +124,22 @@ public class Gl46MeshletsFarWorldRenderer extends AbstractFarWorldRenderer<Gl46M
nglClearNamedBufferSubData(this.glDrawIndirect.id, GL_R32UI, 4, 4, GL_RED_INTEGER, GL_UNSIGNED_INT, 0); nglClearNamedBufferSubData(this.glDrawIndirect.id, GL_R32UI, 4, 4, GL_RED_INTEGER, GL_UNSIGNED_INT, 0);
this.meshletGenerator.bind(); this.meshletGenerator.bind();
this.bindResources(viewport); this.bindResources(viewport, false);
glDispatchCompute((this.geometry.getSectionCount()+63)/64, 1, 1); glDispatchCompute((this.geometry.getSectionCount()+63)/64, 1, 1);
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT | GL_COMMAND_BARRIER_BIT); glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT | GL_COMMAND_BARRIER_BIT);
this.lodShader.bind(); this.lodShader.bind();
this.bindResources(viewport); this.bindResources(viewport, true);
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
//glDrawElementsInstanced(GL_TRIANGLES, 6*126, GL_UNSIGNED_SHORT, 0, 40000);
glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, 0); glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, 0);
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT | GL_FRAMEBUFFER_BARRIER_BIT); glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT | GL_FRAMEBUFFER_BARRIER_BIT);
this.cullShader.bind(); this.cullShader.bind();
this.bindResources(viewport); this.bindResources(viewport, false);
glDepthMask(false); glDepthMask(false);
glColorMask(false, false, false, false); glColorMask(false, false, false, false);
glDrawElementsInstanced(GL_TRIANGLES, 6 * 2 * 3, GL_UNSIGNED_BYTE, (1 << 16) * 6 * 2, this.geometry.getSectionCount()); glDrawElementsInstanced(GL_TRIANGLES, 6 * 2 * 3, GL_UNSIGNED_BYTE, (1 << 16) * 6 * 2, this.geometry.getSectionCount());
@@ -145,6 +147,11 @@ public class Gl46MeshletsFarWorldRenderer extends AbstractFarWorldRenderer<Gl46M
glDepthMask(true); glDepthMask(true);
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
glBindVertexArray(0);
glBindSampler(0, 0);
glBindTextureUnit(0, 0);
RenderLayer.getCutoutMipped().endDrawing();
} }

View File

@@ -30,6 +30,7 @@ public class RenderDataFactory {
private final LongArrayList translucentQuadCollector = new LongArrayList(); private final LongArrayList translucentQuadCollector = new LongArrayList();
private final LongArrayList[] directionalQuadCollectors = new LongArrayList[]{new LongArrayList(), new LongArrayList(), new LongArrayList(), new LongArrayList(), new LongArrayList(), new LongArrayList()}; private final LongArrayList[] directionalQuadCollectors = new LongArrayList[]{new LongArrayList(), new LongArrayList(), new LongArrayList(), new LongArrayList(), new LongArrayList(), new LongArrayList()};
private final boolean generateMeshlets = true;
private int minX; private int minX;
private int minY; private int minY;
@@ -51,6 +52,15 @@ public class RenderDataFactory {
// since fluid states are explicitly overlays over the base block // since fluid states are explicitly overlays over the base block
// can do funny stuff like double rendering // can do funny stuff like double rendering
private static final boolean USE_UINT64 = false;//FIXME: replace with automatic detection of uint64 shader extension support
private static void writePos(long ptr, long pos) {
if (USE_UINT64) {
MemoryUtil.memPutLong(ptr, pos);
} else {
MemoryUtil.memPutInt(ptr, (int) (pos>>32));
MemoryUtil.memPutInt(ptr + 4, (int)pos);
}
}
//section is already acquired and gets released by the parent //section is already acquired and gets released by the parent
public BuiltSection generateMesh(WorldSection section) { public BuiltSection generateMesh(WorldSection section) {
@@ -76,38 +86,122 @@ public class RenderDataFactory {
this.generateMeshForAxis(section, 1);//Direction.Axis.Z this.generateMeshForAxis(section, 1);//Direction.Axis.Z
this.generateMeshForAxis(section, 2);//Direction.Axis.X this.generateMeshForAxis(section, 2);//Direction.Axis.X
int quadCount = this.doubleSidedQuadCollector.size() + this.translucentQuadCollector.size(); int bufferSize;
for (var collector : this.directionalQuadCollectors) { if (this.generateMeshlets) {
quadCount += collector.size(); bufferSize = getMeshletHoldingCount(this.doubleSidedQuadCollector.size(), 126, 128) +
getMeshletHoldingCount(this.translucentQuadCollector.size(), 126, 128);
for (var collector : this.directionalQuadCollectors) {
bufferSize += getMeshletHoldingCount(collector.size(), 126, 128);
}
} else {
bufferSize = this.doubleSidedQuadCollector.size() + this.translucentQuadCollector.size();
for (var collector : this.directionalQuadCollectors) {
bufferSize += collector.size();
}
} }
if (quadCount == 0) { if (bufferSize == 0) {
return new BuiltSection(section.key); return new BuiltSection(section.key);
} }
//TODO: generate the meshlets here //TODO: generate the meshlets here
MemoryBuffer buff;
var buff = new MemoryBuffer(quadCount*8L);
long ptr = buff.address;
int[] offsets = new int[8]; int[] offsets = new int[8];
int coff = 0; if (this.generateMeshlets) {
long key = section.key;
buff = new MemoryBuffer(bufferSize * 8L);
long ptr = buff.address;
MemoryUtil.memSet(ptr, -1, bufferSize * 8L);
int meshlet = 0;
int innerQuadCount = 0;
//Ordering is: translucent, double sided quads, directional quads //Ordering is: translucent, double sided quads, directional quads
offsets[0] = coff; offsets[0] = meshlet;
for (long data : this.translucentQuadCollector) { for (long data : this.translucentQuadCollector) {
MemoryUtil.memPutLong(ptr + ((coff++)*8L), data); if (innerQuadCount == 0) {
} //Write out meshlet header
offsets[1] = coff; //Write out the section position
for (long data : this.doubleSidedQuadCollector) { writePos(ptr + meshlet * 8L * 128L, key);
MemoryUtil.memPutLong(ptr + ((coff++)*8L), data); MemoryUtil.memPutLong(ptr + meshlet * 8L * 128L + 8, 0);
} }
MemoryUtil.memPutLong(ptr + meshlet * 8L * 128 + (2 + innerQuadCount++) * 8L, data);
if (innerQuadCount == 126) {
innerQuadCount = 0;
meshlet++;
}
}
for (int face = 0; face < 6; face++) { if (innerQuadCount != 0) {
offsets[face+2] = coff; meshlet++;
for (long data : this.directionalQuadCollectors[face]) { innerQuadCount = 0;
}
offsets[1] = meshlet;
for (long data : this.doubleSidedQuadCollector) {
if (innerQuadCount == 0) {
//Write out meshlet header
//Write out the section position
writePos(ptr + meshlet * 8L * 128L, key);
MemoryUtil.memPutLong(ptr + meshlet * 8L * 128L + 8, 0);
}
MemoryUtil.memPutLong(ptr + meshlet * 8L * 128 + (2 + innerQuadCount++) * 8L, data);
if (innerQuadCount == 126) {
innerQuadCount = 0;
meshlet++;
}
}
if (innerQuadCount != 0) {
meshlet++;
innerQuadCount = 0;
}
for (int face = 0; face < 6; face++) {
offsets[face + 2] = meshlet;
for (long data : this.directionalQuadCollectors[face]) {
if (innerQuadCount == 0) {
//Write out meshlet header
//Write out the section position
writePos(ptr + meshlet * 8L * 128L, key);
MemoryUtil.memPutLong(ptr + meshlet * 8L * 128L + 8, 0);
}
MemoryUtil.memPutLong(ptr + meshlet * 8L * 128 + (2 + innerQuadCount++) * 8L, data);
if (innerQuadCount == 126) {
innerQuadCount = 0;
meshlet++;
}
}
if (innerQuadCount != 0) {
meshlet++;
innerQuadCount = 0;
}
}
} else {
buff = new MemoryBuffer(bufferSize * 8L);
long ptr = buff.address;
int coff = 0;
//Ordering is: translucent, double sided quads, directional quads
offsets[0] = coff;
for (long data : this.translucentQuadCollector) {
MemoryUtil.memPutLong(ptr + ((coff++) * 8L), data); MemoryUtil.memPutLong(ptr + ((coff++) * 8L), data);
} }
offsets[1] = coff;
for (long data : this.doubleSidedQuadCollector) {
MemoryUtil.memPutLong(ptr + ((coff++) * 8L), data);
}
for (int face = 0; face < 6; face++) {
offsets[face + 2] = coff;
for (long data : this.directionalQuadCollectors[face]) {
MemoryUtil.memPutLong(ptr + ((coff++) * 8L), data);
}
}
} }
int aabb = 0; int aabb = 0;
@@ -323,4 +417,12 @@ public class RenderDataFactory {
} }
} }
} }
private static int getMeshletHoldingCount(int quads, int quadsPerMeshlet, int meshletSize) {
return ((quads+(quadsPerMeshlet-1))/quadsPerMeshlet)*meshletSize;
}
public static int alignUp(int n, int alignment) {
return (n + alignment - 1) & -alignment;
}
} }

View File

@@ -1,3 +1,4 @@
#line 1
struct Frustum { struct Frustum {
vec4 planes[6]; vec4 planes[6];
}; };
@@ -51,7 +52,7 @@ layout(binding = 2, std430) restrict buffer DrawBuffer {
DrawCommand drawCmd; DrawCommand drawCmd;
}; };
#ifndef Quad #ifndef MESHLET_ACCESS
#define MESHLET_ACCESS readonly writeonly #define MESHLET_ACCESS readonly writeonly
#endif #endif
layout(binding = 3, std430) MESHLET_ACCESS restrict buffer MeshletListData { layout(binding = 3, std430) MESHLET_ACCESS restrict buffer MeshletListData {

View File

@@ -1,3 +1,14 @@
#version 450 #version 460 core
#extension GL_ARB_gpu_shader_int64 : enable
#define VISIBILITY_ACCESS writeonly
#import <voxy:lod/gl46mesh/bindings.glsl>
layout(early_fragment_tests) in;
flat in uint id;
flat in uint value;
out vec4 colour;
void main() { void main() {
visibilityData[id] = value;
colour = vec4(float(id&7u)/7, float((id>>3)&7u)/7, float((id>>6)&7u)/7, 1);
} }

View File

@@ -1,3 +1,30 @@
#version 450 #version 460 core
#extension GL_ARB_gpu_shader_int64 : enable
#define VISIBILITY_ACCESS writeonly
#import <voxy:lod/gl46mesh/bindings.glsl>
#import <voxy:lod/section.glsl>
flat out uint id;
flat out uint value;
void main() { void main() {
uint sid = gl_InstanceID;
SectionMeta section = sectionData[sid];
uint detail = extractDetail(section);
ivec3 ipos = extractPosition(section);
ivec3 aabbOffset = extractAABBOffset(section);
ivec3 size = extractAABBSize(section);
//Transform ipos with respect to the vertex corner
ivec3 pos = (((ipos<<detail)-baseSectionPos)<<5);
pos += (aabbOffset-1)*(1<<detail);
pos += (ivec3(gl_VertexID&1, (gl_VertexID>>2)&1, (gl_VertexID>>1)&1)*(size+2))*(1<<detail);
gl_Position = MVP * vec4(vec3(pos),1);
//Write to this id
id = sid;
value = frameId;
} }

View File

@@ -7,10 +7,35 @@
#define MESHLET_SIZE (QUADS_PER_MESHLET+2) #define MESHLET_SIZE (QUADS_PER_MESHLET+2)
#import <voxy:lod/quad_format.glsl> #import <voxy:lod/quad_format.glsl>
#import <voxy:lod/gl46mesh/bindings.glsl> #import <voxy:lod/gl46mesh/bindings.glsl>
#import <voxy:lod/section.glsl> #define PosHeader Quad
#define GEOMETRY_FMT Quad
GEOMETRY_FMT meshletPosition;
#ifdef GL_ARB_gpu_shader_int64
ivec3 extractPosition(PosHeader pos64) {
//((long)lvl<<60)|((long)(y&0xFF)<<52)|((long)(z&((1<<24)-1))<<28)|((long)(x&((1<<24)-1))<<4);
//return ivec3((pos64<<4)&uint64_t(0xFFFFFFFF),(pos64>>28)&uint64_t(0xFFFFFFFF),(pos64>>24)&uint64_t(0xFFFFFFFF))>>ivec3(8,24,8);
return (ivec3(int(pos64>>4)&((1<<24)-1), int(pos64>>52)&0xFF, int(pos64>>28)&((1<<24)-1))<<ivec3(8,24,8))>>ivec3(8,24,8);
}
uint extractDetail(PosHeader pos64) {
return uint(pos64>>60);
}
#else
ivec3 extractPosition(PosHeader pos) {
int y = ((int(pos.x)<<4)>>24);
int x = (int(pos.y)<<4)>>8;
int z = int((pos.x&((1<<20)-1))<<4);
z |= int(pos.y>>28)&0xF;
z <<= 8;
z >>= 8;
return ivec3(x,y,z);
}
uint extractDetail(PosHeader pos) {
return uint(pos.x)>>28;
}
#endif
PosHeader meshletPosition;
Quad quad; Quad quad;
bool setupMeshlet() { bool setupMeshlet() {
gl_CullDistance[0] = 1; gl_CullDistance[0] = 1;
@@ -23,7 +48,7 @@ bool setupMeshlet() {
return true; return true;
} }
uint baseId = (data*QUADS_PER_MESHLET); uint baseId = (data*MESHLET_SIZE);
uint quadIndex = baseId + (gl_VertexID>>2) + 2; uint quadIndex = baseId + (gl_VertexID>>2) + 2;
meshletPosition = geometryPool[baseId]; meshletPosition = geometryPool[baseId];
quad = geometryPool[quadIndex]; quad = geometryPool[quadIndex];
@@ -35,7 +60,21 @@ bool setupMeshlet() {
} }
void main() { void main() {
if (setupMeshlet()) { if (setupMeshlet()) {
gl_Position = vec4(1.0f/0.0f);
return; return;
} }
if ((gl_VertexID>>2)!=0) {
gl_Position = vec4(1.0f/0.0f);
return;
}
uint detail = extractDetail(meshletPosition);
ivec3 sectionPos = extractPosition(meshletPosition);
ivec3 pos = (((sectionPos<<detail)-baseSectionPos)<<5);
pos += ivec3(gl_VertexID&1, 0, (gl_VertexID>>1)&1)*(1<<detail);
gl_Position = MVP * vec4(vec3(pos),1);
} }