pub struct DeviceResources {Show 56 fields
pub target_format: TextureFormat,
pub sample_count: u32,
pub pipeline_cache: Option<PipelineCache>,
pub solid_pipeline: RenderPipeline,
pub solid_two_sided_pipeline: RenderPipeline,
pub transparent_pipeline: RenderPipeline,
pub wireframe_pipeline: RenderPipeline,
pub camera_uniform_buf: Buffer,
pub light_uniform_buf: Buffer,
pub light_storage_buf: Buffer,
pub clustered: ClusteredResources,
pub camera_bind_group: BindGroup,
pub camera_bind_group_layout: BindGroupLayout,
pub object_bind_group_layout: BindGroupLayout,
pub shadow_map_texture: Texture,
pub shadow_map_view: TextureView,
pub shadow_sampler: Sampler,
pub point_shadow_cube_texture: Texture,
pub point_shadow_cube_view: TextureView,
pub point_shadow_face_views: Vec<TextureView>,
pub shadow_point_pipeline: RenderPipeline,
pub shadow_point_face_buf: Buffer,
pub shadow_point_face_bind_group: BindGroup,
pub shadow_pipeline: RenderPipeline,
pub shadow_pipeline_two_sided: RenderPipeline,
pub shadow_uniform_buf: Buffer,
pub shadow_bind_group: BindGroup,
pub shadow_info_buf: Buffer,
pub shadow_atlas_depth_sampler: Sampler,
pub shadow_atlas_viewer_pipeline: RenderPipeline,
pub shadow_atlas_viewer_bg: BindGroup,
pub shadow_atlas_viewer_buf: Buffer,
pub debug_frag_sentinel_buf: Buffer,
pub gizmo_pipeline: RenderPipeline,
pub gizmo_vertex_buffer: Buffer,
pub gizmo_index_buffer: Buffer,
pub gizmo_index_count: u32,
pub gizmo_uniform_buf: Buffer,
pub gizmo_bind_group: BindGroup,
pub overlay_pipeline: RenderPipeline,
pub overlay_line_pipeline: RenderPipeline,
pub grid_pipeline: RenderPipeline,
pub grid_uniform_buf: Buffer,
pub grid_bind_group: BindGroup,
pub overlay_bind_group_layout: BindGroupLayout,
pub constraint_line_buffers: Vec<(Buffer, Buffer, u32, Buffer, BindGroup)>,
pub axes_pipeline: RenderPipeline,
pub axes_vertex_buffer: Buffer,
pub axes_vertex_count: u32,
pub texture_bind_group_layout: BindGroupLayout,
pub fallback_texture: GpuTexture,
pub ibl_irradiance_view: Option<TextureView>,
pub ibl_prefiltered_view: Option<TextureView>,
pub ibl_brdf_lut_view: Option<TextureView>,
pub ibl_skybox_view: Option<TextureView>,
pub frame_upload_bytes: u64,
/* private fields */
}Expand description
Device-shared GPU resources: pipelines, layouts, samplers, fallbacks, LUTs,
and the per-feature pipeline clusters (decal, scatter, volume, …).
Created once at init and shared across every viewport.
Typically stored in the host framework’s resource container and accessed
by ViewportRenderer during prepare() and paint().
Fields§
§target_format: TextureFormatSwapchain texture format; all pipelines are compiled for this format.
sample_count: u32MSAA sample count used by all render pipelines.
pipeline_cache: Option<PipelineCache>Optional pipeline cache shared by every pipeline built here. Some only
when the device enables Features::PIPELINE_CACHE. Persist its contents
across runs with ViewportRenderer::pipeline_cache_data to skip shader
recompilation on later launches.
solid_pipeline: RenderPipelineSolid-shaded render pipeline (TriangleList topology, no blending).
solid_two_sided_pipeline: RenderPipelineSolid-shaded render pipeline with back-face culling disabled (two-sided surfaces).
transparent_pipeline: RenderPipelineTransparent render pipeline (TriangleList topology, alpha blending).
wireframe_pipeline: RenderPipelineWireframe render pipeline (LineList topology, same shader).
camera_uniform_buf: BufferUniform buffer holding the per-frame CameraUniform (view-proj + eye position).
light_uniform_buf: BufferUniform buffer holding the per-frame LightsUniform header (count +
hemisphere + IBL + debug params). The per-light array lives in
light_storage_buf (binding 13).
light_storage_buf: BufferStorage buffer of per-light SingleLightUniform entries (binding 13).
Sized for MAX_SCENE_LIGHTS. The renderer truncates the consumer’s
light list to this cap each frame, ranking surplus lights by
LightSource::importance * proximity_weight.
clustered: ClusteredResourcesClustered-shading state: cluster grid, global light index list, and the per-frame cluster build pipeline. Bindings 14/15/16 of the camera bind group expose this state to every lit pipeline.
camera_bind_group: BindGroupBind group (group 0) binding camera, light, clip-plane, and shadow uniforms.
camera_bind_group_layout: BindGroupLayoutBind group layout for group 0 (shared by all scene pipelines).
object_bind_group_layout: BindGroupLayoutBind group layout for group 1 (per-object uniform: model, material, selection).
shadow_map_texture: TextureShadow atlas depth texture (Depth32Float, atlas_size x atlas_size, 2x2 tile grid).
shadow_map_view: TextureViewDepth texture view for binding as a shader resource (sampling).
shadow_sampler: SamplerComparison sampler for PCF shadow filtering.
point_shadow_cube_texture: TextureCubemap-array depth texture for point-light shadows. Layered as
MAX_POINT_SHADOW_LIGHTS * 6 faces of POINT_SHADOW_FACE_SIZE px.
point_shadow_cube_view: TextureViewtexture_depth_cube_array view bound to the lit-pass bind group.
point_shadow_face_views: Vec<TextureView>One 2D-array view per face, used as the depth attachment during the
shadow render pass. len() == MAX_POINT_SHADOW_LIGHTS * 6, indexed
as slot * 6 + face.
shadow_point_pipeline: RenderPipelineRender pipeline for the point-shadow depth pass. Same vertex layout as the cascade shadow pipeline; writes linear distance-to-light.
shadow_point_face_buf: BufferPer-face uniform buffer holding view_proj, light_pos, range
for every (slot, face) of the point shadow array. Sized as
MAX_POINT_SHADOW_LIGHTS * 6 * 256 bytes (256-byte dynamic-offset
stride).
shadow_point_face_bind_group: BindGroupBind group for the point-shadow per-face uniform. Stride is 256; the per-face render pass sets a dynamic offset.
shadow_pipeline: RenderPipelineRender pipeline for the shadow depth pass (depth-only, no fragment output).
Culls front faces, so closed solids cast shadow from their back face
and a solid’s own front face is never compared against itself in the
shadow map. Two-sided materials (BackfacePolicy::Identical and
friends) are routed to shadow_pipeline_two_sided instead so both
sides of cloth, foliage, and planar surfaces cast shadows.
shadow_pipeline_two_sided: RenderPipelineShadow caster pipeline for two-sided materials. Same layout and shader
as shadow_pipeline but with cull_mode: None and a larger caster-side
depth bias (CSM_SHADOW_BIAS_TWO_SIDED) so both sides of a two-sided
mesh rasterise into the shadow atlas without the surface self-shadowing
where it is its own receiver.
shadow_uniform_buf: BufferUniform buffer holding the per-cascade light-space view-projection matrix (64 bytes).
shadow_bind_group: BindGroupBind group for the shadow pass (group 0: light uniform).
shadow_info_buf: BufferUniform buffer for the ShadowAtlasUniform (binding 5 of camera_bgl, 416 bytes).
shadow_atlas_depth_sampler: SamplerNon-comparison sampler for reading depth values as float (atlas viewer).
shadow_atlas_viewer_pipeline: RenderPipelinePipeline for the shadow atlas corner overlay.
shadow_atlas_viewer_bg: BindGroupBind group for the atlas viewer (uniform + depth texture + sampler).
shadow_atlas_viewer_buf: BufferUniform buffer: NDC rect of the atlas viewer quad.
debug_frag_sentinel_buf: Buffer16-byte sentinel bound at group 0 binding 12 when the debug fragment buffer is inactive.
gizmo_pipeline: RenderPipelineGizmo render pipeline (TriangleList, depth_compare Always : always on top).
gizmo_vertex_buffer: BufferGizmo vertex buffer (3 axis arrows, regenerated when hovered axis changes).
gizmo_index_buffer: BufferGizmo index buffer.
gizmo_index_count: u32Number of indices in the gizmo index buffer.
gizmo_uniform_buf: BufferGizmo uniform buffer (model matrix: positions gizmo at selected object, scaled to screen size).
gizmo_bind_group: BindGroupBind group for gizmo uniform (group 1).
overlay_pipeline: RenderPipelineOverlay render pipeline (TriangleList with alpha blending : for semi-transparent BC quads).
overlay_line_pipeline: RenderPipelineOverlay wireframe pipeline (LineList, no alpha blending needed).
grid_pipeline: RenderPipelineFull-screen analytical grid pipeline (no vertex buffer : positions hardcoded in shader).
grid_uniform_buf: BufferUniform buffer for the grid shader (GridUniform : written every frame in prepare()).
grid_bind_group: BindGroupBind group for the grid uniform (group 0, single binding).
overlay_bind_group_layout: BindGroupLayoutBind group layout for overlay uniforms (group 1: model + colour uniform).
constraint_line_buffers: Vec<(Buffer, Buffer, u32, Buffer, BindGroup)>Transient constraint guide lines, rebuilt each frame in prepare(). Each entry: (vertex_buffer, index_buffer, index_count, uniform_buffer, bind_group).
axes_pipeline: RenderPipelineScreen-space axes indicator pipeline (TriangleList, no depth, alpha blending).
axes_vertex_buffer: BufferVertex buffer for axes indicator geometry (rebuilt each frame).
axes_vertex_count: u32Number of vertices in the axes indicator buffer.
texture_bind_group_layout: BindGroupLayoutBind group layout for texture group (group 2: albedo + sampler + normal_map + ao_map).
fallback_texture: GpuTextureFallback 1x1 white texture used when material.texture_id is None.
ibl_irradiance_view: Option<TextureView>IBL irradiance equirect texture view (binding 7). None until environment uploaded.
ibl_prefiltered_view: Option<TextureView>IBL prefiltered specular equirect texture view (binding 8). None until environment uploaded.
ibl_brdf_lut_view: Option<TextureView>BRDF integration LUT texture view (binding 9). None until the first
upload_environment_map; cached across subsequent uploads (the LUT is
scene-independent: function of roughness x N.V only).
ibl_skybox_view: Option<TextureView>Skybox / full-res environment equirect texture view (binding 11). None until uploaded.
frame_upload_bytes: u64Cumulative bytes of geometry data uploaded since the last prepare() reset.
Incremented by upload_mesh, upload_mesh_data, and replace_mesh_data.
Read and reset at the start of each prepare() call to populate
FrameStats::upload_bytes.
Implementations§
Source§impl DeviceResources
impl DeviceResources
Sourcepub fn run_compute_filters(
&mut self,
device: &Device,
queue: &Queue,
items: &[ComputeFilterItem],
) -> Vec<ComputeFilterResult>
pub fn run_compute_filters( &mut self, device: &Device, queue: &Queue, items: &[ComputeFilterItem], ) -> Vec<ComputeFilterResult>
Dispatch GPU compute filters for all items in the list.
Returns one ComputeFilterResult per item. The renderer uses these
during paint() to override the mesh’s default index buffer.
This is a synchronous v1 implementation: it submits each dispatch individually and polls the device to read back the counter. This is acceptable for v1; async readback can be added later.
Source§impl DeviceResources
impl DeviceResources
Sourcepub fn create_gpu_particle_system(
&mut self,
device: &Device,
queue: &Queue,
config: &GpuParticleSystemConfig,
) -> GpuParticleSystemId
pub fn create_gpu_particle_system( &mut self, device: &Device, queue: &Queue, config: &GpuParticleSystemConfig, ) -> GpuParticleSystemId
Allocate a persistent GPU particle system.
The returned GpuParticleSystemId stays valid until
drop_gpu_particle_system is called
or the renderer is dropped.
Sourcepub fn drop_gpu_particle_system(&mut self, id: GpuParticleSystemId)
pub fn drop_gpu_particle_system(&mut self, id: GpuParticleSystemId)
Release a particle system. The handle becomes invalid; the slot is
reused on the next create_gpu_particle_system call.
Source§impl DeviceResources
impl DeviceResources
Sourcepub fn new(
device: &Device,
target_format: TextureFormat,
sample_count: u32,
) -> Self
pub fn new( device: &Device, target_format: TextureFormat, sample_count: u32, ) -> Self
Create all GPU resources for the viewport.
Call once at application startup. target_format must match the swap-chain surface
format. Use sample_count = 1 unless the caller is providing MSAA resolve targets.
Sourcepub fn new_with_cache(
device: &Device,
target_format: TextureFormat,
sample_count: u32,
pipeline_cache_data: Option<&[u8]>,
) -> Self
pub fn new_with_cache( device: &Device, target_format: TextureFormat, sample_count: u32, pipeline_cache_data: Option<&[u8]>, ) -> Self
Like new, but seeds a wgpu::PipelineCache from previously
saved data so shader compilation can be skipped on later launches.
pipeline_cache_data should come from a prior
ViewportRenderer::pipeline_cache_data
call, or None on first run. The cache is only created when the device
enables Features::PIPELINE_CACHE; otherwise this behaves exactly like
new and the data is ignored.
Source§impl DeviceResources
impl DeviceResources
Sourcepub fn upload_texture(
&mut self,
device: &Device,
queue: &Queue,
width: u32,
height: u32,
rgba_data: &[u8],
) -> ViewportResult<TextureId>
pub fn upload_texture( &mut self, device: &Device, queue: &Queue, width: u32, height: u32, rgba_data: &[u8], ) -> ViewportResult<TextureId>
Upload an RGBA texture to the GPU and return its texture ID.
The ID can be stored in Material::texture_id to apply the texture to objects.
rgba_data must be exactly width * height * 4 bytes in RGBA8 format.
§Errors
Returns ViewportError::InvalidTextureData if the data length is incorrect.
Sourcepub fn upload_normal_map(
&mut self,
device: &Device,
queue: &Queue,
width: u32,
height: u32,
rgba_data: &[u8],
) -> ViewportResult<TextureId>
pub fn upload_normal_map( &mut self, device: &Device, queue: &Queue, width: u32, height: u32, rgba_data: &[u8], ) -> ViewportResult<TextureId>
Upload an RGBA texture as a normal map and return its texture ID.
Uses Rgba8Unorm format (not sRGB) so values are linear : required for correct
normal map decoding. rgba_data must be width * height * 4 bytes.
Sourcepub fn begin_upload_texture(
&mut self,
device: &Device,
queue: &Queue,
width: u32,
height: u32,
rgba: Vec<u8>,
) -> ViewportResult<JobId>
pub fn begin_upload_texture( &mut self, device: &Device, queue: &Queue, width: u32, height: u32, rgba: Vec<u8>, ) -> ViewportResult<JobId>
Start an asynchronous albedo texture upload.
Returns a JobId immediately. The texture and bind group are built
on a worker thread; queue.write_texture queues the pixel copy and
the runner gates the job on a fresh submission that flushes those
writes. Once the status is Ready, take the resulting texture id
with upload_result_texture and store it in Material::texture_id.
rgba transfers into the worker; clone at the call site to retain
it. Format and binding match the synchronous upload_texture.
§Errors
Returns
ViewportError::InvalidTextureData
when rgba.len() != width * height * 4, reported before any job is
submitted.
Sourcepub fn begin_upload_normal_map(
&mut self,
device: &Device,
queue: &Queue,
width: u32,
height: u32,
rgba: Vec<u8>,
) -> ViewportResult<JobId>
pub fn begin_upload_normal_map( &mut self, device: &Device, queue: &Queue, width: u32, height: u32, rgba: Vec<u8>, ) -> ViewportResult<JobId>
Start an asynchronous normal-map upload.
Same shape as begin_upload_texture, but the texture is created
with the linear Rgba8Unorm format and bound into the normal-map
slot. Take the result with upload_result_texture once Ready.
§Errors
Same as begin_upload_texture.
Sourcepub fn upload_result_texture(&mut self, id: JobId) -> ViewportResult<TextureId>
pub fn upload_result_texture(&mut self, id: JobId) -> ViewportResult<TextureId>
Take the texture id produced by a completed begin_upload_texture
or begin_upload_normal_map job.
Returns JobNotReady while the upload is still in flight, and
JobResultMissing for ids that have already been taken, were
issued by a different upload type, or never existed.
Sourcepub fn upload_compressed_texture(
&mut self,
device: &Device,
queue: &Queue,
desc: CompressedTextureDesc<'_>,
) -> ViewportResult<TextureId>
pub fn upload_compressed_texture( &mut self, device: &Device, queue: &Queue, desc: CompressedTextureDesc<'_>, ) -> ViewportResult<TextureId>
Upload a pre-compressed, pre-mipped texture and return its texture ID.
Sync wrapper around begin_upload_compressed_texture:
see that method for the format and layout requirements. Blocks the
calling thread until the upload completes.
§Errors
Sourcepub fn begin_upload_compressed_texture(
&mut self,
device: &Device,
queue: &Queue,
desc: CompressedTextureDesc<'_>,
) -> ViewportResult<JobId>
pub fn begin_upload_compressed_texture( &mut self, device: &Device, queue: &Queue, desc: CompressedTextureDesc<'_>, ) -> ViewportResult<JobId>
Start an asynchronous upload of pre-compressed, pre-mipped texture data.
Returns a JobId immediately; take the resulting texture id with
upload_result_texture once the status is
Ready, then store it in a Material slot. The data is validated and
copied into the worker before the job is submitted.
§Errors
Returns
ViewportError::UnsupportedTextureFormat
when desc.format is not block-compressed or the device lacks its
required feature (check first with supports_texture_format), and
ViewportError::InvalidCompressedTextureData
when mip_levels is empty or a level’s byte length does not match its
block-packed size.
Sourcepub fn texture_memory_stats(&self) -> TextureMemoryStats
pub fn texture_memory_stats(&self) -> TextureMemoryStats
Current GPU memory usage for user-uploaded textures.
Counts bytes from upload_texture, upload_normal_map, and the
async upload entries. Internal resources (shadow maps, colourmaps,
IBL, post-processing targets) are not included.
Sourcepub fn free_texture(&mut self, id: TextureId) -> bool
pub fn free_texture(&mut self, id: TextureId) -> bool
Release a user-uploaded texture, reclaiming its slot and GPU memory.
Drops the GpuTexture (wgpu defers the real free until in-flight
commands that reference it complete), bumps the slot generation so id
no longer resolves, and evicts the cached bind groups that named the
texture: the shared material_bind_groups / instance_bind_groups
entries whose key contains id, and any per-mesh object bind group built
against it (invalidated so the next prepare rebinds the fallback).
Returns true if a texture was released, false if id did not resolve
to a live texture (already freed, never uploaded, or a stale handle).
Materials still holding id are not rewritten; they fall back to the
fallback texture until reassigned.
Sourcepub fn replace_texture(
&mut self,
device: &Device,
queue: &Queue,
id: TextureId,
width: u32,
height: u32,
rgba_data: &[u8],
) -> ViewportResult<()>
pub fn replace_texture( &mut self, device: &Device, queue: &Queue, id: TextureId, width: u32, height: u32, rgba_data: &[u8], ) -> ViewportResult<()>
Replace the pixels of an already-uploaded texture in place, keeping the
same TextureId.
The handle stays valid: materials and items holding id pick up the new
pixels on the next frame with no reassignment. The generation check is the
in-flight guard, so a stale handle (its slot freed and reused) returns
StaleHandle instead of overwriting whatever now occupies the slot. Use
this for content that changes over time (a streamed or animated texture)
where re-uploading and reassigning a fresh id would be wasteful.
The texture is recreated as an Rgba8UnormSrgb albedo texture, matching
upload_texture; rgba_data must be exactly
width * height * 4 bytes. Dimensions and format need not match the
original upload.
§Errors
ViewportError::InvalidTextureData
if the data length is wrong, or
ViewportError::StaleHandle
if id does not resolve to a live texture.
Source§impl DeviceResources
impl DeviceResources
Sourcepub fn upload_colourmap(
&mut self,
device: &Device,
queue: &Queue,
rgba_data: &[[u8; 4]; 256],
) -> ColourmapId
pub fn upload_colourmap( &mut self, device: &Device, queue: &Queue, rgba_data: &[[u8; 4]; 256], ) -> ColourmapId
Upload a 256-sample RGBA colourmap to the GPU and return its ColourmapId.
The returned ID can be stored in SceneRenderItem::colourmap_id.
Use BuiltinColourmap variants + Self::builtin_colourmap_id for the built-in presets.
Sourcepub fn get_colourmap_rgba(&self, id: ColourmapId) -> Option<&[[u8; 4]; 256]>
pub fn get_colourmap_rgba(&self, id: ColourmapId) -> Option<&[[u8; 4]; 256]>
Return the CPU-side colourmap LUT for id as 256 RGBA8 entries, or None if the id is invalid.
Useful for any non-GPU colourmap output: PDF export, table cell colouring, custom legend widgets, or sampling a colour at a specific scalar value. The data is always in memory (kept for GPU upload) so this accessor is free.
Sourcepub fn builtin_colourmap_id(&self, preset: BuiltinColourmap) -> ColourmapId
pub fn builtin_colourmap_id(&self, preset: BuiltinColourmap) -> ColourmapId
Return the ColourmapId for a built-in preset.
Call Self::ensure_colourmaps_initialized first (done automatically by
ViewportRenderer::prepare). Panics if colourmaps have not been initialized yet.
Sourcepub fn ensure_colourmaps_initialized(&mut self, device: &Device, queue: &Queue)
pub fn ensure_colourmaps_initialized(&mut self, device: &Device, queue: &Queue)
Ensure built-in colourmaps are uploaded to the GPU.
Called automatically by ViewportRenderer::prepare() on the first frame.
Safe to call multiple times : no-op after first invocation.
Sourcepub fn upload_matcap(
&mut self,
device: &Device,
queue: &Queue,
rgba_data: &[u8],
blendable: bool,
) -> ViewportResult<MatcapId>
pub fn upload_matcap( &mut self, device: &Device, queue: &Queue, rgba_data: &[u8], blendable: bool, ) -> ViewportResult<MatcapId>
Upload a 256x256 RGBA matcap texture and return its MatcapId.
rgba_data must be exactly 256 * 256 * 4 = 262_144 bytes.
Set blendable = true for matcaps whose alpha channel tints the base
geometry colour; false for static matcaps that fully replace the colour.
§Errors
Returns ViewportError::InvalidTextureData
if rgba_data has the wrong length.
Sourcepub fn builtin_matcap_id(&self, preset: BuiltinMatcap) -> MatcapId
pub fn builtin_matcap_id(&self, preset: BuiltinMatcap) -> MatcapId
Return the MatcapId for a built-in preset.
Panics if called before the renderer has run at least one prepare pass
(which calls Self::ensure_matcaps_initialized automatically).
Sourcepub fn ensure_matcaps_initialized(&mut self, device: &Device, queue: &Queue)
pub fn ensure_matcaps_initialized(&mut self, device: &Device, queue: &Queue)
Upload the eight built-in matcaps to the GPU if not already done.
Called automatically by ViewportRenderer::prepare(). Safe to call
multiple times : no-op after first invocation.
Source§impl DeviceResources
impl DeviceResources
Sourcepub fn resident_bytes(&self) -> ResidentBytes
pub fn resident_bytes(&self) -> ResidentBytes
Resident GPU bytes for the user-uploaded working set: meshes, user textures, Gaussian splats, marching-cubes volumes, and pre-uploaded scivis curves.
Cheap enough to poll per frame: mesh, texture, and splat totals are
running counters, and the volume / curve totals sum a handful of live
entries. A streaming or eviction policy compares ResidentBytes::total
against its own byte budget and calls the matching free_* to stay under
it. Built-in LUTs, IBL maps, and render targets are not counted; see
ResidentBytes.
Sourcepub fn vram_budget(&self, device: &Device) -> Option<VramBudget>
pub fn vram_budget(&self, device: &Device) -> Option<VramBudget>
Query the GPU’s device-local VRAM budget for device.
A thin wrapper over vram_budget so the
hardware total sits next to resident_bytes: a
policy sizes an eviction budget as a fraction of total_bytes and
compares ResidentBytes::total
against it. Returns None on backends that cannot be introspected. See
VramBudget for what available_bytes
reports per backend.
Source§impl DeviceResources
impl DeviceResources
Sourcepub fn register_lod_group(
&mut self,
levels: &[MeshId],
min_screen_sizes: &[f32],
) -> ViewportResult<LodGroupId>
pub fn register_lod_group( &mut self, levels: &[MeshId], min_screen_sizes: &[f32], ) -> ViewportResult<LodGroupId>
Group meshes that are already uploaded into a LOD chain.
levels lists the meshes full detail first; min_screen_sizes gives the
matching lower screen-size bound for each, as a fraction of viewport
height. The thresholds must strictly decrease.
All levels must be drawable the same way: they need the same named attributes and the same deformer attachment, otherwise switching to a level would silently change or drop coloring, warp, or skinning. That is checked here so a mismatch fails at registration instead of at render time.
§Errors
ViewportError::LodGroupEmptyiflevelsis empty.ViewportError::LodLevelCountMismatchif the two lists differ in length.ViewportError::SlotEmptyif a mesh id is not in the store.ViewportError::LodThresholdsNotDescendingif a threshold is not smaller than the previous one.ViewportError::LodLevelIncompatibleif a level’s attribute set or deform attachment differs from level 0.
Sourcepub fn free_lod_group(&mut self, id: LodGroupId) -> bool
pub fn free_lod_group(&mut self, id: LodGroupId) -> bool
Free a LOD group and, composition-aware, its member meshes.
Removes the group from the registry and bumps its slot generation so
id no longer resolves. Each member mesh is freed with
free_mesh unless another still-live group also
references it, in which case the shared mesh is left resident. Freeing
the member meshes is the point of the call: freeing a group without it
would leak every level’s GPU buffers.
Returns true if a group was freed, false if id did not resolve to a
live group (already freed or a stale handle).
Sourcepub fn set_lod_cull_below(
&mut self,
id: LodGroupId,
cull_below: Option<f32>,
) -> ViewportResult<()>
pub fn set_lod_cull_below( &mut self, id: LodGroupId, cull_below: Option<f32>, ) -> ViewportResult<()>
Set the screen size, as a fraction of viewport height, below which
objects in this group stop drawing. None disables size culling.
Applies to both SceneRenderItems and individual MeshInstanceItem
instances that use the group.
§Errors
Returns ViewportError::LodGroupNotFound if id is not registered.
Source§impl DeviceResources
impl DeviceResources
Sourcepub fn upload_mesh(
&mut self,
device: &Device,
vertices: &[Vertex],
indices: &[u32],
) -> ViewportResult<MeshId>
pub fn upload_mesh( &mut self, device: &Device, vertices: &[Vertex], indices: &[u32], ) -> ViewportResult<MeshId>
Create a GpuMesh from vertex/index slices and register it into the resource list.
Returns the MeshId of the new mesh.
§Errors
Returns ViewportError::EmptyMesh if
vertices or indices is empty.
§Examples
let result = resources.upload_mesh(device, &[], &[]);
assert!(matches!(result, Err(ViewportError::EmptyMesh { .. })));Sourcepub fn upload_mesh_data(
&mut self,
device: &Device,
data: &MeshData,
) -> ViewportResult<MeshId>
pub fn upload_mesh_data( &mut self, device: &Device, data: &MeshData, ) -> ViewportResult<MeshId>
Upload a MeshData (from the geometry primitives module) directly.
Converts positions/normals/indices to the GPU Vertex layout (white colour)
and creates a normal visualization line buffer (light blue #a0c4ff, length 0.1).
Returns the MeshId.
§Errors
Returns ViewportError::EmptyMesh if positions or indices are empty,
ViewportError::MeshLengthMismatch if positions and normals differ in length,
or ViewportError::InvalidVertexIndex if an index references a nonexistent vertex.
Sourcepub fn begin_upload_mesh_data(
&mut self,
device: &Device,
data: MeshData,
) -> ViewportResult<JobId>
pub fn begin_upload_mesh_data( &mut self, device: &Device, data: MeshData, ) -> ViewportResult<JobId>
Start an asynchronous mesh upload.
Returns immediately with a JobId. The CPU prep (tangent
computation, vertex repack, normal-line build) runs on a worker
thread; GPU buffer creation and store insertion run on the main
thread during the next process_uploads call after the worker
finishes. Once the status is Ready, call upload_result_mesh to
take the resulting MeshId.
Ownership of data transfers into the worker. To upload a mesh
without giving up ownership, clone the MeshData at the call site.
§Errors
Returns the same validation errors as upload_mesh_data (empty
mesh, length mismatch, invalid vertex index) before any job is
submitted.
Sourcepub fn upload_result_mesh(&mut self, id: JobId) -> ViewportResult<MeshId>
pub fn upload_result_mesh(&mut self, id: JobId) -> ViewportResult<MeshId>
Take the MeshId produced by a completed begin_upload_mesh_data
job.
Returns JobNotReady while the upload is still in flight, and
JobResultMissing for ids that have already been taken, were
issued by a different upload type, or never existed.
Sourcepub fn upload_mesh_data_pickable(
&mut self,
device: &Device,
data: &MeshData,
) -> ViewportResult<MeshId>
pub fn upload_mesh_data_pickable( &mut self, device: &Device, data: &MeshData, ) -> ViewportResult<MeshId>
Upload a MeshData and retain CPU positions and indices for picking.
Equivalent to upload_mesh_data. The CPU
position and index data is kept so that renderer.pick() can test
FACE, EDGE, and VERTEX hits against this mesh. Use this variant to
make the intent explicit at the call site.
§Errors
Same as upload_mesh_data.
Sourcepub fn set_pickable(&mut self, mesh_id: MeshId, pickable: bool)
pub fn set_pickable(&mut self, mesh_id: MeshId, pickable: bool)
Free or retain the CPU position and index data for an already-uploaded mesh.
set_pickable(id, false) drops the retained CPU data, freeing memory.
The mesh continues to render normally; it will be silently skipped for
FACE, EDGE, and VERTEX picks after this call.
set_pickable(id, true) is a no-op: CPU data is either already present
(the mesh was uploaded via [upload_mesh_data] or
[upload_mesh_data_pickable]) or it was freed and cannot be recovered
without re-uploading.
Has no effect if mesh_id is not found.
Sourcepub fn write_mesh_positions_normals(
&mut self,
queue: &Queue,
mesh_id: MeshId,
positions: &[[f32; 3]],
normals: &[[f32; 3]],
) -> ViewportResult<()>
pub fn write_mesh_positions_normals( &mut self, queue: &Queue, mesh_id: MeshId, positions: &[[f32; 3]], normals: &[[f32; 3]], ) -> ViewportResult<()>
Write new positions and normals into an existing mesh without reallocating GPU buffers.
The vertex count must match the original upload exactly. Use this for deforming meshes where topology is stable across frames: the index buffer, edge buffer, and bind groups are all reused. Colour, UVs, and tangents are written as defaults (white, zero, [0,0,0,1]).
The normal line visualization buffer is also updated in place if it was created at upload time.
Mutually exclusive per frame with
set_position_override_buffer and
set_normal_override_buffer for the
same mesh: the two write paths race. A debug assertion fires if both
are active. To switch from GPU-compute deformation back to CPU writes,
call clear_position_override /
clear_normal_override first.
§Errors
Returns ViewportError::StaleHandle
if mesh_id is out of range, ViewportError::MeshLengthMismatch
if positions and normals differ in length or do not match the existing vertex count.
Sourcepub fn set_position_override_buffer(
&mut self,
mesh_id: MeshId,
buffer: Buffer,
) -> ViewportResult<()>
pub fn set_position_override_buffer( &mut self, mesh_id: MeshId, buffer: Buffer, ) -> ViewportResult<()>
Bind a GPU storage buffer of per-vertex positions to mesh_id. The
standard mesh and skinned-mesh pipelines read positions from this
buffer instead of the vertex buffer’s position attribute on every frame
the binding is present.
Intended consumer: a GpuPlugin that
computes deformed positions on the GPU in pre_prepare (cloth, hair,
GPU particles, audio-reactive displacement). The override path
sidesteps the CPU round-trip that
write_mesh_positions_normals
requires.
The buffer must:
- have
wgpu::BufferUsages::STORAGE, - hold at least 3
f32per vertex (12 bytes each), in flat[x, y, z, x, y, z, ...]order. This matches the warp-attribute buffer layout and avoids WGSL’s 16-byte vec3 stride padding, so a consumer compute shader can write tightvec3data directly.
The shader bounds-checks arrayLength before reading, so a smaller
buffer falls back to in.position for out-of-range vertex indices.
Override and skinning compose: when both are active, the override replaces the bind-pose input and skinning is then applied on top.
Do not call this in the same frame as write_mesh_positions_normals
for the same mesh; the two write paths race and the result is
undefined. Pick one source for positions per frame.
§Errors
Returns ViewportError::StaleHandle
if mesh_id is not registered.
Sourcepub fn set_normal_override_buffer(
&mut self,
mesh_id: MeshId,
buffer: Buffer,
) -> ViewportResult<()>
pub fn set_normal_override_buffer( &mut self, mesh_id: MeshId, buffer: Buffer, ) -> ViewportResult<()>
Same idea as set_position_override_buffer
but for per-vertex normals (bound at group 1 binding 14).
§Errors
Returns ViewportError::StaleHandle
if mesh_id is not registered.
Sourcepub fn clear_position_override(&mut self, mesh_id: MeshId) -> ViewportResult<()>
pub fn clear_position_override(&mut self, mesh_id: MeshId) -> ViewportResult<()>
Revert the position source to the mesh’s vertex buffer attribute. Drops the override buffer handle; if no other owner holds it, wgpu frees it after the in-flight frames complete.
§Errors
Returns ViewportError::StaleHandle
if mesh_id is not registered.
Sourcepub fn clear_normal_override(&mut self, mesh_id: MeshId) -> ViewportResult<()>
pub fn clear_normal_override(&mut self, mesh_id: MeshId) -> ViewportResult<()>
Revert the normal source to the mesh’s vertex buffer attribute.
§Errors
Returns ViewportError::StaleHandle
if mesh_id is not registered.
Sourcepub fn replace_mesh_data(
&mut self,
device: &Device,
queue: &Queue,
mesh_id: MeshId,
data: &MeshData,
) -> ViewportResult<()>
pub fn replace_mesh_data( &mut self, device: &Device, queue: &Queue, mesh_id: MeshId, data: &MeshData, ) -> ViewportResult<()>
Replace the mesh at mesh_index with new geometry data.
When the new vertex and index counts match the existing mesh and no attributes are present, the existing GPU buffers are reused and data is written in place, avoiding GPU memory allocation. When topology changes, new buffers are allocated.
This is the only slot-targeting mesh operation, so it doubles as the
guard against a free racing a queued replace: the mesh_id generation is
checked here (and again in MeshStore::replace), so a handle whose mesh
was freed, or freed and its slot reused by a later upload, is rejected
rather than overwriting the mesh now in that slot. The async upload paths
need no such guard because they allocate a fresh slot at apply time.
§Errors
Returns ViewportError::StaleHandle if mesh_index is out of range
or the handle is stale, or any mesh validation error from the new data.
Sourcepub fn mesh(&self, id: MeshId) -> Option<&GpuMesh>
pub fn mesh(&self, id: MeshId) -> Option<&GpuMesh>
Get a reference to the mesh at the given index, or None if the slot is empty/invalid.
Sourcepub fn mesh_slot_count(&self) -> usize
pub fn mesh_slot_count(&self) -> usize
Total number of mesh slots (including empty/removed slots).
Sourcepub fn remove_mesh(&mut self, id: MeshId) -> bool
👎Deprecated: renamed to free_mesh
pub fn remove_mesh(&mut self, id: MeshId) -> bool
renamed to free_mesh
Deprecated alias for free_mesh.
Sourcepub fn free_mesh(&mut self, id: MeshId) -> bool
pub fn free_mesh(&mut self, id: MeshId) -> bool
Free a mesh, reclaiming its GPU buffers and slot.
Drops the GpuMesh (vertex, index, attribute buffers and its object bind
group; wgpu defers the real free until in-flight commands complete),
bumps the slot generation so id no longer resolves, and frees the slot
for a later upload to reuse. A stale id held elsewhere degrades to
fallback rendering rather than aliasing the reused slot.
Returns true if a mesh was freed, false if id did not resolve to a
live mesh. This is the residency-facing name for remove_mesh; the two
are equivalent. To free a mesh that is a member of a LOD group, free the
group with free_lod_group instead so shared
members are handled.
Sourcepub fn upload_volume_mesh(
&mut self,
device: &Device,
data: &VolumeMeshData,
) -> ViewportResult<VolumeMeshItem>
pub fn upload_volume_mesh( &mut self, device: &Device, data: &VolumeMeshData, ) -> ViewportResult<VolumeMeshItem>
Upload an unstructured volume mesh and return a ready-to-submit
VolumeMeshItem.
Extracts the boundary surface and uploads it through the standard mesh pipeline. Interior faces (shared by two cells) are discarded; only boundary faces (belonging to exactly one cell) are kept. Per-cell scalar and colour attributes are remapped to per-face attributes so the face-colouring path handles them automatically.
The returned item has transparency: None and projected_tet_id: None;
it renders as an opaque surface mesh. Use
upload_volume_mesh_with_transparency
instead if you need to toggle volumetric rendering at runtime.
Sourcepub fn upload_volume_mesh_with_transparency(
&mut self,
device: &Device,
data: VolumeMeshData,
scalar_attribute: &str,
) -> ViewportResult<VolumeMeshItem>
pub fn upload_volume_mesh_with_transparency( &mut self, device: &Device, data: VolumeMeshData, scalar_attribute: &str, ) -> ViewportResult<VolumeMeshItem>
Upload an unstructured volume mesh with both the boundary surface and the projected-tet decomposition needed for volumetric rendering.
The returned item carries:
boundary_mesh_id+face_to_cellfor the opaque surface draw and boundary-level cell picking,projected_tet_idfor the volumetric draw, andvolume_mesh_data(anArcover the input) for interior-inclusive cell picking when transparency is on.
Default transparency: None: the item renders as a boundary surface
until the host sets VolumeMeshItem::transparency
to Some(VolumeTransparency { .. }). Switching modes at runtime is free
because both GPU artifacts are already resident.
scalar_attribute names a key in data.cell_scalars; cells without the
attribute receive scalar 0.0. The scalar range is auto-detected from the
data and stored in the per-volume uniform.
Sourcepub fn upload_clipped_volume_mesh(
&mut self,
device: &Device,
data: &VolumeMeshData,
clip_planes: &[[f32; 4]],
) -> ViewportResult<VolumeMeshItem>
pub fn upload_clipped_volume_mesh( &mut self, device: &Device, data: &VolumeMeshData, clip_planes: &[[f32; 4]], ) -> ViewportResult<VolumeMeshItem>
Upload a clipped volume mesh, returning a ready-to-submit
VolumeMeshItem.
Each entry in clip_planes is [nx, ny, nz, d] where a point p is
kept when dot(p, [nx, ny, nz]) + d >= 0. An empty slice is equivalent
to upload_volume_mesh.
The returned item has transparency: None and projected_tet_id: None.
Sourcepub fn replace_clipped_volume_mesh(
&mut self,
device: &Device,
queue: &Queue,
mesh_id: MeshId,
data: &VolumeMeshData,
clip_planes: &[[f32; 4]],
) -> ViewportResult<Vec<u32>>
pub fn replace_clipped_volume_mesh( &mut self, device: &Device, queue: &Queue, mesh_id: MeshId, data: &VolumeMeshData, clip_planes: &[[f32; 4]], ) -> ViewportResult<Vec<u32>>
Replace an existing boundary-mesh slot with a freshly-extracted clipped
volume mesh, returning the new face_to_cell map.
Equivalent to calling upload_clipped_volume_mesh
and then replace_mesh_data, but without
allocating a new mesh slot. Use this for per-frame clip-plane updates to
avoid leaking GPU memory.
Sourcepub fn replace_sparse_volume_grid_data(
&mut self,
device: &Device,
queue: &Queue,
mesh_id: MeshId,
data: &SparseVolumeGridData,
) -> ViewportResult<()>
pub fn replace_sparse_volume_grid_data( &mut self, device: &Device, queue: &Queue, mesh_id: MeshId, data: &SparseVolumeGridData, ) -> ViewportResult<()>
Replace a previously uploaded sparse voxel grid in place.
Equivalent to calling upload_sparse_volume_grid_data
and then replace_mesh_data, but without allocating a new slot.
Use this for per-frame or per-interaction updates (e.g. voxel paint) to avoid leaking GPU memory.
Sourcepub fn upload_sparse_volume_grid_data(
&mut self,
device: &Device,
data: &SparseVolumeGridData,
) -> ViewportResult<MeshId>
pub fn upload_sparse_volume_grid_data( &mut self, device: &Device, data: &SparseVolumeGridData, ) -> ViewportResult<MeshId>
Upload a sparse voxel grid by extracting its boundary surface and uploading
the result via upload_mesh_data.
Only quad faces not shared between two active cells are kept. Per-cell scalars and colours are remapped to per-face attributes, and per-node scalars are averaged over the 4 quad corners to produce per-face scalars.
Returns the MeshId. Reference cell and node attributes via
AttributeRef { kind: AttributeKind::Face, .. }.
Sourcepub fn begin_upload_volume_mesh(
&mut self,
device: &Device,
data: VolumeMeshData,
) -> JobId
pub fn begin_upload_volume_mesh( &mut self, device: &Device, data: VolumeMeshData, ) -> JobId
Start an asynchronous boundary-only volume mesh upload.
Returns a JobId immediately. Boundary
extraction (extract_boundary_faces) and vertex prep
(prep_mesh_data) run on a worker thread; the apply step creates
GPU buffers and inserts the mesh. Take the resulting
VolumeMeshItem via
upload_result_volume_mesh.
Ownership of data transfers into the worker. The returned item has
transparency: None; this async path does not produce a projected-tet
decomposition. For volumetric rendering use the synchronous
upload_volume_mesh_with_transparency.
Sourcepub fn upload_result_volume_mesh(
&mut self,
id: JobId,
) -> ViewportResult<VolumeMeshItem>
pub fn upload_result_volume_mesh( &mut self, id: JobId, ) -> ViewportResult<VolumeMeshItem>
Take the VolumeMeshItem produced
by a completed
begin_upload_volume_mesh job.
Sourcepub fn begin_upload_clipped_volume_mesh(
&mut self,
device: &Device,
data: VolumeMeshData,
clip_planes: Vec<[f32; 4]>,
) -> JobId
pub fn begin_upload_clipped_volume_mesh( &mut self, device: &Device, data: VolumeMeshData, clip_planes: Vec<[f32; 4]>, ) -> JobId
Start an asynchronous clipped volume mesh upload. See
upload_clipped_volume_mesh for the
sync analog and the semantics of clip_planes.
Sourcepub fn upload_result_clipped_volume_mesh(
&mut self,
id: JobId,
) -> ViewportResult<VolumeMeshItem>
pub fn upload_result_clipped_volume_mesh( &mut self, id: JobId, ) -> ViewportResult<VolumeMeshItem>
Take the VolumeMeshItem produced
by a completed
begin_upload_clipped_volume_mesh job.
Sourcepub fn begin_upload_sparse_volume_grid_data(
&mut self,
device: &Device,
data: SparseVolumeGridData,
) -> JobId
pub fn begin_upload_sparse_volume_grid_data( &mut self, device: &Device, data: SparseVolumeGridData, ) -> JobId
Start an asynchronous sparse voxel grid upload.
Sourcepub fn upload_result_sparse_volume_grid(
&mut self,
id: JobId,
) -> ViewportResult<MeshId>
pub fn upload_result_sparse_volume_grid( &mut self, id: JobId, ) -> ViewportResult<MeshId>
Take the MeshId produced by a completed
begin_upload_sparse_volume_grid_data
job.
Sourcepub fn replace_projected_tet(
&mut self,
device: &Device,
id: ProjectedTetId,
data: &VolumeMeshData,
scalar_attribute: &str,
) -> ViewportResult<()>
pub fn replace_projected_tet( &mut self, device: &Device, id: ProjectedTetId, data: &VolumeMeshData, scalar_attribute: &str, ) -> ViewportResult<()>
Replace the tet buffer of an existing projected-tet mesh in-place.
Rebuilds the tet storage buffer (and its bind group) from the new scalar
attribute. The uniform buffer (density, thresholds, opacity) is reused;
only the cached scalar range is refreshed. Changing the colourmap on the
owning item is now free because the LUT is bound per-frame in render.rs,
so this call no longer takes a colourmap_id.
Source§impl DeviceResources
impl DeviceResources
Sourcepub fn replace_attribute(
&mut self,
queue: &Queue,
mesh_id: MeshId,
name: &str,
data: &[f32],
) -> ViewportResult<()>
pub fn replace_attribute( &mut self, queue: &Queue, mesh_id: MeshId, name: &str, data: &[f32], ) -> ViewportResult<()>
Write new scalar data into an existing attribute buffer in-place.
No GPU buffer reallocation, no mesh re-upload, no bind group rebuild is
required. The attribute bind group will be rebuilt on the next
prepare() call if the scalar range changes (tracked via last_tex_key).
§Errors
ViewportError::SlotEmpty:mesh_idnot found in the store.ViewportError::AttributeNotFound:namenot present on the mesh.ViewportError::AttributeLengthMismatch:data.len()differs from the original upload (same-topology requirement).
Source§impl DeviceResources
impl DeviceResources
Sourcepub fn set_deform_time(&mut self, queue: &Queue, time_seconds: f32)
pub fn set_deform_time(&mut self, queue: &Queue, time_seconds: f32)
Write the shared header uniform’s time_seconds field. Cheap; safe to
call per frame.
Sourcepub fn set_deform_slot_params(
&mut self,
queue: &Queue,
slot: usize,
params: [[f32; 4]; 4],
)
pub fn set_deform_slot_params( &mut self, queue: &Queue, slot: usize, params: [[f32; 4]; 4], )
Write the four vec4<f32> parameter words for one slot in the shared
header uniform.
Sourcepub fn attach_deform_slot(
&mut self,
device: &Device,
mesh_id: MeshId,
slot: usize,
stride_bytes: u32,
data: &[u8],
)
pub fn attach_deform_slot( &mut self, device: &Device, mesh_id: MeshId, slot: usize, stride_bytes: u32, data: &[u8], )
Attach raw bytes for one deformer slot on the given mesh.
stride_bytes is the per-vertex byte stride and must equal the
registered deformer’s per_vertex_stride. The data length is
expected to be vertex_count * stride_bytes; the renderer does not
validate the vertex count, only that the byte length is a multiple
of stride_bytes and 4.
Sourcepub fn detach_deform_slot(
&mut self,
device: &Device,
mesh_id: MeshId,
slot: usize,
) -> bool
pub fn detach_deform_slot( &mut self, device: &Device, mesh_id: MeshId, slot: usize, ) -> bool
Detach a per-mesh slot’s data. Returns true if any data was removed.
Sourcepub fn has_deform_slot(&self, mesh_id: MeshId, slot: usize) -> bool
pub fn has_deform_slot(&self, mesh_id: MeshId, slot: usize) -> bool
Returns true when the mesh has per-mesh data attached at the given
slot.
Sourcepub fn attach_deform_slot_instance(
&mut self,
device: &Device,
queue: &Queue,
mesh_id: MeshId,
instance_id: u32,
slot: usize,
stride_bytes: u32,
data: &[u8],
)
pub fn attach_deform_slot_instance( &mut self, device: &Device, queue: &Queue, mesh_id: MeshId, instance_id: u32, slot: usize, stride_bytes: u32, data: &[u8], )
Attach raw bytes for one deformer slot on a single instance of the
given mesh. Used for data that varies per instance (e.g. joint
palettes). stride_bytes is the per-element byte stride; the data
length must be a multiple of stride_bytes and 4.
Sourcepub fn detach_deform_slot_instance(
&mut self,
device: &Device,
queue: &Queue,
mesh_id: MeshId,
instance_id: u32,
slot: usize,
) -> bool
pub fn detach_deform_slot_instance( &mut self, device: &Device, queue: &Queue, mesh_id: MeshId, instance_id: u32, slot: usize, ) -> bool
Detach a per-instance slot’s data. Returns true if any data was
removed.
Sourcepub fn has_deform_slot_instance(
&self,
mesh_id: MeshId,
instance_id: u32,
slot: usize,
) -> bool
pub fn has_deform_slot_instance( &self, mesh_id: MeshId, instance_id: u32, slot: usize, ) -> bool
Returns true when the given instance of the mesh has per-instance
data attached at the given slot.
Sourcepub fn register_deformer(
&mut self,
device: &Device,
desc: DeformerDesc,
) -> ViewportResult<DeformerId>
pub fn register_deformer( &mut self, device: &Device, desc: DeformerDesc, ) -> ViewportResult<DeformerId>
Register a deformer against the mesh shader family.
Validates the descriptor’s name and allocates a slot, composes every
mesh-family base shader with the new deformer plus all previously
registered ones, and runs each composed module through wgpu’s
validator. On success, the LDR and HDR mesh.wgsl pipelines are
rebuilt from the freshly composed source so subsequent draws run
the registered body. Other mesh-family pipelines (instanced,
shadow, outline mask, OIT) continue to run the identity path until
their factories migrate to the same rebuild path.
On any validation failure the registration is rolled back: the previously composed sources stay live and the returned error names the shader that failed.
§Errors
ViewportError::DeformNameTakenwhendesc.nameis already registered.ViewportError::DeformShaderInvalidwhendesc.nameis not a valid WGSL identifier, or when any composed module fails validation.ViewportError::DeformSlotsExhaustedwhen allDEFORM_SLOT_COUNTslots are in use.
Sourcepub fn registered_deformer_count(&self) -> usize
pub fn registered_deformer_count(&self) -> usize
Number of currently registered deformers (host + internal).
Sourcepub fn deformer_id_by_name(&self, name: &str) -> Option<DeformerId>
pub fn deformer_id_by_name(&self, name: &str) -> Option<DeformerId>
Look up a registered deformer’s id by its name. Returns None when
no deformer with that name has been registered.
Sourcepub fn deform_slot_handle(&self, id: DeformerId) -> DeformSlotHandle
pub fn deform_slot_handle(&self, id: DeformerId) -> DeformSlotHandle
Build a DeformSlotHandle for the given deformer. Plugins stash
the handle at registration time and use it to write that slot’s
slot_params block from contexts (e.g. a GpuPlugin::pre_prepare)
that only carry &wgpu::Queue.
Source§impl DeviceResources
impl DeviceResources
Sourcepub fn upload_font(&mut self, ttf_bytes: &[u8]) -> Result<FontHandle, FontError>
pub fn upload_font(&mut self, ttf_bytes: &[u8]) -> Result<FontHandle, FontError>
Upload a user-supplied TTF font for use with overlay items.
Returns an opaque FontHandle that can be passed to [LabelItem],
[ScalarBarItem], or [RulerItem] via their font field. Pass
None on those items to use the built-in default font instead.
The font bytes must be a valid TrueType (.ttf) file.
Source§impl DeviceResources
impl DeviceResources
Sourcepub fn upload_overlay_texture(
&mut self,
device: &Device,
queue: &Queue,
width: u32,
height: u32,
rgba_data: &[u8],
) -> OverlayTextureId
pub fn upload_overlay_texture( &mut self, device: &Device, queue: &Queue, width: u32, height: u32, rgba_data: &[u8], ) -> OverlayTextureId
Upload RGBA8 pixel data as a persistent texture for overlay shape fills.
Returns an OverlayTextureId that can be stored in
OverlayShapeItem::texture. The texture persists for the lifetime of
this DeviceResources.
rgba_data must contain exactly width * height * 4 bytes in
row-major, top-to-bottom order. The data is treated as sRGB-encoded
(standard 8-bit image data).
Sourcepub fn begin_upload_overlay_texture(
&mut self,
device: &Device,
queue: &Queue,
width: u32,
height: u32,
rgba_data: Vec<u8>,
) -> ViewportResult<JobId>
pub fn begin_upload_overlay_texture( &mut self, device: &Device, queue: &Queue, width: u32, height: u32, rgba_data: Vec<u8>, ) -> ViewportResult<JobId>
Start an asynchronous overlay texture upload.
Returns a JobId immediately. Texture
creation and queue.write_texture run on a worker thread on cloned
Device and Queue handles; the apply step inserts the prepared
OverlayShapeTextureEntry into the store. Take the resulting
OverlayTextureId via
upload_result_overlay_texture.
Ownership of rgba_data transfers into the worker.
§Errors
Returns ViewportError::InvalidTextureData
before submission when rgba_data.len() != width * height * 4.
Sourcepub fn upload_result_overlay_texture(
&mut self,
id: JobId,
) -> ViewportResult<OverlayTextureId>
pub fn upload_result_overlay_texture( &mut self, id: JobId, ) -> ViewportResult<OverlayTextureId>
Take the OverlayTextureId produced by a completed
begin_upload_overlay_texture job.
Source§impl DeviceResources
impl DeviceResources
Sourcepub fn update_gizmo_mesh(
&mut self,
device: &Device,
queue: &Queue,
mode: GizmoMode,
hovered: GizmoAxis,
space_orientation: Quat,
)
pub fn update_gizmo_mesh( &mut self, device: &Device, queue: &Queue, mode: GizmoMode, hovered: GizmoAxis, space_orientation: Quat, )
Re-upload the gizmo mesh with updated hover highlight colours.
Called each frame when the hovered axis changes to brighten the appropriate axis colour. The gizmo mesh is small (~300 vertices), so re-uploading every frame is acceptable.
Sourcepub fn update_gizmo_uniform(&self, queue: &Queue, model: Mat4)
pub fn update_gizmo_uniform(&self, queue: &Queue, model: Mat4)
Update the gizmo model matrix uniform (translation to gizmo center + scale for screen size).
Sourcepub fn create_constraint_overlay(
&self,
device: &Device,
overlay: &ConstraintOverlay,
) -> (Buffer, Buffer, u32, Buffer, BindGroup)
pub fn create_constraint_overlay( &self, device: &Device, overlay: &ConstraintOverlay, ) -> (Buffer, Buffer, u32, Buffer, BindGroup)
Create a line-list overlay for an active transform constraint.
Source§impl DeviceResources
impl DeviceResources
Group-0 bind layout shared by every scene pipeline. Use as group 0 when building a plugin pipeline layout.
Sourcepub fn opaque_target_desc(&self) -> OpaqueTargetDesc
pub fn opaque_target_desc(&self) -> OpaqueTargetDesc
Render-target descriptor for the HDR opaque scene pass.
Sourcepub fn oit_target_desc(&self) -> OitTargetDesc
pub fn oit_target_desc(&self) -> OitTargetDesc
Render-target descriptor for the OIT pass (MRT: accum + reveal).
Sourcepub fn mask_target_desc(&self) -> MaskTargetDesc
pub fn mask_target_desc(&self) -> MaskTargetDesc
Render-target descriptor for the outline-mask pass.
Sourcepub fn pick_target_desc(&self) -> PickTargetDesc
pub fn pick_target_desc(&self) -> PickTargetDesc
Render-target descriptor for the pick-id pass.
Sourcepub fn shadow_target_desc(&self) -> ShadowTargetDesc
pub fn shadow_target_desc(&self) -> ShadowTargetDesc
Render-target descriptor for the shadow-atlas pass.
Sourcepub fn texture_view(&self, id: TextureId) -> Option<&TextureView>
pub fn texture_view(&self, id: TextureId) -> Option<&TextureView>
Borrow the TextureView for a texture previously uploaded via
upload_texture or
upload_normal_map.
Returns None if id does not refer to a live texture (a stale handle
whose texture was freed, or one out of range).
Lifetime contract: the returned view is valid until the texture is freed
with free_texture. Plugins that build a bind
group from this view must rebuild it after any operation that could
invalidate the texture (a free, device recreation). A safer pattern is to
fetch the view each frame just before building / rebuilding the bind
group.
Sourcepub fn texture_sampler(&self, id: TextureId) -> Option<&Sampler>
pub fn texture_sampler(&self, id: TextureId) -> Option<&Sampler>
Borrow the sampler the texture was uploaded with.
Most user textures are uploaded with a shared linear-repeat sampler;
prefer material_sampler when you need
the shared lib sampler rather than the per-texture instance.
Sourcepub fn material_sampler(&self) -> &Sampler
pub fn material_sampler(&self) -> &Sampler
Shared linear-repeat sampler used by the lib’s material pipelines.
Use this when building a plugin bind group that samples user
textures the same way Material does (linear filter, repeat wrap).
Sourcepub fn lut_sampler(&self) -> &Sampler
pub fn lut_sampler(&self) -> &Sampler
Shared linear-clamp sampler used by the lib for colormap LUTs.
Use this when sampling 1D LUT-style data (colourmaps, transfer functions) where the texture should not wrap.
Sourcepub fn shadow_filter_sampler(&self) -> &Sampler
pub fn shadow_filter_sampler(&self) -> &Sampler
Comparison sampler used for PCF shadow filtering.
Plugins that sample the shadow atlas directly (rather than through
viewport_sample_csm) use this sampler when binding the atlas.
Sourcepub fn deform_bind_group_layout(&self) -> &BindGroupLayout
pub fn deform_bind_group_layout(&self) -> &BindGroupLayout
Bind group layout for the per-vertex deformation sidecar.
Plugins building pipelines that draw meshes with registered deformers
add this layout at group 2 so their vertex stage can read from the
shared deform_data / deform_instance_data storage buffers.
Sourcepub fn texture_count(&self) -> usize
pub fn texture_count(&self) -> usize
Number of live user-uploaded textures.
id values in 0..texture_count() are addressable via
texture_view, with the caveat that promoted
IDs from async uploads may sit at the high end.
Sourcepub fn build_opaque_pipeline(
&self,
device: &Device,
opts: &PluginPipelineOpts<'_>,
) -> RenderPipeline
pub fn build_opaque_pipeline( &self, device: &Device, opts: &PluginPipelineOpts<'_>, ) -> RenderPipeline
Build an opaque scene pipeline that draws into the HDR scene pass.
Standard depth state: LessEqual test, depth write on. The pipeline
layout lists shared_bindings as group 0,
then extra_bind_group_layouts as groups 1.., in order. The plugin
owns all groups past 0.
Sourcepub fn build_oit_pipeline(
&self,
device: &Device,
opts: &PluginPipelineOpts<'_>,
) -> RenderPipeline
pub fn build_oit_pipeline( &self, device: &Device, opts: &PluginPipelineOpts<'_>, ) -> RenderPipeline
Build a transparent pipeline that draws into the OIT pass.
The fragment shader must return OitOutput,
writing both @location(0) (accum) and @location(1) (reveal).
Depth state: LessEqual test, depth write off.
Sourcepub fn build_mask_pipeline(
&self,
device: &Device,
opts: &PluginPipelineOpts<'_>,
) -> RenderPipeline
pub fn build_mask_pipeline( &self, device: &Device, opts: &PluginPipelineOpts<'_>, ) -> RenderPipeline
Build a pipeline for the outline-mask pass (R8 target).
Fragment shader must write 1.0 at @location(0) for any covered
pixel; use SHARED_MASK_WGSL.
Depth state: LessEqual test, no depth write.
Sourcepub fn build_pick_pipeline(
&self,
device: &Device,
opts: &PluginPipelineOpts<'_>,
) -> RenderPipeline
pub fn build_pick_pipeline( &self, device: &Device, opts: &PluginPipelineOpts<'_>, ) -> RenderPipeline
Build a pipeline for the pick-id pass (R32Uint target).
Fragment shader must write the item’s PickId value at
@location(0); use SHARED_PICK_WGSL.
Sourcepub fn build_shadow_pipeline(
&self,
device: &Device,
opts: &PluginPipelineOpts<'_>,
) -> RenderPipeline
pub fn build_shadow_pipeline( &self, device: &Device, opts: &PluginPipelineOpts<'_>, ) -> RenderPipeline
Build a depth-only pipeline for the shadow-atlas pass.
No fragment output. The fragment entry is optional; pass an empty
string to use a depth-only configuration with no fragment stage.
Standard depth state: LessEqual test, depth write on, with the
lib’s standard depth bias.
Source§impl DeviceResources
impl DeviceResources
Sourcepub fn upload_gaussian_splat(
&mut self,
device: &Device,
queue: &Queue,
data: &GaussianSplatData,
) -> ViewportResult<GaussianSplatId>
pub fn upload_gaussian_splat( &mut self, device: &Device, queue: &Queue, data: &GaussianSplatData, ) -> ViewportResult<GaussianSplatId>
Upload one Gaussian splat set to the GPU and return its handle.
Call once per splat set at startup (or when the set changes). The returned
[GaussianSplatId] is stable until [free_gaussian_splat] is called.
§Errors
Returns ViewportError::InvalidGaussianSplatData
if data.positions is empty or if the lengths of positions, scales,
rotations, and opacities do not all match.
§Examples
let result = renderer.upload_gaussian_splat(device, queue, &GaussianSplatData::default());
assert!(matches!(result, Err(ViewportError::InvalidGaussianSplatData { .. })));Sourcepub fn replace_gaussian_splat(
&mut self,
device: &Device,
queue: &Queue,
id: GaussianSplatId,
data: &GaussianSplatData,
) -> ViewportResult<()>
pub fn replace_gaussian_splat( &mut self, device: &Device, queue: &Queue, id: GaussianSplatId, data: &GaussianSplatData, ) -> ViewportResult<()>
Replace the contents of an uploaded Gaussian splat set in place, keeping
the same GaussianSplatId.
Items holding the handle pick up the new splats on the next frame with no
reassignment. The generation check is the in-flight guard: a stale handle
(its slot freed and reused) returns
StaleHandle instead of
overwriting whatever now occupies the slot. Use this for content that
changes over time (a re-trained or streamed splat set).
§Errors
InvalidGaussianSplatData
when data is empty or its per-attribute vectors disagree in length, or
StaleHandle if id does not
resolve to a live set.
Sourcepub fn free_gaussian_splat(&mut self, id: GaussianSplatId)
pub fn free_gaussian_splat(&mut self, id: GaussianSplatId)
Remove an uploaded Gaussian splat set by handle.
Sourcepub fn begin_upload_gaussian_splat(
&mut self,
device: &Device,
queue: &Queue,
data: GaussianSplatData,
) -> ViewportResult<JobId>
pub fn begin_upload_gaussian_splat( &mut self, device: &Device, queue: &Queue, data: GaussianSplatData, ) -> ViewportResult<JobId>
Start an asynchronous Gaussian splat upload.
Returns a JobId immediately. Vec4
padding for positions / scales / rotations and storage buffer
creation + writes all run on a worker thread on a cloned Device
and Queue. The apply step inserts the prepared GaussianSplatGpuSet
into the store and surfaces the resulting [GaussianSplatId].
§Errors
Returns [ViewportError::InvalidGaussianSplatData] before any job
is submitted when data.positions is empty or the per-attribute
vectors disagree in length.
Sourcepub fn upload_result_gaussian_splat(
&mut self,
id: JobId,
) -> ViewportResult<GaussianSplatId>
pub fn upload_result_gaussian_splat( &mut self, id: JobId, ) -> ViewportResult<GaussianSplatId>
Take the GaussianSplatId produced by a
completed begin_upload_gaussian_splat job.
Source§impl DeviceResources
impl DeviceResources
Sourcepub fn upload_glyph_set(
&mut self,
device: &Device,
queue: &Queue,
item: &GlyphItem,
) -> GlyphSetId
pub fn upload_glyph_set( &mut self, device: &Device, queue: &Queue, item: &GlyphItem, ) -> GlyphSetId
Pre-upload a glyph set and return a typed handle.
Sourcepub fn drop_glyph_set(&mut self, id: GlyphSetId) -> bool
pub fn drop_glyph_set(&mut self, id: GlyphSetId) -> bool
Remove a pre-uploaded glyph set.
Sourcepub fn replace_glyph_set(
&mut self,
device: &Device,
queue: &Queue,
id: GlyphSetId,
item: &GlyphItem,
) -> bool
pub fn replace_glyph_set( &mut self, device: &Device, queue: &Queue, id: GlyphSetId, item: &GlyphItem, ) -> bool
Replace the geometry of a pre-uploaded glyph set, keeping the same id.
Sourcepub fn begin_upload_glyph_set(
&mut self,
device: &Device,
queue: &Queue,
item: GlyphItem,
) -> JobId
pub fn begin_upload_glyph_set( &mut self, device: &Device, queue: &Queue, item: GlyphItem, ) -> JobId
Start an asynchronous glyph set upload.
Sourcepub fn upload_result_glyph_set(
&mut self,
id: JobId,
) -> ViewportResult<GlyphSetId>
pub fn upload_result_glyph_set( &mut self, id: JobId, ) -> ViewportResult<GlyphSetId>
Take the GlyphSetId produced by a
completed begin_upload_glyph_set job.
Sourcepub fn upload_tensor_glyph_set(
&mut self,
device: &Device,
queue: &Queue,
item: &TensorGlyphItem,
) -> TensorGlyphSetId
pub fn upload_tensor_glyph_set( &mut self, device: &Device, queue: &Queue, item: &TensorGlyphItem, ) -> TensorGlyphSetId
Pre-upload a tensor glyph set and return a typed handle.
Sourcepub fn drop_tensor_glyph_set(&mut self, id: TensorGlyphSetId) -> bool
pub fn drop_tensor_glyph_set(&mut self, id: TensorGlyphSetId) -> bool
Remove a pre-uploaded tensor glyph set.
Sourcepub fn replace_tensor_glyph_set(
&mut self,
device: &Device,
queue: &Queue,
id: TensorGlyphSetId,
item: &TensorGlyphItem,
) -> bool
pub fn replace_tensor_glyph_set( &mut self, device: &Device, queue: &Queue, id: TensorGlyphSetId, item: &TensorGlyphItem, ) -> bool
Replace the geometry of a pre-uploaded tensor glyph set, keeping the same id.
Sourcepub fn begin_upload_tensor_glyph_set(
&mut self,
device: &Device,
queue: &Queue,
item: TensorGlyphItem,
) -> JobId
pub fn begin_upload_tensor_glyph_set( &mut self, device: &Device, queue: &Queue, item: TensorGlyphItem, ) -> JobId
Start an asynchronous tensor glyph set upload.
Sourcepub fn upload_result_tensor_glyph_set(
&mut self,
id: JobId,
) -> ViewportResult<TensorGlyphSetId>
pub fn upload_result_tensor_glyph_set( &mut self, id: JobId, ) -> ViewportResult<TensorGlyphSetId>
Take the TensorGlyphSetId produced by a
completed begin_upload_tensor_glyph_set job.
Source§impl DeviceResources
impl DeviceResources
Sourcepub fn upload_point_cloud(
&mut self,
device: &Device,
queue: &Queue,
item: &PointCloudItem,
) -> PointCloudId
pub fn upload_point_cloud( &mut self, device: &Device, queue: &Queue, item: &PointCloudItem, ) -> PointCloudId
Pre-upload a point cloud and return a typed handle.
Sourcepub fn drop_point_cloud(&mut self, id: PointCloudId) -> bool
pub fn drop_point_cloud(&mut self, id: PointCloudId) -> bool
Remove a pre-uploaded point cloud.
Sourcepub fn replace_point_cloud(
&mut self,
device: &Device,
queue: &Queue,
id: PointCloudId,
item: &PointCloudItem,
) -> bool
pub fn replace_point_cloud( &mut self, device: &Device, queue: &Queue, id: PointCloudId, item: &PointCloudItem, ) -> bool
Replace the geometry of a pre-uploaded point cloud, keeping the same id.
Sourcepub fn begin_upload_point_cloud(
&mut self,
device: &Device,
queue: &Queue,
item: PointCloudItem,
) -> JobId
pub fn begin_upload_point_cloud( &mut self, device: &Device, queue: &Queue, item: PointCloudItem, ) -> JobId
Start an asynchronous point cloud upload.
Sourcepub fn upload_result_point_cloud(
&mut self,
id: JobId,
) -> ViewportResult<PointCloudId>
pub fn upload_result_point_cloud( &mut self, id: JobId, ) -> ViewportResult<PointCloudId>
Take the PointCloudId produced by a
completed begin_upload_point_cloud job.
Source§impl DeviceResources
impl DeviceResources
Sourcepub fn upload_polyline(
&mut self,
device: &Device,
queue: &Queue,
item: &PolylineItem,
) -> PolylineId
pub fn upload_polyline( &mut self, device: &Device, queue: &Queue, item: &PolylineItem, ) -> PolylineId
Pre-upload a polyline and return a typed handle.
The returned PolylineId refers to GPU
buffers retained by the renderer until [drop_polyline] is called.
Submit a PolylineRefItem on
SceneFrame::polyline_refs each frame to draw the polyline at a
custom model transform without rebuilding its segment buffer.
The viewport size used for screen-space miter calculations is set from the most recent ref-item draw of this polyline. Stationary callers can rely on it being correct after the first frame.
Sourcepub fn drop_polyline(&mut self, id: PolylineId) -> bool
pub fn drop_polyline(&mut self, id: PolylineId) -> bool
Remove a pre-uploaded polyline. Returns true if a polyline was
actually removed, false if the id was already invalid.
Sourcepub fn replace_polyline(
&mut self,
device: &Device,
queue: &Queue,
id: PolylineId,
item: &PolylineItem,
) -> bool
pub fn replace_polyline( &mut self, device: &Device, queue: &Queue, id: PolylineId, item: &PolylineItem, ) -> bool
Replace the geometry of a pre-uploaded polyline, keeping the same
PolylineId.
Returns true if the id was valid and the polyline was replaced,
false if the slot was empty (call upload_polyline instead).
Sourcepub fn begin_upload_polyline(
&mut self,
device: &Device,
queue: &Queue,
item: PolylineItem,
) -> JobId
pub fn begin_upload_polyline( &mut self, device: &Device, queue: &Queue, item: PolylineItem, ) -> JobId
Start an asynchronous polyline upload.
Returns a JobId immediately. The upload
runs during the next process_uploads call (driven by prepare_scene);
once the status is Ready, call
upload_result_polyline to take the
resulting handle.
Ownership of item transfers into the worker.
Sourcepub fn upload_result_polyline(
&mut self,
id: JobId,
) -> ViewportResult<PolylineId>
pub fn upload_result_polyline( &mut self, id: JobId, ) -> ViewportResult<PolylineId>
Take the PolylineId produced by a
completed begin_upload_polyline job.
Source§impl DeviceResources
impl DeviceResources
Sourcepub fn upload_sprite_set(
&mut self,
device: &Device,
queue: &Queue,
item: &SpriteItem,
) -> SpriteSetId
pub fn upload_sprite_set( &mut self, device: &Device, queue: &Queue, item: &SpriteItem, ) -> SpriteSetId
Pre-upload a static sprite set and return a typed handle.
Use this for sprites whose positions, sizes, and colours never
change between frames: foliage, signage, light flares. Submit a
SpriteSetRefItem on
SceneFrame::sprite_set_refs each frame to draw the set.
Sourcepub fn drop_sprite_set(&mut self, id: SpriteSetId) -> bool
pub fn drop_sprite_set(&mut self, id: SpriteSetId) -> bool
Remove a pre-uploaded sprite set.
Sourcepub fn replace_sprite_set(
&mut self,
device: &Device,
queue: &Queue,
id: SpriteSetId,
item: &SpriteItem,
) -> bool
pub fn replace_sprite_set( &mut self, device: &Device, queue: &Queue, id: SpriteSetId, item: &SpriteItem, ) -> bool
Replace the contents of a pre-uploaded sprite set, keeping the same id.
Sourcepub fn begin_upload_sprite_set(
&mut self,
device: &Device,
queue: &Queue,
item: SpriteItem,
) -> JobId
pub fn begin_upload_sprite_set( &mut self, device: &Device, queue: &Queue, item: SpriteItem, ) -> JobId
Start an asynchronous sprite set upload.
Sourcepub fn upload_result_sprite_set(
&mut self,
id: JobId,
) -> ViewportResult<SpriteSetId>
pub fn upload_result_sprite_set( &mut self, id: JobId, ) -> ViewportResult<SpriteSetId>
Take the SpriteSetId produced by a completed
begin_upload_sprite_set job.
Sourcepub fn upload_sprite_instance_set(
&mut self,
device: &Device,
queue: &Queue,
item: &SpriteItem,
) -> SpriteInstanceSetId
pub fn upload_sprite_instance_set( &mut self, device: &Device, queue: &Queue, item: &SpriteItem, ) -> SpriteInstanceSetId
Pre-upload a sprite instance set and return a typed handle.
Use this for sprites whose definition (texture, blend, size mode)
is stable but whose instance transforms change every frame: NPCs,
item drops, damage numbers. Submit a
SpriteInstanceSetRefItem
on SceneFrame::sprite_instance_set_refs each frame.
The current implementation pre-bakes both the definition and the instance transforms; full per-frame instance transform override against a stable definition is a planned follow-up.
Sourcepub fn drop_sprite_instance_set(&mut self, id: SpriteInstanceSetId) -> bool
pub fn drop_sprite_instance_set(&mut self, id: SpriteInstanceSetId) -> bool
Remove a pre-uploaded sprite instance set.
Sourcepub fn replace_sprite_instance_set(
&mut self,
device: &Device,
queue: &Queue,
id: SpriteInstanceSetId,
item: &SpriteItem,
) -> bool
pub fn replace_sprite_instance_set( &mut self, device: &Device, queue: &Queue, id: SpriteInstanceSetId, item: &SpriteItem, ) -> bool
Replace the contents of a pre-uploaded sprite instance set, keeping the same id.
Sourcepub fn begin_upload_sprite_instance_set(
&mut self,
device: &Device,
queue: &Queue,
item: SpriteItem,
) -> JobId
pub fn begin_upload_sprite_instance_set( &mut self, device: &Device, queue: &Queue, item: SpriteItem, ) -> JobId
Start an asynchronous sprite instance set upload.
Sourcepub fn upload_result_sprite_instance_set(
&mut self,
id: JobId,
) -> ViewportResult<SpriteInstanceSetId>
pub fn upload_result_sprite_instance_set( &mut self, id: JobId, ) -> ViewportResult<SpriteInstanceSetId>
Take the SpriteInstanceSetId produced by a completed
begin_upload_sprite_instance_set job.
Source§impl DeviceResources
impl DeviceResources
Sourcepub fn upload_streamtube(
&mut self,
device: &Device,
queue: &Queue,
item: &StreamtubeItem,
) -> StreamtubeId
pub fn upload_streamtube( &mut self, device: &Device, queue: &Queue, item: &StreamtubeItem, ) -> StreamtubeId
Pre-upload a streamtube and return a typed handle.
Submit a StreamtubeRefItem on
SceneFrame::streamtube_refs each frame to draw the tube at a
per-frame model transform without rebuilding its mesh.
Sourcepub fn drop_streamtube(&mut self, id: StreamtubeId) -> bool
pub fn drop_streamtube(&mut self, id: StreamtubeId) -> bool
Remove a pre-uploaded streamtube.
Sourcepub fn replace_streamtube(
&mut self,
device: &Device,
queue: &Queue,
id: StreamtubeId,
item: &StreamtubeItem,
) -> bool
pub fn replace_streamtube( &mut self, device: &Device, queue: &Queue, id: StreamtubeId, item: &StreamtubeItem, ) -> bool
Replace the geometry of a pre-uploaded streamtube, keeping the same id.
Sourcepub fn upload_tube(
&mut self,
device: &Device,
queue: &Queue,
item: &TubeItem,
) -> TubeId
pub fn upload_tube( &mut self, device: &Device, queue: &Queue, item: &TubeItem, ) -> TubeId
Pre-upload a general tube and return a typed handle.
Sourcepub fn replace_tube(
&mut self,
device: &Device,
queue: &Queue,
id: TubeId,
item: &TubeItem,
) -> bool
pub fn replace_tube( &mut self, device: &Device, queue: &Queue, id: TubeId, item: &TubeItem, ) -> bool
Replace the geometry of a pre-uploaded tube, keeping the same id.
Sourcepub fn upload_ribbon(
&mut self,
device: &Device,
queue: &Queue,
item: &RibbonItem,
) -> RibbonId
pub fn upload_ribbon( &mut self, device: &Device, queue: &Queue, item: &RibbonItem, ) -> RibbonId
Pre-upload a ribbon and return a typed handle.
Sourcepub fn drop_ribbon(&mut self, id: RibbonId) -> bool
pub fn drop_ribbon(&mut self, id: RibbonId) -> bool
Remove a pre-uploaded ribbon.
Sourcepub fn replace_ribbon(
&mut self,
device: &Device,
queue: &Queue,
id: RibbonId,
item: &RibbonItem,
) -> bool
pub fn replace_ribbon( &mut self, device: &Device, queue: &Queue, id: RibbonId, item: &RibbonItem, ) -> bool
Replace the geometry of a pre-uploaded ribbon, keeping the same id.
Sourcepub fn begin_upload_streamtube(
&mut self,
device: &Device,
queue: &Queue,
item: StreamtubeItem,
) -> JobId
pub fn begin_upload_streamtube( &mut self, device: &Device, queue: &Queue, item: StreamtubeItem, ) -> JobId
Start an asynchronous streamtube upload.
Sourcepub fn upload_result_streamtube(
&mut self,
id: JobId,
) -> ViewportResult<StreamtubeId>
pub fn upload_result_streamtube( &mut self, id: JobId, ) -> ViewportResult<StreamtubeId>
Take the StreamtubeId produced by a
completed begin_upload_streamtube job.
Sourcepub fn begin_upload_tube(
&mut self,
device: &Device,
queue: &Queue,
item: TubeItem,
) -> JobId
pub fn begin_upload_tube( &mut self, device: &Device, queue: &Queue, item: TubeItem, ) -> JobId
Start an asynchronous tube upload.
Sourcepub fn upload_result_tube(&mut self, id: JobId) -> ViewportResult<TubeId>
pub fn upload_result_tube(&mut self, id: JobId) -> ViewportResult<TubeId>
Take the TubeId produced by a completed
begin_upload_tube job.
Sourcepub fn begin_upload_ribbon(
&mut self,
device: &Device,
queue: &Queue,
item: RibbonItem,
) -> JobId
pub fn begin_upload_ribbon( &mut self, device: &Device, queue: &Queue, item: RibbonItem, ) -> JobId
Start an asynchronous ribbon upload.
Sourcepub fn upload_result_ribbon(&mut self, id: JobId) -> ViewportResult<RibbonId>
pub fn upload_result_ribbon(&mut self, id: JobId) -> ViewportResult<RibbonId>
Take the RibbonId produced by a completed
begin_upload_ribbon job.
Source§impl DeviceResources
impl DeviceResources
Sourcepub fn process_uploads(&mut self, device: &Device, queue: &Queue)
pub fn process_uploads(&mut self, device: &Device, queue: &Queue)
Advance the upload-job runner. Worker results received since the previous call are observed, GPU submissions are polled, completed jobs are folded into renderer state, and any completion callbacks fire on the caller’s thread.
Apply closures and callbacks both run after the runner’s mutex is released, so they are free to query the runner or submit a fresh job without risk of deadlock.
Sourcepub fn process_uploads_with_budget(
&mut self,
device: &Device,
queue: &Queue,
budget: FrameBudget,
)
pub fn process_uploads_with_budget( &mut self, device: &Device, queue: &Queue, budget: FrameBudget, )
Advance the upload-job runner with a cap on per-call apply-step work.
Behaves the same as process_uploads except that, after the
runner has been advanced and any failure callbacks fired, the
caller stops popping apply closures off the queue once budget
elapses. Remaining apply closures stay on the queue and are
picked up by the next call. Their owning jobs continue to report
UploadStatus::Pending until their apply runs, so the typed
result is never observably available before it is in place.
The budget covers only the main-thread apply work and the preceding device poll. Worker-thread time is independent. The check happens between applies, so a single long-running apply may push past the deadline once it has started; the budget is a soft cap, not a hard deadline.
Sourcepub fn job_duration(&self, id: JobId) -> Option<Duration>
pub fn job_duration(&self, id: JobId) -> Option<Duration>
Total wall-clock work duration for a completed job.
The value is the sum of the worker thread’s elapsed time and the
main-thread apply-step elapsed time. It excludes frame-pacing
delays (the time the apply step sat waiting for process_uploads
to be called). For sync uploads this method returns None; sync
callers measure their own wall-clock around the call.
Returns None for jobs that are still in flight, were never issued,
or whose duration record has already been dropped via
drop_job_duration. The runner retains durations until the consumer
drops them so single-frame retention is not enough.
Sourcepub fn drop_job_duration(&mut self, id: JobId)
pub fn drop_job_duration(&mut self, id: JobId)
Drop the recorded duration for id. Call this after reading the
value via job_duration; otherwise the duration table grows over
time.
Sourcepub fn upload_status(&self, id: JobId) -> UploadStatus
pub fn upload_status(&self, id: JobId) -> UploadStatus
Look up the current state of a submitted upload job.
Sourcepub fn uploads_pending(&self) -> usize
pub fn uploads_pending(&self) -> usize
Number of upload jobs still in flight.
Sourcepub fn all_uploads_complete(&self) -> bool
pub fn all_uploads_complete(&self) -> bool
True when no upload jobs are in flight.
Sourcepub fn on_upload_complete<F>(&mut self, id: JobId, cb: F)
pub fn on_upload_complete<F>(&mut self, id: JobId, cb: F)
Register a callback to fire when a job finishes. The callback runs on
the caller’s thread during the next process_uploads call. If the
job has already finished and is still in the short retention window,
the callback fires immediately on the calling thread.
Sourcepub fn drain_until(
&mut self,
device: &Device,
queue: &Queue,
id: JobId,
) -> ViewportResult<()>
pub fn drain_until( &mut self, device: &Device, queue: &Queue, id: JobId, ) -> ViewportResult<()>
Block the calling thread, driving process_uploads until id reaches
a terminal state.
Returns Ok(()) when the job’s worker (and any GPU submission it
queued) completes successfully. Returns the worker error when the job
fails. Used internally by the synchronous upload_* entries to wrap
their begin_upload_* counterparts in a single round-trip; consumers
who want to wait on a specific async upload can call it directly.
The loop sleeps for a short interval between polls so it does not pin
a CPU core while the worker is running. It does not call back into the
caller’s event loop; if you have other work to interleave, drive
process_uploads yourself instead.
§Errors
Returns ViewportError::JobResultMissing
if id has already been reaped or was never issued, and the worker’s
error verbatim when the job ends in Failed.
Source§impl DeviceResources
impl DeviceResources
Sourcepub fn upload_volume_for_mc(
&mut self,
device: &Device,
queue: &Queue,
vol: &VolumeData,
) -> ViewportResult<McVolumeId>
pub fn upload_volume_for_mc( &mut self, device: &Device, queue: &Queue, vol: &VolumeData, ) -> ViewportResult<McVolumeId>
Upload a VolumeData to GPU, pre-allocating all intermediate and output
buffers for GPU marching cubes.
The returned McVolumeId is stable until [free_mc_volume] is called.
Returns Err(ViewportError::McBufferTooLarge) if any required buffer exceeds
the device’s max_buffer_size; the caller should fall back to CPU isosurface
extraction.
Source§impl DeviceResources
impl DeviceResources
Sourcepub fn begin_upload_volume_for_mc(
&mut self,
device: &Device,
queue: &Queue,
vol: VolumeData,
) -> JobId
pub fn begin_upload_volume_for_mc( &mut self, device: &Device, queue: &Queue, vol: VolumeData, ) -> JobId
Start an asynchronous marching-cubes-ready volume upload.
Returns a JobId immediately. Slab
sizing, scalar buffer allocation, and intermediate / output buffer
allocation run on a worker thread on cloned Device and Queue
handles. The apply step inserts the resulting GPU buffers into the
MC volume store; once UploadStatus::Ready, call
upload_result_volume_mc to take
the McVolumeId.
Ownership of vol transfers into the worker.
§Errors
The worker surfaces
ViewportError::McBufferTooLarge
through [UploadStatus::Failed] when the device’s
max_storage_buffer_binding_size cannot fit a single Z-cell layer.
Sourcepub fn upload_result_volume_mc(
&mut self,
id: JobId,
) -> ViewportResult<McVolumeId>
pub fn upload_result_volume_mc( &mut self, id: JobId, ) -> ViewportResult<McVolumeId>
Take the McVolumeId produced by a completed
begin_upload_volume_for_mc job.
Sourcepub fn free_mc_volume(&mut self, id: McVolumeId)
pub fn free_mc_volume(&mut self, id: McVolumeId)
Free a MC volume: drop its slab GPU buffers to reclaim the memory now,
mark the slot free, and bump its generation so a stale handle no longer
resolves. The emptied slot is reused by a later upload. Dropping the
buffers drops this volume out of resident_bytes
immediately (wgpu defers the real GPU free until in-flight commands that
reference the buffers complete).
Source§impl DeviceResources
impl DeviceResources
Sourcepub fn upload_volume(
&mut self,
device: &Device,
queue: &Queue,
data: &[f32],
dims: [u32; 3],
) -> VolumeId
pub fn upload_volume( &mut self, device: &Device, queue: &Queue, data: &[f32], dims: [u32; 3], ) -> VolumeId
Upload a 3D scalar field to the GPU as an R32Float 3D texture.
data must be a flat array of dims[0] * dims[1] * dims[2] scalars in
x-fastest order (index = x + ynx + znx*ny).
Returns a VolumeId that can be stored in VolumeItem::volume_id.
Sourcepub fn begin_upload_volume(
&mut self,
device: &Device,
queue: &Queue,
data: Vec<f32>,
dims: [u32; 3],
) -> ViewportResult<JobId>
pub fn begin_upload_volume( &mut self, device: &Device, queue: &Queue, data: Vec<f32>, dims: [u32; 3], ) -> ViewportResult<JobId>
Start an asynchronous volume upload.
Returns a JobId immediately. The 3D
texture creation and queue.write_texture run on a worker thread on
cloned Device and Queue handles; once the job reports
UploadStatus::Ready, call
upload_result_volume to take the
resulting VolumeId.
Ownership of data transfers into the worker.
§Errors
Returns ViewportError::VolumeDataLengthMismatch
if data.len() != dims[0] * dims[1] * dims[2] before any job is
submitted.
Sourcepub fn upload_result_volume(&mut self, id: JobId) -> ViewportResult<VolumeId>
pub fn upload_result_volume(&mut self, id: JobId) -> ViewportResult<VolumeId>
Take the VolumeId produced by a
completed begin_upload_volume job.
Returns JobNotReady while the upload is still in flight, and
JobResultMissing for ids that have already been taken, were
issued by a different upload type, or never existed.
Auto Trait Implementations§
impl !Freeze for DeviceResources
impl !RefUnwindSafe for DeviceResources
impl !UnwindSafe for DeviceResources
impl Send for DeviceResources
impl Sync for DeviceResources
impl Unpin for DeviceResources
impl UnsafeUnpin for DeviceResources
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.