From 45f4c6bb44ac261b3cbf4844d511e5bf34bc0895 Mon Sep 17 00:00:00 2001 From: FurryMileon Date: Sun, 24 May 2026 08:01:43 +0300 Subject: [PATCH] Fix crash when immediate vertex batch exceeds staging buffer size When many entities (e.g. lots of villagers) share a RenderType, MultiBufferSource.BufferSource.endBatch can produce a single immediate vertex buffer larger than the 64 MiB default staging buffer, causing StagingBuffer.copyBuffer to throw 'Upload size is greater than staging buffer size.' and crashing the render thread. Apply the same one-shot fallback that VulkanImage.uploadSubTextureAsync already uses for oversized texture uploads: when the upload would not fit, allocate a temporary StagingBuffer sized to the upload and let scheduleFree() reclaim it after the current frame finishes. --- .../net/vulkanmod/render/engine/VkCommandEncoder.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/net/vulkanmod/render/engine/VkCommandEncoder.java b/src/main/java/net/vulkanmod/render/engine/VkCommandEncoder.java index f359265d0..adc78453b 100644 --- a/src/main/java/net/vulkanmod/render/engine/VkCommandEncoder.java +++ b/src/main/java/net/vulkanmod/render/engine/VkCommandEncoder.java @@ -290,6 +290,14 @@ public void writeToBuffer(GpuBufferSlice gpuBufferSlice, ByteBuffer byteBuffer) var commandBuffer = Renderer.getInstance().getTransferCb(); StagingBuffer stagingBuffer = Vulkan.getStagingBuffer(); + + // Large immediate batches (e.g. many entities sharing one RenderType) can + // exceed the default staging buffer; fall back to a one-shot oversized buffer. + if (size > stagingBuffer.getBufferSize()) { + stagingBuffer = new StagingBuffer(size); + stagingBuffer.scheduleFree(); + } + stagingBuffer.copyBuffer(size, byteBuffer); long srcOffset = stagingBuffer.getOffset();