alex/beta-minecraft-rust
Minecraft Beta 1.7.3 Rewrite
BRANCH main
SNAPSHOT Draw terrain GPU-driven from packed per-section buffers with GPU occlusion culling, add a render distance slider (2-128) with a quad/disk shape, cut chunk bookkeeping at high render distances, and fix a light underflow at y=0
DOWNLOAD
root crates client src render capture.rs
use std::sync::Arc;
use crate::assets::RgbaImage;
use crate::gpu::vk::*;
use crate::gpu::{Buffer, Device, MemoryLocation};
use super::{
COLOR, COLOR_WRITE, COPY_READ, COPY_WRITE, NO_ACCESS, image_barrier, image_copy, memory_barrier,
};
pub(super) struct Capture {
buffer: Buffer,
extent: VkExtent2D,
format: VkFormat,
}
impl Capture {
pub fn new(
device: &Arc<Device>,
extent: VkExtent2D,
format: VkFormat,
) -> crate::gpu::Result<Self> {
let buffer = Buffer::new(
device,
u64::from(extent.width) * u64::from(extent.height) * 4,
VkBufferUsageFlags2::TRANSFER_DST,
MemoryLocation::GpuToCpu,
)?;
Ok(Self {
buffer,
extent,
format,
})
}
pub unsafe fn record(&self, device: &Device, cmd: VkCommandBuffer, image: VkImage) {
unsafe {
let source = VkImageLayout::TransferSrcOptimal;
let layouts = (VkImageLayout::ColorAttachmentOptimal, source);
image_barrier(device, cmd, image, COLOR, layouts, COLOR_WRITE, COPY_READ);
let region = image_copy(0, [0, 0], self.extent.width, self.extent.height);
let (commands, buffer) = (&device.commands, self.buffer.handle());
commands.vkCmdCopyImageToBuffer(cmd, image, source, buffer, 1, ®ion);
let host = (VkPipelineStageFlags2::HOST, VkAccessFlags2::HOST_READ);
memory_barrier(device, cmd, COPY_WRITE, host);
let layouts = (source, VkImageLayout::PresentSrcKhr);
image_barrier(device, cmd, image, COLOR, layouts, COPY_READ, NO_ACCESS);
}
}
// Read only after the submission's fence signals
pub fn finish(mut self) -> crate::gpu::Result<RgbaImage> {
self.buffer.invalidate()?;
let mut pixels = self.buffer.mapped().to_vec();
let bgra = self.format == VkFormat::B8G8R8A8Unorm;
for pixel in pixels.as_chunks_mut::<4>().0 {
if bgra {
pixel.swap(0, 2);
}
pixel[3] = 255;
}
Ok(RgbaImage {
width: self.extent.width,
height: self.extent.height,
pixels,
})
}
}