use crate::backend::RenderState;
use super::{bind_group::AsBindGroup, PipelineSet, PIPELINE_VIEWPORT};
pub struct PipelineBindGroup;
impl AsBindGroup for PipelineBindGroup {
fn bind_group_layout(device: &wgpu::Device) -> wgpu::BindGroupLayout {
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
label: None,
entries: &[
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStages::VERTEX,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
min_binding_size: None,
},
count: None,
},
wgpu::BindGroupLayoutEntry {
binding: 1,
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Texture {
sample_type: wgpu::TextureSampleType::Float { filterable: true },
view_dimension: wgpu::TextureViewDimension::D2,
multisampled: false,
},
count: None,
},
wgpu::BindGroupLayoutEntry {
binding: 2,
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
count: None,
},
],
})
}
fn as_bind_group(&self, render_state: &RenderState) -> wgpu::BindGroup {
render_state
.device
.create_bind_group(&wgpu::BindGroupDescriptor {
label: None,
layout: &Self::bind_group_layout(&render_state.device),
entries: &[
wgpu::BindGroupEntry {
binding: 0,
resource: render_state.viewport.scale_buffer.as_entire_binding(),
},
wgpu::BindGroupEntry {
binding: 1,
resource: wgpu::BindingResource::TextureView(
&render_state.viewport.viewport_texture.texture_view,
),
},
wgpu::BindGroupEntry {
binding: 2,
resource: wgpu::BindingResource::Sampler(&render_state.default_sampler),
},
],
})
}
}
pub fn register_viewport_pipeline(
RenderState {
pipelines,
surface_format,
device,
..
}: &mut RenderState,
) {
let copy_shader = device.create_shader_module(wgpu::include_wgsl!("shaders/viewport.wgsl"));
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
bind_group_layouts: &[&PipelineBindGroup::bind_group_layout(device)],
..Default::default()
});
let fragment_target = &[Some(wgpu::ColorTargetState {
format: *surface_format,
blend: Some(wgpu::BlendState::ALPHA_BLENDING),
write_mask: wgpu::ColorWrites::ALL,
})];
let descriptor = wgpu::RenderPipelineDescriptor {
label: Some("viewport_pipeline"),
layout: Some(&pipeline_layout),
vertex: wgpu::VertexState {
module: ©_shader,
entry_point: None,
buffers: &[],
compilation_options: wgpu::PipelineCompilationOptions::default(),
},
fragment: Some(wgpu::FragmentState {
module: ©_shader,
entry_point: None,
compilation_options: wgpu::PipelineCompilationOptions::default(),
targets: fragment_target,
}),
primitive: wgpu::PrimitiveState {
topology: wgpu::PrimitiveTopology::TriangleList,
..Default::default()
},
depth_stencil: None,
multisample: wgpu::MultisampleState::default(),
multiview: None,
cache: None,
};
let pipeline = device.create_render_pipeline(&descriptor);
let copy_pipeline = PipelineSet {
pipeline: pipeline,
pipeline_bind_group: Box::new(PipelineBindGroup),
};
pipelines.insert(PIPELINE_VIEWPORT, copy_pipeline);
}