use crate::{FrameResources, RenderResources};
use wgpu::*;
#[derive(Debug)]
pub struct WgpuRenderState {
pub device: *const Device,
pub render_pass_encoder: *mut std::ffi::c_void,
}
impl WgpuRenderState {
pub unsafe fn new(device: &Device, render_pass: &mut RenderPass) -> Self {
Self {
device: device as *const Device,
render_pass_encoder: render_pass as *mut _ as *mut std::ffi::c_void,
}
}
pub unsafe fn device(&self) -> &Device {
unsafe { &*self.device }
}
pub unsafe fn render_pass_encoder(&mut self) -> &mut RenderPass<'_> {
unsafe { &mut *(self.render_pass_encoder as *mut RenderPass) }
}
}
#[derive(Debug, Clone)]
pub struct WgpuInitInfo {
pub instance: Option<Instance>,
pub adapter: Option<Adapter>,
pub device: Device,
pub queue: Queue,
pub num_frames_in_flight: u32,
pub render_target_format: TextureFormat,
pub depth_stencil_format: Option<TextureFormat>,
pub pipeline_multisample_state: MultisampleState,
}
impl WgpuInitInfo {
pub fn new(device: Device, queue: Queue, render_target_format: TextureFormat) -> Self {
Self {
instance: None,
adapter: None,
device,
queue,
num_frames_in_flight: 3,
render_target_format,
depth_stencil_format: None,
pipeline_multisample_state: MultisampleState {
count: 1,
mask: !0,
alpha_to_coverage_enabled: false,
},
}
}
pub fn with_frames_in_flight(mut self, count: u32) -> Self {
self.num_frames_in_flight = count;
self
}
pub fn with_depth_stencil_format(mut self, format: TextureFormat) -> Self {
self.depth_stencil_format = Some(format);
self
}
pub fn with_multisample_state(mut self, state: MultisampleState) -> Self {
self.pipeline_multisample_state = state;
self
}
pub fn with_instance(mut self, instance: Instance) -> Self {
self.instance = Some(instance);
self
}
pub fn with_adapter(mut self, adapter: Adapter) -> Self {
self.adapter = Some(adapter);
self
}
}
pub struct WgpuBackendData {
pub init_info: WgpuInitInfo,
pub instance: Option<Instance>,
pub adapter: Option<Adapter>,
pub device: Device,
pub queue: Queue,
pub render_target_format: TextureFormat,
pub depth_stencil_format: Option<TextureFormat>,
pub pipeline_state: Option<RenderPipeline>,
pub render_resources: RenderResources,
pub frame_resources: Vec<FrameResources>,
pub num_frames_in_flight: u32,
pub frame_index: u32,
}
impl WgpuBackendData {
pub fn new(init_info: WgpuInitInfo) -> Self {
let queue = init_info.queue.clone();
let num_frames = init_info.num_frames_in_flight;
let frame_resources = (0..num_frames).map(|_| FrameResources::new()).collect();
Self {
instance: init_info.instance.clone(),
adapter: init_info.adapter.clone(),
device: init_info.device.clone(),
queue,
render_target_format: init_info.render_target_format,
depth_stencil_format: init_info.depth_stencil_format,
pipeline_state: None,
render_resources: RenderResources::new(),
frame_resources,
num_frames_in_flight: num_frames,
frame_index: u32::MAX, init_info,
}
}
pub fn current_frame_resources(&mut self) -> &mut FrameResources {
let index = (self.frame_index % self.num_frames_in_flight) as usize;
&mut self.frame_resources[index]
}
pub fn frame_resources_at(&mut self, index: usize) -> Option<&mut FrameResources> {
self.frame_resources.get_mut(index)
}
pub fn next_frame(&mut self) {
if self.frame_index == u32::MAX {
self.frame_index = 0;
} else {
self.frame_index = self.frame_index.wrapping_add(1);
}
}
pub fn is_initialized(&self) -> bool {
self.pipeline_state.is_some()
}
}