pub struct FilterResources { /* private fields */ }Expand description
The GPU resources a frame’s filter rounds are executed with, beyond the two pooled pages they ping-pong between.
Three of them, and each is the engine’s only one of its kind: the
filter-data texture holding every filter in the frame’s 48-byte parameter
block, the bilinear sampler
(filter_sampler) the blur kernels
read their source page through, and the instance buffer one quad per pass is
drawn from.
Public because this is executing a filter pass — the renderer holds one
and drives it over the pages the scheduler named, and tests/filters.rs
drives the same type over pages of its own on real hardware. That second
caller is not a convenience: frust_scene carries no filter command yet
(the scene seam is a later plan), so a filter layer cannot reach
EngineRenderer::encode through a Scene at all, and driving this type
directly is the only way the ported WGSL is exercised on a device.
Implementations§
Source§impl FilterResources
impl FilterResources
Sourcepub fn prepare(
&mut self,
device: &Device,
queue: &Queue,
pipeline: &RenderPipeline,
blocks: &[GpuFilterData],
passes: u32,
)
pub fn prepare( &mut self, device: &Device, queue: &Queue, pipeline: &RenderPipeline, blocks: &[GpuFilterData], passes: u32, )
Uploads this frame’s parameter blocks and reserves room for passes
pass instances, growing either resource if the frame outgrew it.
pipeline is the one EnginePipeline::Filter describes; it is needed
because wgpu derives a pipeline’s bind-group layouts from its shader
module, so the group naming the filter-data texture can only be built
against the pipeline that will bind it.
A block count no filter-data texture could hold (see
filter_data_texture_height) leaves the group unbuilt, which leaves
every filter pass of the frame issuing no draw — the page is still
cleared, so the layer composites as transparent rather than as whatever
its page last held. Unreachable in practice, and “draw less, never
wrong” when it is not.
Sourcepub fn write_instance(
&self,
queue: &Queue,
index: u32,
instance: &FilterInstanceData,
)
pub fn write_instance( &self, queue: &Queue, index: u32, instance: &FilterInstanceData, )
Writes one pass’s instance into slot index of the instance buffer.
Separate from Self::prepare because a pass’s dest_texture_size is
the extent the texture pool quantized its destination page up to, and
NDC is computed against the attachment’s real extent — only the round
that acquires the page knows it. A queue write issued while the frame is
being recorded still lands ahead of the command buffers it is submitted
with, which is the same ordering a page’s viewport uniform already
relies on.
A slot past the reserved capacity is dropped rather than written, which
leaves that pass drawing whatever the slot last held; unreachable, since
prepare reserved one slot per pass of this very frame.
Sourcepub fn record_pass(
&self,
device: &Device,
encoder: &mut CommandEncoder,
plan: &FilterPassPlan<'_>,
)
pub fn record_pass( &self, device: &Device, encoder: &mut CommandEncoder, plan: &FilterPassPlan<'_>, )
Records one filter pass into encoder: clear the destination page, then
draw the one instanced quad that filters plan’s source into it.
The clear is unconditional and the draw is not. A filter pass writes only the region its step names — a decimated one a quarter of the texels the pass before it did — and the kernels sample past that region without bounds checks, so whatever surrounds it has to be transparent rather than a previous holder’s pixels. That has to hold even on the path where the pass itself cannot be issued, or the layer’s composite would sample the page’s previous tenant instead of nothing.
The pass is opened and closed here, on the caller’s own encoder: a filter
round is not an exception to EngineRenderer::encode’s contract.
Sourcepub fn record_pass_timed(
&self,
device: &Device,
encoder: &mut CommandEncoder,
plan: &FilterPassPlan<'_>,
timestamps: Option<RenderPassTimestampWrites<'_>>,
)
pub fn record_pass_timed( &self, device: &Device, encoder: &mut CommandEncoder, plan: &FilterPassPlan<'_>, timestamps: Option<RenderPassTimestampWrites<'_>>, )
Self::record_pass, stamping the pass’s GPU time into timestamps.
A separate method rather than a field on FilterPassPlan: the plan is
public and built by struct literal outside this crate, so a new required
field would break every one of those call sites to serve a diagnostic
they do not use. None records exactly what Self::record_pass does.