Skip to main content

GpuSceneResident

Struct GpuSceneResident 

Source
pub struct GpuSceneResident {
    pub grid_count: u32,
    pub occupancy_pages: Vec<Buffer>,
    pub occupancy_page_words: u32,
    pub occupancy_num_pages: u32,
    pub all_color_offsets: Buffer,
    pub all_colors: Buffer,
    pub all_chunk_colors_base: Buffer,
    pub all_chunk_occupancy: Buffer,
    pub all_slot_chunk_idx: Buffer,
    pub grid_static_meta: Buffer,
    pub total_bytes: u64,
    pub static_meta: Vec<GridStaticMeta>,
    /* private fields */
}
Expand description

GPU-resident storage for an entire scene’s grids.

Fields§

§grid_count: u32

Number of grids uploaded (= SceneUpload::grid_count()); the shader’s grid loop bound and the length of Self::static_meta.

§occupancy_pages: Vec<Buffer>

Concatenated per-slot occupancy, split into up to MAX_OCC_PAGES storage bindings so no single binding exceeds the device’s max_storage_buffer_binding_size. The vec is always exactly MAX_OCC_PAGES long — pages past occupancy_num_pages are 1-word dummies kept only so the bind group has a buffer for every layout entry. Page p holds the global word range [p*occupancy_page_words, (p+1)*occupancy_page_words); occupancy_page_words is a whole number of chunk slots so no slot straddles a boundary.

§occupancy_page_words: u32

Words per occupancy page (a multiple of occ_words_per_slot).

§occupancy_num_pages: u32

Number of real (non-dummy) pages in occupancy_pages.

§all_color_offsets: Buffer

Binding 2 — concatenated per-slot color_offsets prefix tables (all grids, all mips). Grid g’s region starts at static_meta[g].color_offsets_offset words.

§all_colors: Buffer

Binding 3 — concatenated packed voxel colours (all grids). Each word is the voxlap wire format the shader unpacks: blue in bits 0-7, green 8-15, red 16-23, and a brightness byte (not alpha) in bits 24-31 with 0x80 = neutral.

§all_chunk_colors_base: Buffer

Binding 4 — per-slot colour base table: word meta_id of grid g’s region holds the slot’s colour start (in words, relative to static_meta[g].colors_offset) = meta_id × colour stride.

§all_chunk_occupancy: Buffer

Binding 5 — per-grid chunk-occupancy bitmaps (one bit per pool slot: set iff the slot holds a non-empty chunk). The outer DDA tests it to skip whole 128×128×256 chunks per step.

§all_slot_chunk_idx: Buffer

GPU.7 — per-slot chunk_idx for identity verification in the shader. Stored as vec3<i32> with std430 16-byte stride (each entry is [i32; 4] on the host: x, y, z, _pad).

§grid_static_meta: Buffer

Binding 6 — the GridStaticMeta array, one element per grid. Mostly upload-time constant; the live chunk-AABB fields are patched in place on refresh_chunk / evict_chunk.

§total_bytes: u64

Total bytes allocated across all the resident storage buffers, for VRAM accounting (see Self::resident_bytes).

§static_meta: Vec<GridStaticMeta>

Cached static metadata for the host’s frame-loop work.

Implementations§

Source§

impl GpuSceneResident

Source

pub fn upload(device: &Device, info: &SceneUpload) -> Self

Pack + upload info. Each grid is uploaded as a contiguous slab inside the shared storage buffers; per-grid offsets live in grid_static_meta. The grid count is bounded only by the device’s storage-buffer limits (per-grid cameras + metadata are runtime-sized storage arrays, not a fixed shader array).

Source

pub fn resident_bytes(&self) -> u64

GPU memory held by the scene’s storage buffers, in bytes — Self::total_bytes as computed at upload time (in-place refreshes never change it).

Source

pub fn refresh_chunk( &mut self, queue: &Queue, scene_idx: usize, chunk_idx: [i32; 3], chunk: &ChunkUpload, ) -> RefreshOutcome

Install or refresh a chunk in its modular pool slot. GPU.7 generalises GPU.6’s in-place refresh: any chunk_idx maps to a slot via chunk_idx & (pool_dims - 1). The previous occupant (if a different chunk) is silently replaced — the host is responsible for guaranteeing that the pool is sized large enough that two simultaneously-resident chunks never collide on the same slot.

Source

pub fn refresh_chunk_partial( &mut self, queue: &Queue, scene_idx: usize, chunk_idx: [i32; 3], vxl: &Vxl, x0: i32, y0: i32, x1: i32, y1: i32, ) -> bool

Evict a chunk’s slot — clear its chunk_occupancy bit and reset slot_chunk_idx to the empty sentinel. Used by the host when a chunk disappears from the CPU-side Grid::chunks (e.g. streaming eviction past r_evict).

Returns false if scene_idx is past grid_count (no-op); true otherwise. PF.12.c — partial refresh: re-derive + re-upload ONLY the columns inside the inclusive chunk-local mip-0 column rect [x0..=x1] × [y0..=y1] (pre-padded by the caller with the edit’s ±1 adjacency reach), for every mip. Requires the slot to already hold chunk_idx with a mirrored offsets table, and every dirty column’s colour COUNT to be unchanged (a count change reflows the packed colour block). Returns false — with nothing written — when any precondition fails; the caller falls back to the full Self::refresh_chunk path.

The count-stable case is the streaming bake tracker’s per-frame path (brightness-byte rewrites) and recolour edits: those now upload a few KB instead of decompressing + rewriting the whole ~1–2 MB chunk ladder.

Source

pub fn evict_chunk( &mut self, queue: &Queue, scene_idx: usize, chunk_idx: [i32; 3], ) -> bool

Evict chunk_idx from grid scene_idx: clear the slot’s chunk-occupancy bit, stamp SLOT_EMPTY_SENTINEL into its slot_chunk_idx entry, and shrink the grid’s chunk-AABB if the box tightened. The bulk voxel data is left in place — the cleared occupancy bit + sentinel already make the shader treat the slot as empty. A no-op (returning true) when the slot meanwhile holds a different chunk, so a stale evict can never wipe a newer occupant. Returns false only for an out-of-range scene_idx.

Source

pub fn chunk_occ_pyramid_shadow(&self) -> &[Vec<Vec<u32>>]

Read-only view of the chunk-occupancy pyramid shadows (per grid, per level above L0) — the CPU mirror the incremental maintenance updates; exposed for integration tests to assert the re-OR bookkeeping (rendering itself only reads the GPU copy).

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> Downcast<T> for T

Source§

fn downcast(&self) -> &T

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> Upcast<T> for T

Source§

fn upcast(&self) -> Option<&T>

Source§

impl<T> WasmNotSend for T
where T: Send,

Source§

impl<T> WasmNotSendSync for T

Source§

impl<T> WasmNotSync for T
where T: Sync,