use wgpu::*;
use super::cubemap::CubemapTexture;
use super::textures::ChannelTexture;
pub fn create_bind_group_layout(device: &Device) -> BindGroupLayout {
device.create_bind_group_layout(&BindGroupLayoutDescriptor {
label: Some("Custom Shader Bind Group Layout"),
entries: &[
BindGroupLayoutEntry {
binding: 0,
visibility: ShaderStages::VERTEX | ShaderStages::FRAGMENT,
ty: BindingType::Buffer {
ty: BufferBindingType::Uniform,
has_dynamic_offset: false,
min_binding_size: None,
},
count: None,
},
BindGroupLayoutEntry {
binding: 1,
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Texture {
sample_type: TextureSampleType::Float { filterable: true },
view_dimension: TextureViewDimension::D2,
multisampled: false,
},
count: None,
},
BindGroupLayoutEntry {
binding: 2,
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Sampler(SamplerBindingType::Filtering),
count: None,
},
BindGroupLayoutEntry {
binding: 3,
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Texture {
sample_type: TextureSampleType::Float { filterable: true },
view_dimension: TextureViewDimension::D2,
multisampled: false,
},
count: None,
},
BindGroupLayoutEntry {
binding: 4,
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Sampler(SamplerBindingType::Filtering),
count: None,
},
BindGroupLayoutEntry {
binding: 5,
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Texture {
sample_type: TextureSampleType::Float { filterable: true },
view_dimension: TextureViewDimension::D2,
multisampled: false,
},
count: None,
},
BindGroupLayoutEntry {
binding: 6,
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Sampler(SamplerBindingType::Filtering),
count: None,
},
BindGroupLayoutEntry {
binding: 7,
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Texture {
sample_type: TextureSampleType::Float { filterable: true },
view_dimension: TextureViewDimension::D2,
multisampled: false,
},
count: None,
},
BindGroupLayoutEntry {
binding: 8,
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Sampler(SamplerBindingType::Filtering),
count: None,
},
BindGroupLayoutEntry {
binding: 9,
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Texture {
sample_type: TextureSampleType::Float { filterable: true },
view_dimension: TextureViewDimension::D2,
multisampled: false,
},
count: None,
},
BindGroupLayoutEntry {
binding: 10,
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Sampler(SamplerBindingType::Filtering),
count: None,
},
BindGroupLayoutEntry {
binding: 11,
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Texture {
sample_type: TextureSampleType::Float { filterable: true },
view_dimension: TextureViewDimension::Cube,
multisampled: false,
},
count: None,
},
BindGroupLayoutEntry {
binding: 12,
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Sampler(SamplerBindingType::Filtering),
count: None,
},
BindGroupLayoutEntry {
binding: 13,
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Buffer {
ty: BufferBindingType::Uniform,
has_dynamic_offset: false,
min_binding_size: None,
},
count: None,
},
],
})
}
pub struct BindGroupInputs<'a> {
pub layout: &'a BindGroupLayout,
pub uniform_buffer: &'a Buffer,
pub intermediate_texture_view: &'a TextureView,
pub custom_uniform_buffer: &'a Buffer,
pub sampler: &'a Sampler,
pub channel_textures: &'a [ChannelTexture; 4],
pub cubemap: &'a CubemapTexture,
}
pub fn create_bind_group(device: &Device, inputs: BindGroupInputs<'_>) -> BindGroup {
let BindGroupInputs {
layout,
uniform_buffer,
intermediate_texture_view,
custom_uniform_buffer,
sampler,
channel_textures,
cubemap,
} = inputs;
device.create_bind_group(&BindGroupDescriptor {
label: Some("Custom Shader Bind Group"),
layout,
entries: &[
BindGroupEntry {
binding: 0,
resource: uniform_buffer.as_entire_binding(),
},
BindGroupEntry {
binding: 1,
resource: BindingResource::TextureView(&channel_textures[0].view),
},
BindGroupEntry {
binding: 2,
resource: BindingResource::Sampler(&channel_textures[0].sampler),
},
BindGroupEntry {
binding: 3,
resource: BindingResource::TextureView(&channel_textures[1].view),
},
BindGroupEntry {
binding: 4,
resource: BindingResource::Sampler(&channel_textures[1].sampler),
},
BindGroupEntry {
binding: 5,
resource: BindingResource::TextureView(&channel_textures[2].view),
},
BindGroupEntry {
binding: 6,
resource: BindingResource::Sampler(&channel_textures[2].sampler),
},
BindGroupEntry {
binding: 7,
resource: BindingResource::TextureView(&channel_textures[3].view),
},
BindGroupEntry {
binding: 8,
resource: BindingResource::Sampler(&channel_textures[3].sampler),
},
BindGroupEntry {
binding: 9,
resource: BindingResource::TextureView(intermediate_texture_view),
},
BindGroupEntry {
binding: 10,
resource: BindingResource::Sampler(sampler),
},
BindGroupEntry {
binding: 11,
resource: BindingResource::TextureView(&cubemap.view),
},
BindGroupEntry {
binding: 12,
resource: BindingResource::Sampler(&cubemap.sampler),
},
BindGroupEntry {
binding: 13,
resource: custom_uniform_buffer.as_entire_binding(),
},
],
})
}
pub fn create_render_pipeline(
device: &Device,
shader_module: &ShaderModule,
bind_group_layout: &BindGroupLayout,
surface_format: TextureFormat,
label: Option<&str>,
) -> RenderPipeline {
let pipeline_layout = device.create_pipeline_layout(&PipelineLayoutDescriptor {
label: Some(label.unwrap_or("Custom Shader Pipeline Layout")),
bind_group_layouts: &[Some(bind_group_layout)],
immediate_size: 0,
});
device.create_render_pipeline(&RenderPipelineDescriptor {
label: Some(label.unwrap_or("Custom Shader Pipeline")),
layout: Some(&pipeline_layout),
vertex: VertexState {
module: shader_module,
entry_point: Some("vs_main"),
buffers: &[],
compilation_options: Default::default(),
},
fragment: Some(FragmentState {
module: shader_module,
entry_point: Some("fs_main"),
targets: &[Some(ColorTargetState {
format: surface_format,
blend: Some(BlendState::PREMULTIPLIED_ALPHA_BLENDING),
write_mask: ColorWrites::ALL,
})],
compilation_options: Default::default(),
}),
primitive: PrimitiveState {
topology: PrimitiveTopology::TriangleStrip,
..Default::default()
},
depth_stencil: None,
multisample: MultisampleState::default(),
cache: None,
multiview_mask: None,
})
}