2626public class DrawBuffers {
2727 public static final int VERTEX_SIZE = PipelineManager .terrainVertexFormat .getVertexSize ();
2828 public static final int INDEX_SIZE = Short .BYTES ;
29+ public static final int UNDEFINED_FACING_IDX = QuadFacing .UNDEFINED .ordinal ();
30+ public static final float POS_OFFSET = CustomVertexFormat .getPositionOffset ();
2931
3032 private static final int CMD_STRIDE = 32 ;
3133
@@ -43,7 +45,7 @@ public class DrawBuffers {
4345 final int [] sectionIndices = new int [512 ];
4446 final int [] masks = new int [512 ];
4547
46- //Need ugly minHeight Parameter to fix custom world heights (exceeding 384 Blocks in total)
48+ // Need ugly minHeight parameter to fix custom world heights (exceeding 384 Blocks in total)
4749 public DrawBuffers (int index , Vector3i origin , int minHeight ) {
4850 this .index = index ;
4951 this .origin = origin ;
@@ -71,23 +73,50 @@ public void upload(RenderSection section, UploadBuffer buffer, TerrainRenderType
7173 return ;
7274 }
7375
76+ int oldOffset = -1 ;
77+ int size = 0 ;
7478 for (int i = 0 ; i < QuadFacing .COUNT ; i ++) {
7579 long paramPtr = DrawParametersBuffer .getParamsPtr (this .drawParamsPtr , section .inAreaIndex , renderType .ordinal (), i );
76-
7780 int vertexOffset = DrawParametersBuffer .getVertexOffset (paramPtr );
81+
82+ // Only need to get first used offset, as it identifies the whole segment that will be freed
83+ if (oldOffset == -1 ) {
84+ oldOffset = vertexOffset ;
85+ }
86+
87+ var vertexBuffer = vertexBuffers [i ];
88+ if (vertexBuffer != null ) {
89+ size += vertexBuffer .remaining ();
90+
91+ }
92+ }
93+
94+ if (size == 0 ) {
95+ return ;
96+ }
97+
98+ AreaBuffer areaBuffer = this .getAreaBufferOrAlloc (renderType );
99+ areaBuffer .freeSegment (oldOffset );
100+ AreaBuffer .Segment segment = areaBuffer .allocateSegment (size );
101+
102+ int baseInstance = encodeSectionOffset (section .xOffset (), section .yOffset (), section .zOffset ());
103+
104+ int offset = 0 ;
105+ for (int i = 0 ; i < QuadFacing .COUNT ; i ++) {
106+ long paramPtr = DrawParametersBuffer .getParamsPtr (this .drawParamsPtr , section .inAreaIndex , renderType .ordinal (), i );
107+
108+ int vertexOffset = -1 ;
78109 int firstIndex = 0 ;
79110 int indexCount = 0 ;
80111
81112 var vertexBuffer = vertexBuffers [i ];
82113 int vertexCount = 0 ;
83114
84115 if (vertexBuffer != null ) {
85- AreaBuffer .Segment segment = this .getAreaBufferOrAlloc (renderType ).upload (vertexBuffer , vertexOffset , paramPtr );
86- vertexOffset = segment .offset / VERTEX_SIZE ;
87-
88- int baseInstance = encodeSectionOffset (section .xOffset (), section .yOffset (), section .zOffset ());
89- DrawParametersBuffer .setBaseInstance (paramPtr , baseInstance );
116+ areaBuffer .upload (segment , vertexBuffer , offset );
117+ vertexOffset = (segment .offset + offset ) / VERTEX_SIZE ;
90118
119+ offset += vertexBuffer .remaining ();
91120 vertexCount = vertexBuffer .limit () / VERTEX_SIZE ;
92121 indexCount = vertexCount * 6 / 4 ;
93122 }
@@ -97,16 +126,17 @@ public void upload(RenderSection section, UploadBuffer buffer, TerrainRenderType
97126 this .indexBuffer = new AreaBuffer (AreaBuffer .Usage .INDEX , 60000 , INDEX_SIZE );
98127 }
99128
100- int oldOffset = DrawParametersBuffer .getIndexCount (paramPtr ) > 0 ? DrawParametersBuffer .getFirstIndex (paramPtr ) : -1 ;
101- AreaBuffer .Segment segment = this .indexBuffer .upload (buffer .getIndexBuffer (), oldOffset , paramPtr );
102- firstIndex = segment .offset / INDEX_SIZE ;
129+ oldOffset = DrawParametersBuffer .getIndexCount (paramPtr ) > 0 ? DrawParametersBuffer .getFirstIndex (paramPtr ) : -1 ;
130+ AreaBuffer .Segment ibSegment = this .indexBuffer .upload (buffer .getIndexBuffer (), oldOffset , paramPtr );
131+ firstIndex = ibSegment .offset / INDEX_SIZE ;
103132 } else {
104133 Renderer .getDrawer ().getQuadsIndexBuffer ().checkCapacity (vertexCount );
105134 }
106135
107136 DrawParametersBuffer .setIndexCount (paramPtr , indexCount );
108137 DrawParametersBuffer .setFirstIndex (paramPtr , firstIndex );
109138 DrawParametersBuffer .setVertexOffset (paramPtr , vertexOffset );
139+ DrawParametersBuffer .setBaseInstance (paramPtr , baseInstance );
110140 }
111141
112142 buffer .release ();
@@ -140,9 +170,6 @@ private int encodeSectionOffset(int xOffset, int yOffset, int zOffset) {
140170 return yOffset1 << 16 | zOffset1 << 8 | xOffset1 ;
141171 }
142172
143- // TODO: refactor
144- public static final float POS_OFFSET = PipelineManager .terrainVertexFormat == CustomVertexFormat .COMPRESSED_TERRAIN ? 4.0f : 0.0f ;
145-
146173 private void updateChunkAreaOrigin (VkCommandBuffer commandBuffer , Pipeline pipeline , double camX , double camY , double camZ , MemoryStack stack ) {
147174 float xOffset = (float ) ((this .origin .x ) + POS_OFFSET - camX );
148175 float yOffset = (float ) ((this .origin .y ) + POS_OFFSET - camY );
@@ -187,26 +214,57 @@ public void buildDrawBatchesIndirect(Vec3 cameraPos, IndirectBuffer indirectBuff
187214
188215 long drawParamsBasePtr2 = drawParamsBasePtr + (sectionIdx * facingsStride );
189216
217+ int indexCount = 0 ;
218+ int firstIndex = 0 ;
219+ int vertexOffset = 0 ;
220+ int baseInstance = 0 ;
221+
190222 for (int i = 0 ; i < QuadFacing .COUNT ; i ++) {
191223
192224 if ((mask & 1 << i ) == 0 ) {
193225 drawParamsBasePtr2 += DrawParametersBuffer .STRIDE ;
226+
227+ // Flush draw cmd
228+ if (indexCount > 0 ) {
229+ MemoryUtil .memPutInt (ptr , indexCount );
230+ MemoryUtil .memPutInt (ptr + 4 , 1 );
231+ MemoryUtil .memPutInt (ptr + 8 , firstIndex );
232+ MemoryUtil .memPutInt (ptr + 12 , vertexOffset );
233+ MemoryUtil .memPutInt (ptr + 16 , baseInstance );
234+
235+ ptr += CMD_STRIDE ;
236+ drawCount ++;
237+ }
238+
239+ indexCount = 0 ;
240+ firstIndex = 0 ;
241+ vertexOffset = 0 ;
242+ baseInstance = 0 ;
243+
194244 continue ;
195245 }
196246
197247 long drawParamsPtr = drawParamsBasePtr2 ;
198248
199- final int indexCount = DrawParametersBuffer .getIndexCount (drawParamsPtr );
200- final int firstIndex = DrawParametersBuffer .getFirstIndex (drawParamsPtr );
201- final int vertexOffset = DrawParametersBuffer .getVertexOffset (drawParamsPtr );
202- final int baseInstance = DrawParametersBuffer .getBaseInstance (drawParamsPtr );
249+ final int indexCount_i = DrawParametersBuffer .getIndexCount (drawParamsPtr );
250+ final int firstIndex_i = DrawParametersBuffer .getFirstIndex (drawParamsPtr );
251+ final int vertexOffset_i = DrawParametersBuffer .getVertexOffset (drawParamsPtr );
252+ final int baseInstance_i = DrawParametersBuffer .getBaseInstance (drawParamsPtr );
203253
204- drawParamsBasePtr2 += DrawParametersBuffer .STRIDE ;
205-
206- if (indexCount <= 0 ) {
207- continue ;
254+ if (indexCount == 0 ) {
255+ indexCount = indexCount_i ;
256+ firstIndex = firstIndex_i ;
257+ vertexOffset = vertexOffset_i ;
258+ baseInstance = baseInstance_i ;
259+ }
260+ else {
261+ indexCount += indexCount_i ;
208262 }
209263
264+ drawParamsBasePtr2 += DrawParametersBuffer .STRIDE ;
265+ }
266+
267+ if (indexCount > 0 ) {
210268 MemoryUtil .memPutInt (ptr , indexCount );
211269 MemoryUtil .memPutInt (ptr + 4 , 1 );
212270 MemoryUtil .memPutInt (ptr + 8 , firstIndex );
@@ -227,8 +285,7 @@ public void buildDrawBatchesIndirect(Vec3 cameraPos, IndirectBuffer indirectBuff
227285 count ++;
228286 }
229287
230- final int facing = 6 ;
231- final long facingOffset = facing * DrawParametersBuffer .STRIDE ;
288+ final long facingOffset = UNDEFINED_FACING_IDX * DrawParametersBuffer .STRIDE ;
232289 drawParamsBasePtr += facingOffset ;
233290
234291 long ptr = bufferPtr ;
@@ -293,34 +350,57 @@ public void buildDrawBatchesDirect(Vec3 cameraPos, StaticQueue<RenderSection> qu
293350
294351 long drawParamsBasePtr2 = drawParamsBasePtr + (sectionIdx * facingsStride );
295352
353+ int indexCount = 0 ;
354+ int firstIndex = 0 ;
355+ int vertexOffset = 0 ;
356+ int baseInstance = 0 ;
357+
296358 for (int i = 0 ; i < QuadFacing .COUNT ; i ++) {
297359
298360 if ((mask & 1 << i ) == 0 ) {
299361 drawParamsBasePtr2 += DrawParametersBuffer .STRIDE ;
362+
363+ // Flush draw cmd
364+ if (indexCount > 0 ) {
365+ vkCmdDrawIndexed (commandBuffer , indexCount , 1 , firstIndex , vertexOffset , baseInstance );
366+ }
367+
368+ indexCount = 0 ;
369+ firstIndex = 0 ;
370+ vertexOffset = 0 ;
371+ baseInstance = 0 ;
372+
300373 continue ;
301374 }
302375
303376 long drawParamsPtr = drawParamsBasePtr2 ;
304377
305- final int indexCount = DrawParametersBuffer .getIndexCount (drawParamsPtr );
306- final int firstIndex = DrawParametersBuffer .getFirstIndex (drawParamsPtr );
307- final int vertexOffset = DrawParametersBuffer .getVertexOffset (drawParamsPtr );
308- final int baseInstance = DrawParametersBuffer .getBaseInstance (drawParamsPtr );
309-
310- drawParamsBasePtr2 += DrawParametersBuffer .STRIDE ;
378+ final int indexCount_i = DrawParametersBuffer .getIndexCount (drawParamsPtr );
379+ final int firstIndex_i = DrawParametersBuffer .getFirstIndex (drawParamsPtr );
380+ final int vertexOffset_i = DrawParametersBuffer .getVertexOffset (drawParamsPtr );
381+ final int baseInstance_i = DrawParametersBuffer .getBaseInstance (drawParamsPtr );
311382
312- if (indexCount <= 0 ) {
313- continue ;
383+ if (indexCount == 0 ) {
384+ indexCount = indexCount_i ;
385+ firstIndex = firstIndex_i ;
386+ vertexOffset = vertexOffset_i ;
387+ baseInstance = baseInstance_i ;
388+ }
389+ else {
390+ indexCount += indexCount_i ;
314391 }
315392
393+ drawParamsBasePtr2 += DrawParametersBuffer .STRIDE ;
394+ }
395+
396+ if (indexCount > 0 ) {
316397 vkCmdDrawIndexed (commandBuffer , indexCount , 1 , firstIndex , vertexOffset , baseInstance );
317398 }
318399 }
319400
320401 }
321402 else {
322- final int facing = 6 ;
323- final long facingOffset = facing * DrawParametersBuffer .STRIDE ;
403+ final long facingOffset = UNDEFINED_FACING_IDX * DrawParametersBuffer .STRIDE ;
324404 drawParamsBasePtr += facingOffset ;
325405
326406 for (var iterator = queue .iterator (isTranslucent ); iterator .hasNext (); ) {
@@ -354,7 +434,7 @@ private int getMask(Vec3 camera, RenderSection section) {
354434 final int secY = section .yOffset ;
355435 final int secZ = section .zOffset ;
356436
357- int mask = 1 << QuadFacing . UNDEFINED . ordinal () ;
437+ int mask = 1 << UNDEFINED_FACING_IDX ;
358438
359439 mask |= camera .x - secX >= 0 ? 1 << QuadFacing .X_POS .ordinal () : 0 ;
360440 mask |= camera .y - secY >= 0 ? 1 << QuadFacing .Y_POS .ordinal () : 0 ;
0 commit comments