diff options
Diffstat (limited to 'wgpu/src/quad.rs')
-rw-r--r-- | wgpu/src/quad.rs | 261 |
1 files changed, 128 insertions, 133 deletions
diff --git a/wgpu/src/quad.rs b/wgpu/src/quad.rs index 9047080d..24d20cfa 100644 --- a/wgpu/src/quad.rs +++ b/wgpu/src/quad.rs @@ -1,7 +1,10 @@ use crate::Transformation; +use iced_graphics::layer; use iced_native::Rectangle; +use bytemuck::{Pod, Zeroable}; use std::mem; +use wgpu::util::DeviceExt; #[derive(Debug)] pub struct Pipeline { @@ -14,57 +17,58 @@ pub struct Pipeline { } impl Pipeline { - pub fn new( - device: &mut wgpu::Device, - format: wgpu::TextureFormat, - ) -> Pipeline { + pub fn new(device: &wgpu::Device, format: wgpu::TextureFormat) -> Pipeline { let constant_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { - bindings: &[wgpu::BindGroupLayoutBinding { + label: Some("iced_wgpu::quad uniforms layout"), + entries: &[wgpu::BindGroupLayoutEntry { binding: 0, visibility: wgpu::ShaderStage::VERTEX, - ty: wgpu::BindingType::UniformBuffer { dynamic: false }, + ty: wgpu::BindingType::UniformBuffer { + dynamic: false, + min_binding_size: wgpu::BufferSize::new( + mem::size_of::<Uniforms>() as u64, + ), + }, + count: None, }], }); - let constants_buffer = device - .create_buffer_mapped( - 1, - wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST, - ) - .fill_from_slice(&[Uniforms::default()]); + let constants_buffer = device.create_buffer(&wgpu::BufferDescriptor { + label: Some("iced_wgpu::quad uniforms buffer"), + size: mem::size_of::<Uniforms>() as u64, + usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST, + mapped_at_creation: false, + }); let constants = device.create_bind_group(&wgpu::BindGroupDescriptor { + label: Some("iced_wgpu::quad uniforms bind group"), layout: &constant_layout, - bindings: &[wgpu::Binding { + entries: &[wgpu::BindGroupEntry { binding: 0, - resource: wgpu::BindingResource::Buffer { - buffer: &constants_buffer, - range: 0..std::mem::size_of::<Uniforms>() as u64, - }, + resource: wgpu::BindingResource::Buffer( + constants_buffer.slice(..), + ), }], }); let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: Some("iced_wgpu::quad pipeline layout"), + push_constant_ranges: &[], bind_group_layouts: &[&constant_layout], }); - let vs = include_bytes!("shader/quad.vert.spv"); - let vs_module = device.create_shader_module( - &wgpu::read_spirv(std::io::Cursor::new(&vs[..])) - .expect("Read quad vertex shader as SPIR-V"), - ); + let vs_module = device + .create_shader_module(wgpu::include_spirv!("shader/quad.vert.spv")); - let fs = include_bytes!("shader/quad.frag.spv"); - let fs_module = device.create_shader_module( - &wgpu::read_spirv(std::io::Cursor::new(&fs[..])) - .expect("Read quad fragment shader as SPIR-V"), - ); + let fs_module = device + .create_shader_module(wgpu::include_spirv!("shader/quad.frag.spv")); let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { - layout: &layout, + label: Some("iced_wgpu::quad pipeline"), + layout: Some(&layout), vertex_stage: wgpu::ProgrammableStageDescriptor { module: &vs_module, entry_point: "main", @@ -76,9 +80,7 @@ impl Pipeline { rasterization_state: Some(wgpu::RasterizationStateDescriptor { front_face: wgpu::FrontFace::Cw, cull_mode: wgpu::CullMode::None, - depth_bias: 0, - depth_bias_slope_scale: 0.0, - depth_bias_clamp: 0.0, + ..Default::default() }), primitive_topology: wgpu::PrimitiveTopology::TriangleList, color_states: &[wgpu::ColorStateDescriptor { @@ -96,70 +98,80 @@ impl Pipeline { write_mask: wgpu::ColorWrite::ALL, }], depth_stencil_state: None, - index_format: wgpu::IndexFormat::Uint16, - vertex_buffers: &[ - wgpu::VertexBufferDescriptor { - stride: mem::size_of::<Vertex>() as u64, - step_mode: wgpu::InputStepMode::Vertex, - attributes: &[wgpu::VertexAttributeDescriptor { - shader_location: 0, - format: wgpu::VertexFormat::Float2, - offset: 0, - }], - }, - wgpu::VertexBufferDescriptor { - stride: mem::size_of::<Quad>() as u64, - step_mode: wgpu::InputStepMode::Instance, - attributes: &[ - wgpu::VertexAttributeDescriptor { - shader_location: 1, + vertex_state: wgpu::VertexStateDescriptor { + index_format: wgpu::IndexFormat::Uint16, + vertex_buffers: &[ + wgpu::VertexBufferDescriptor { + stride: mem::size_of::<Vertex>() as u64, + step_mode: wgpu::InputStepMode::Vertex, + attributes: &[wgpu::VertexAttributeDescriptor { + shader_location: 0, format: wgpu::VertexFormat::Float2, offset: 0, - }, - wgpu::VertexAttributeDescriptor { - shader_location: 2, - format: wgpu::VertexFormat::Float2, - offset: 4 * 2, - }, - wgpu::VertexAttributeDescriptor { - shader_location: 3, - format: wgpu::VertexFormat::Float4, - offset: 4 * (2 + 2), - }, - wgpu::VertexAttributeDescriptor { - shader_location: 4, - format: wgpu::VertexFormat::Float4, - offset: 4 * (2 + 2 + 4), - }, - wgpu::VertexAttributeDescriptor { - shader_location: 5, - format: wgpu::VertexFormat::Float, - offset: 4 * (2 + 2 + 4 + 4), - }, - wgpu::VertexAttributeDescriptor { - shader_location: 6, - format: wgpu::VertexFormat::Float, - offset: 4 * (2 + 2 + 4 + 4 + 1), - }, - ], - }, - ], + }], + }, + wgpu::VertexBufferDescriptor { + stride: mem::size_of::<layer::Quad>() as u64, + step_mode: wgpu::InputStepMode::Instance, + attributes: &[ + wgpu::VertexAttributeDescriptor { + shader_location: 1, + format: wgpu::VertexFormat::Float2, + offset: 0, + }, + wgpu::VertexAttributeDescriptor { + shader_location: 2, + format: wgpu::VertexFormat::Float2, + offset: 4 * 2, + }, + wgpu::VertexAttributeDescriptor { + shader_location: 3, + format: wgpu::VertexFormat::Float4, + offset: 4 * (2 + 2), + }, + wgpu::VertexAttributeDescriptor { + shader_location: 4, + format: wgpu::VertexFormat::Float4, + offset: 4 * (2 + 2 + 4), + }, + wgpu::VertexAttributeDescriptor { + shader_location: 5, + format: wgpu::VertexFormat::Float, + offset: 4 * (2 + 2 + 4 + 4), + }, + wgpu::VertexAttributeDescriptor { + shader_location: 6, + format: wgpu::VertexFormat::Float, + offset: 4 * (2 + 2 + 4 + 4 + 1), + }, + ], + }, + ], + }, sample_count: 1, sample_mask: !0, alpha_to_coverage_enabled: false, }); - let vertices = device - .create_buffer_mapped(QUAD_VERTS.len(), wgpu::BufferUsage::VERTEX) - .fill_from_slice(&QUAD_VERTS); + let vertices = + device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("iced_wgpu::quad vertex buffer"), + contents: bytemuck::cast_slice(&QUAD_VERTS), + usage: wgpu::BufferUsage::VERTEX, + }); - let indices = device - .create_buffer_mapped(QUAD_INDICES.len(), wgpu::BufferUsage::INDEX) - .fill_from_slice(&QUAD_INDICES); + let indices = + device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("iced_wgpu::quad index buffer"), + contents: bytemuck::cast_slice(&QUAD_INDICES), + usage: wgpu::BufferUsage::INDEX, + }); let instances = device.create_buffer(&wgpu::BufferDescriptor { - size: mem::size_of::<Quad>() as u64 * Quad::MAX as u64, + label: Some("iced_wgpu::quad instance buffer"), + size: mem::size_of::<layer::Quad>() as u64 * MAX_INSTANCES as u64, usage: wgpu::BufferUsage::VERTEX | wgpu::BufferUsage::COPY_DST, + mapped_at_creation: false, }); Pipeline { @@ -174,9 +186,10 @@ impl Pipeline { pub fn draw( &mut self, - device: &mut wgpu::Device, + device: &wgpu::Device, + staging_belt: &mut wgpu::util::StagingBelt, encoder: &mut wgpu::CommandEncoder, - instances: &[Quad], + instances: &[layer::Quad], transformation: Transformation, scale: f32, bounds: Rectangle<u32>, @@ -184,37 +197,38 @@ impl Pipeline { ) { let uniforms = Uniforms::new(transformation, scale); - let constants_buffer = device - .create_buffer_mapped(1, wgpu::BufferUsage::COPY_SRC) - .fill_from_slice(&[uniforms]); + { + let mut constants_buffer = staging_belt.write_buffer( + encoder, + &self.constants_buffer, + 0, + wgpu::BufferSize::new(mem::size_of::<Uniforms>() as u64) + .unwrap(), + device, + ); - encoder.copy_buffer_to_buffer( - &constants_buffer, - 0, - &self.constants_buffer, - 0, - std::mem::size_of::<Uniforms>() as u64, - ); + constants_buffer.copy_from_slice(bytemuck::bytes_of(&uniforms)); + } let mut i = 0; let total = instances.len(); while i < total { - let end = (i + Quad::MAX).min(total); + let end = (i + MAX_INSTANCES).min(total); let amount = end - i; - let instance_buffer = device - .create_buffer_mapped(amount, wgpu::BufferUsage::COPY_SRC) - .fill_from_slice(&instances[i..end]); + let instance_bytes = bytemuck::cast_slice(&instances[i..end]); - encoder.copy_buffer_to_buffer( - &instance_buffer, - 0, + let mut instance_buffer = staging_belt.write_buffer( + encoder, &self.instances, 0, - (mem::size_of::<Quad>() * amount) as u64, + wgpu::BufferSize::new(instance_bytes.len() as u64).unwrap(), + device, ); + instance_buffer.copy_from_slice(instance_bytes); + { let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { @@ -222,13 +236,9 @@ impl Pipeline { wgpu::RenderPassColorAttachmentDescriptor { attachment: target, resolve_target: None, - load_op: wgpu::LoadOp::Load, - store_op: wgpu::StoreOp::Store, - clear_color: wgpu::Color { - r: 0.0, - g: 0.0, - b: 0.0, - a: 0.0, + ops: wgpu::Operations { + load: wgpu::LoadOp::Load, + store: true, }, }, ], @@ -237,11 +247,9 @@ impl Pipeline { render_pass.set_pipeline(&self.pipeline); render_pass.set_bind_group(0, &self.constants, &[]); - render_pass.set_index_buffer(&self.indices, 0); - render_pass.set_vertex_buffers( - 0, - &[(&self.vertices, 0), (&self.instances, 0)], - ); + render_pass.set_index_buffer(self.indices.slice(..)); + render_pass.set_vertex_buffer(0, self.vertices.slice(..)); + render_pass.set_vertex_buffer(1, self.instances.slice(..)); render_pass.set_scissor_rect( bounds.x, bounds.y, @@ -257,13 +265,13 @@ impl Pipeline { ); } - i += Quad::MAX; + i += MAX_INSTANCES; } } } #[repr(C)] -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Zeroable, Pod)] pub struct Vertex { _position: [f32; 2], } @@ -285,23 +293,10 @@ const QUAD_VERTS: [Vertex; 4] = [ }, ]; -#[repr(C)] -#[derive(Debug, Clone, Copy)] -pub struct Quad { - pub position: [f32; 2], - pub scale: [f32; 2], - pub color: [f32; 4], - pub border_color: [f32; 4], - pub border_radius: f32, - pub border_width: f32, -} - -impl Quad { - const MAX: usize = 100_000; -} +const MAX_INSTANCES: usize = 100_000; #[repr(C)] -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, Zeroable, Pod)] struct Uniforms { transform: [f32; 16], scale: f32, |