pebble/wgpu/render_pass.rs
1use crate::wgpu::{buffer::Buffer, buffers::BindGroup, material::RenderPipeline};
2
3/// A render pass, opaque — the value [`ActiveFrame::begin_pass`](crate::rendering::active_frame::ActiveFrame::begin_pass)/
4/// [`render_context`](crate::rendering::active_frame::ActiveFrame::render_context)
5/// hands back for [`WGPUBackend`](super::backend::WGPUBackend). There's no
6/// way to reach the underlying `wgpu::RenderPass` from outside this crate —
7/// every draw-time operation is a method here instead.
8pub struct RenderPass<'a> {
9 raw: wgpu::RenderPass<'a>,
10}
11
12impl<'a> RenderPass<'a> {
13 pub(crate) fn new(raw: wgpu::RenderPass<'a>) -> Self {
14 Self { raw }
15 }
16
17 pub fn set_pipeline(&mut self, pipeline: &RenderPipeline) {
18 self.raw.set_pipeline(pipeline.raw());
19 }
20
21 /// `offsets` is the dynamic-offset slice for any
22 /// [`BindingKind::dynamic_uniform_buffer`](super::binding::BindingKind::dynamic_uniform_buffer)/
23 /// [`dynamic_storage_buffer`](super::binding::BindingKind::dynamic_storage_buffer)
24 /// entries in this bind group's layout, in the order they appear —
25 /// empty if none.
26 pub fn set_bind_group(&mut self, index: u32, bind_group: &BindGroup, offsets: &[u32]) {
27 self.raw.set_bind_group(index, Some(bind_group.raw()), offsets);
28 }
29
30 /// Binds `buffer` in its entirety at vertex slot `slot`.
31 pub fn set_vertex_buffer(&mut self, slot: u32, buffer: &'a Buffer) {
32 self.raw.set_vertex_buffer(slot, buffer.raw().slice(..));
33 }
34
35 /// Binds `buffer` in its entirety as the index buffer.
36 pub fn set_index_buffer(&mut self, buffer: &'a Buffer, format: IndexFormat) {
37 self.raw.set_index_buffer(buffer.raw().slice(..), format.into());
38 }
39
40 pub fn draw(&mut self, vertices: std::ops::Range<u32>, instances: std::ops::Range<u32>) {
41 self.raw.draw(vertices, instances);
42 }
43
44 pub fn draw_indexed(
45 &mut self,
46 indices: std::ops::Range<u32>,
47 base_vertex: i32,
48 instances: std::ops::Range<u32>,
49 ) {
50 self.raw.draw_indexed(indices, base_vertex, instances);
51 }
52
53 /// Drops the borrow-checker tie to whatever this pass's encoder was
54 /// borrowed from, without actually extending its real lifetime — see
55 /// `wgpu::RenderPass::forget_lifetime`'s own docs for the safety
56 /// contract. `pub(crate)` only, and only compiled in with the
57 /// `profiler` feature: needed by [`profiler`](super::profiler) to
58 /// satisfy `egui_wgpu::Renderer::render`'s `RenderPass<'static>`
59 /// requirement, not something ordinary rendering code needs.
60 #[cfg(feature = "profiler")]
61 pub(crate) fn forget_lifetime(self) -> RenderPass<'static> {
62 RenderPass { raw: self.raw.forget_lifetime() }
63 }
64
65 /// `pub(crate)` escape hatch for internal code (the profiler overlay)
66 /// that hands this pass to a third-party renderer (`egui_wgpu`)
67 /// expecting a raw `wgpu::RenderPass`.
68 #[cfg(feature = "profiler")]
69 pub(crate) fn raw_mut(&mut self) -> &mut wgpu::RenderPass<'a> {
70 &mut self.raw
71 }
72}
73
74/// Index buffer element width — mirrors `wgpu::IndexFormat` (which has
75/// exactly these two variants).
76#[derive(Clone, Copy, PartialEq, Eq)]
77pub enum IndexFormat {
78 Uint16,
79 Uint32,
80}
81
82impl From<IndexFormat> for wgpu::IndexFormat {
83 fn from(format: IndexFormat) -> Self {
84 match format {
85 IndexFormat::Uint16 => wgpu::IndexFormat::Uint16,
86 IndexFormat::Uint32 => wgpu::IndexFormat::Uint32,
87 }
88 }
89}