It dobedobedoba be partially working
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
protected void bindResources(Gl46MeshletViewport viewport) {
|
||||
protected void bindResources(Gl46MeshletViewport viewport, boolean bindToDrawIndirect) {
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, 0, this.uniformBuffer.id);
|
||||
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, 4, this.geometry.metaId());
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, viewport.visibilityBuffer.id);
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 6, this.models.getBufferId());
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 7, this.models.getColourBufferId());
|
||||
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());
|
||||
|
||||
//Bind the texture atlas
|
||||
@@ -115,6 +115,7 @@ public class Gl46MeshletsFarWorldRenderer extends AbstractFarWorldRenderer<Gl46M
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
RenderLayer.getCutoutMipped().startDrawing();
|
||||
|
||||
this.updateUniformBuffer(viewport);
|
||||
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);
|
||||
|
||||
this.meshletGenerator.bind();
|
||||
this.bindResources(viewport);
|
||||
this.bindResources(viewport, false);
|
||||
glDispatchCompute((this.geometry.getSectionCount()+63)/64, 1, 1);
|
||||
|
||||
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT | GL_COMMAND_BARRIER_BIT);
|
||||
|
||||
this.lodShader.bind();
|
||||
this.bindResources(viewport);
|
||||
this.bindResources(viewport, true);
|
||||
glDisable(GL_CULL_FACE);
|
||||
//glDrawElementsInstanced(GL_TRIANGLES, 6*126, GL_UNSIGNED_SHORT, 0, 40000);
|
||||
glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, 0);
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT | GL_FRAMEBUFFER_BARRIER_BIT);
|
||||
|
||||
this.cullShader.bind();
|
||||
this.bindResources(viewport);
|
||||
this.bindResources(viewport, false);
|
||||
glDepthMask(false);
|
||||
glColorMask(false, false, false, false);
|
||||
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);
|
||||
|
||||
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
|
||||
|
||||
glBindVertexArray(0);
|
||||
glBindSampler(0, 0);
|
||||
glBindTextureUnit(0, 0);
|
||||
RenderLayer.getCutoutMipped().endDrawing();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ public class RenderDataFactory {
|
||||
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 boolean generateMeshlets = true;
|
||||
|
||||
private int minX;
|
||||
private int minY;
|
||||
@@ -51,6 +52,15 @@ public class RenderDataFactory {
|
||||
// since fluid states are explicitly overlays over the base block
|
||||
// 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
|
||||
public BuiltSection generateMesh(WorldSection section) {
|
||||
@@ -76,39 +86,123 @@ public class RenderDataFactory {
|
||||
this.generateMeshForAxis(section, 1);//Direction.Axis.Z
|
||||
this.generateMeshForAxis(section, 2);//Direction.Axis.X
|
||||
|
||||
int quadCount = this.doubleSidedQuadCollector.size() + this.translucentQuadCollector.size();
|
||||
int bufferSize;
|
||||
if (this.generateMeshlets) {
|
||||
bufferSize = getMeshletHoldingCount(this.doubleSidedQuadCollector.size(), 126, 128) +
|
||||
getMeshletHoldingCount(this.translucentQuadCollector.size(), 126, 128);
|
||||
for (var collector : this.directionalQuadCollectors) {
|
||||
quadCount += collector.size();
|
||||
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);
|
||||
}
|
||||
|
||||
//TODO: generate the meshlets here
|
||||
|
||||
var buff = new MemoryBuffer(quadCount*8L);
|
||||
long ptr = buff.address;
|
||||
MemoryBuffer buff;
|
||||
int[] offsets = new int[8];
|
||||
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
|
||||
offsets[0] = meshlet;
|
||||
for (long data : this.translucentQuadCollector) {
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
MemoryUtil.memPutLong(ptr + ((coff++) * 8L), data);
|
||||
}
|
||||
|
||||
for (int face = 0; face < 6; face++) {
|
||||
offsets[face+2] = coff;
|
||||
offsets[face + 2] = coff;
|
||||
for (long data : this.directionalQuadCollectors[face]) {
|
||||
MemoryUtil.memPutLong(ptr + ((coff++) * 8L), data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int aabb = 0;
|
||||
aabb |= this.minX;
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
#line 1
|
||||
struct Frustum {
|
||||
vec4 planes[6];
|
||||
};
|
||||
@@ -51,7 +52,7 @@ layout(binding = 2, std430) restrict buffer DrawBuffer {
|
||||
DrawCommand drawCmd;
|
||||
};
|
||||
|
||||
#ifndef Quad
|
||||
#ifndef MESHLET_ACCESS
|
||||
#define MESHLET_ACCESS readonly writeonly
|
||||
#endif
|
||||
layout(binding = 3, std430) MESHLET_ACCESS restrict buffer MeshletListData {
|
||||
|
||||
@@ -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() {
|
||||
visibilityData[id] = value;
|
||||
colour = vec4(float(id&7u)/7, float((id>>3)&7u)/7, float((id>>6)&7u)/7, 1);
|
||||
}
|
||||
@@ -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() {
|
||||
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;
|
||||
}
|
||||
@@ -7,10 +7,35 @@
|
||||
#define MESHLET_SIZE (QUADS_PER_MESHLET+2)
|
||||
#import <voxy:lod/quad_format.glsl>
|
||||
#import <voxy:lod/gl46mesh/bindings.glsl>
|
||||
#import <voxy:lod/section.glsl>
|
||||
#define GEOMETRY_FMT Quad
|
||||
#define PosHeader 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;
|
||||
bool setupMeshlet() {
|
||||
gl_CullDistance[0] = 1;
|
||||
@@ -23,7 +48,7 @@ bool setupMeshlet() {
|
||||
return true;
|
||||
}
|
||||
|
||||
uint baseId = (data*QUADS_PER_MESHLET);
|
||||
uint baseId = (data*MESHLET_SIZE);
|
||||
uint quadIndex = baseId + (gl_VertexID>>2) + 2;
|
||||
meshletPosition = geometryPool[baseId];
|
||||
quad = geometryPool[quadIndex];
|
||||
@@ -35,7 +60,21 @@ bool setupMeshlet() {
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
if (setupMeshlet()) {
|
||||
gl_Position = vec4(1.0f/0.0f);
|
||||
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);
|
||||
}
|
||||
Reference in New Issue
Block a user