-
Notifications
You must be signed in to change notification settings - Fork 0
[Batch 5] Chunk block data GPU storage buffer #389
Copy link
Copy link
Open
Labels
batch-5Batch 5: Final PushBatch 5: Final PushdocumentationImprovements or additions to documentationImprovements or additions to documentationengineenhancementNew feature or requestNew feature or requesthotfixperf/gpu-computeGPU compute shader workGPU compute shader work
Description
Summary
Upload chunk block data (1 byte per block) to a GPU storage buffer so that a compute meshing shader can read blocks directly. This is the foundation for GPU-driven mesh generation.
Depends on: #384 (transfer queue for uploading block data efficiently)
Current State
Block data lives only in CPU memory (Chunk.blocks: [16][256][16]BlockType). Meshing reads blocks on CPU worker threads, produces vertex arrays, uploads vertices to GPU. The GPU never sees raw block data.
Target State
A GPU-visible storage buffer holds block data for all loaded chunks. Layout:
Buffer: [chunk_0_blocks | chunk_1_blocks | ... | chunk_N_blocks]
Each chunk: 16 × 256 × 16 = 65536 bytes (BlockType is u8)
Total: 16384 chunks × 64KB = 1GB max
A compute meshing shader (future issue) can read blocks from this buffer and output vertices directly on the GPU — no CPU meshing, no vertex upload.
Implementation Plan
Step 1: Block data buffer management
const GpuBlockBuffer = struct {
buffer: BufferHandle,
capacity: usize, // max chunks
slot_size: usize, // 65536 bytes per chunk
allocator: FreeListAllocator, // which slots are in use
pub fn allocate(self: *GpuBlockBuffer, chunk_index: u32) !usize;
pub fn free(self: *GpuBlockBuffer, slot: usize) void;
pub fn upload(self: *GpuBlockBuffer, slot: usize, blocks: []const u8) !void;
};Step 2: Chunk index mapping
- Need a mapping: chunk coordinate
(cx, cz)→ buffer slot index - Could use the same index as
ChunkStorageHashMap (iterate and assign) - Or: sparse mapping with a lookup texture/buffer
Step 3: Upload integration
- When a chunk finishes generating: upload block data to GPU storage buffer
- Use the transfer queue ([Batch 4] Dedicated transfer queue + staging buffer ring #384) for upload
- Mark slot as allocated
- When chunk unloads: free the slot
Step 4: Lighting data (optional, same buffer or separate)
sky_lightandblock_lightcould go in the same buffer (appended after blocks)- Or a separate buffer for light data
- Keep it simple for this issue: blocks only, light stays on CPU for now
Step 5: Integration with chunk lifecycle
WorldStreamer: after chunk generates, callgpu_block_buffer.upload()WorldStreamer: when chunk unloads, callgpu_block_buffer.free()- Player modifies block: update both CPU chunk and GPU buffer (small sub-region upload)
Files to Create
src/world/gpu_block_buffer.zig— GPU block data buffer management
Files to Modify
src/world/world_renderer.zig— own and manage GpuBlockBuffersrc/world/world_streamer.zig— upload block data on generate, free on unloadsrc/game/player.zig— update GPU buffer on block break/place
Testing
- Block data uploads for all chunks within render distance
- Slots freed correctly on chunk unload
- Block modifications reflected in GPU buffer (verify by reading back)
- Memory bounded: doesn't exceed max allocation
- No performance regression from upload overhead
- Works with 0 chunks, 1 chunk, 16384 chunks
Roadmap: docs/PERFORMANCE_ROADMAP.md — Batch 5, Issue 4A-1
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
batch-5Batch 5: Final PushBatch 5: Final PushdocumentationImprovements or additions to documentationImprovements or additions to documentationengineenhancementNew feature or requestNew feature or requesthotfixperf/gpu-computeGPU compute shader workGPU compute shader work