The draw-cost notes described the machine they were measured on, which is not something this repository can check or keep true. What is left is what the file measures and how to read it; the rest lives with the machine. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
153 lines
4.8 KiB
Rust
153 lines
4.8 KiB
Rust
use iris_core::{UiData, UiRenderNode, UiRenderState};
|
|
use pollster::FutureExt;
|
|
use std::sync::Arc;
|
|
use wgpu::*;
|
|
use winit::{dpi::PhysicalSize, window::Window};
|
|
|
|
pub const CLEAR_COLOR: Color = Color::BLACK;
|
|
|
|
pub struct UiRenderer {
|
|
window: Arc<Window>,
|
|
surface: Surface<'static>,
|
|
device: Device,
|
|
queue: Queue,
|
|
config: SurfaceConfiguration,
|
|
encoder: CommandEncoder,
|
|
pub ui: UiRenderNode,
|
|
}
|
|
|
|
impl UiRenderer {
|
|
pub fn update(&mut self, ui: &mut UiData, render: &mut UiRenderState) {
|
|
self.ui.update(&self.device, &self.queue, ui, render);
|
|
}
|
|
|
|
pub fn draw(&mut self) {
|
|
let output = match self.surface.get_current_texture() {
|
|
CurrentSurfaceTexture::Success(texture) => texture,
|
|
CurrentSurfaceTexture::Suboptimal(texture) => {
|
|
self.surface.configure(&self.device, &self.config);
|
|
texture
|
|
}
|
|
CurrentSurfaceTexture::Outdated | CurrentSurfaceTexture::Lost => {
|
|
self.surface.configure(&self.device, &self.config);
|
|
return;
|
|
}
|
|
CurrentSurfaceTexture::Timeout
|
|
| CurrentSurfaceTexture::Occluded
|
|
| CurrentSurfaceTexture::Validation => return,
|
|
};
|
|
let view = output
|
|
.texture
|
|
.create_view(&TextureViewDescriptor::default());
|
|
|
|
let mut encoder = std::mem::replace(&mut self.encoder, Self::create_encoder(&self.device));
|
|
{
|
|
let render_pass = &mut encoder.begin_render_pass(&RenderPassDescriptor {
|
|
color_attachments: &[Some(RenderPassColorAttachment {
|
|
view: &view,
|
|
resolve_target: None,
|
|
ops: Operations {
|
|
load: LoadOp::Clear(CLEAR_COLOR),
|
|
store: StoreOp::Store,
|
|
},
|
|
depth_slice: None,
|
|
})],
|
|
..Default::default()
|
|
});
|
|
self.ui.draw(render_pass);
|
|
}
|
|
|
|
self.queue.submit(std::iter::once(encoder.finish()));
|
|
self.window.pre_present_notify();
|
|
self.queue.present(output);
|
|
}
|
|
|
|
pub fn resize(&mut self, size: &PhysicalSize<u32>) {
|
|
self.config.width = size.width;
|
|
self.config.height = size.height;
|
|
self.surface.configure(&self.device, &self.config);
|
|
self.ui.resize((size.width, size.height), &self.queue);
|
|
}
|
|
|
|
fn create_encoder(device: &Device) -> CommandEncoder {
|
|
device.create_command_encoder(&CommandEncoderDescriptor {
|
|
label: Some("Render Encoder"),
|
|
})
|
|
}
|
|
|
|
pub fn new(window: Arc<Window>) -> Self {
|
|
let size = window.inner_size();
|
|
|
|
let instance = Instance::new(InstanceDescriptor {
|
|
backends: Backends::PRIMARY,
|
|
display: Some(Box::new(window.clone())),
|
|
..InstanceDescriptor::new_without_display_handle()
|
|
});
|
|
|
|
let surface = instance
|
|
.create_surface(window.clone())
|
|
.expect("Could not create window surface!");
|
|
|
|
let adapter = instance
|
|
.request_adapter(&RequestAdapterOptions {
|
|
power_preference: PowerPreference::default(),
|
|
compatible_surface: Some(&surface),
|
|
force_fallback_adapter: false,
|
|
apply_limit_buckets: false,
|
|
})
|
|
.block_on()
|
|
.expect("Could not get adapter!");
|
|
|
|
let (device, queue) = adapter
|
|
.request_device(&DeviceDescriptor {
|
|
required_limits: Limits {
|
|
max_buffer_size: 1 << 30,
|
|
..Default::default()
|
|
},
|
|
..Default::default()
|
|
})
|
|
.block_on()
|
|
.expect("Could not get device!");
|
|
|
|
let surface_caps = surface.get_capabilities(&adapter);
|
|
let surface_format = surface_caps
|
|
.formats
|
|
.iter()
|
|
.copied()
|
|
.find(|f| f.is_srgb())
|
|
.unwrap_or(surface_caps.formats[0]);
|
|
|
|
let config = SurfaceConfiguration {
|
|
usage: TextureUsages::RENDER_ATTACHMENT,
|
|
format: surface_format,
|
|
color_space: SurfaceColorSpace::Auto,
|
|
width: size.width,
|
|
height: size.height,
|
|
present_mode: PresentMode::AutoVsync,
|
|
alpha_mode: surface_caps.alpha_modes[0],
|
|
desired_maximum_frame_latency: 2,
|
|
view_formats: vec![],
|
|
};
|
|
|
|
surface.configure(&device, &config);
|
|
|
|
let encoder = Self::create_encoder(&device);
|
|
|
|
let ui = UiRenderNode::new(&device, &config);
|
|
|
|
Self {
|
|
surface,
|
|
device,
|
|
queue,
|
|
config,
|
|
encoder,
|
|
ui,
|
|
window,
|
|
}
|
|
}
|
|
|
|
pub fn window(&self) -> &Window {
|
|
self.window.as_ref()
|
|
}
|
|
}
|