use std::borrow::Cow;
use bytemuck::{Pod, Zeroable};
use aetna_core::paint::QuadInstance;
#[repr(C)]
#[derive(Copy, Clone, Pod, Zeroable, Debug)]
pub(crate) struct FrameUniforms {
pub viewport: [f32; 2],
pub time: f32,
pub scale_factor: f32,
}
const INSTANCE_ATTRS: [wgpu::VertexAttribute; 7] = wgpu::vertex_attr_array![
1 => Float32x4, 2 => Float32x4, 3 => Float32x4, 4 => Float32x4, 5 => Float32x4, 6 => Float32x4, 7 => Float32x4, ];
pub(crate) fn build_quad_pipeline(
device: &wgpu::Device,
layout: &wgpu::PipelineLayout,
target_format: wgpu::TextureFormat,
sample_count: u32,
label: &str,
wgsl: &str,
per_sample_shading: bool,
) -> wgpu::RenderPipeline {
let wgsl = if per_sample_shading {
Cow::Borrowed(wgsl)
} else {
Cow::Owned(wgsl.replace(
"@interpolate(perspective, sample)",
"@interpolate(perspective)",
))
};
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: Some(label),
source: wgpu::ShaderSource::Wgsl(wgsl),
});
device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some(label),
layout: Some(layout),
vertex: wgpu::VertexState {
module: &shader,
entry_point: Some("vs_main"),
compilation_options: Default::default(),
buffers: &[
wgpu::VertexBufferLayout {
array_stride: (2 * std::mem::size_of::<f32>()) as u64,
step_mode: wgpu::VertexStepMode::Vertex,
attributes: &[wgpu::VertexAttribute {
shader_location: 0,
format: wgpu::VertexFormat::Float32x2,
offset: 0,
}],
},
wgpu::VertexBufferLayout {
array_stride: std::mem::size_of::<QuadInstance>() as u64,
step_mode: wgpu::VertexStepMode::Instance,
attributes: &INSTANCE_ATTRS,
},
],
},
fragment: Some(wgpu::FragmentState {
module: &shader,
entry_point: Some("fs_main"),
compilation_options: Default::default(),
targets: &[Some(wgpu::ColorTargetState {
format: target_format,
blend: Some(wgpu::BlendState::ALPHA_BLENDING),
write_mask: wgpu::ColorWrites::ALL,
})],
}),
primitive: wgpu::PrimitiveState {
topology: wgpu::PrimitiveTopology::TriangleStrip,
strip_index_format: None,
front_face: wgpu::FrontFace::Ccw,
cull_mode: None,
polygon_mode: wgpu::PolygonMode::Fill,
unclipped_depth: false,
conservative: false,
},
depth_stencil: None,
multisample: wgpu::MultisampleState {
count: sample_count,
mask: !0,
alpha_to_coverage_enabled: false,
},
multiview_mask: None,
cache: None,
})
}