summaryrefslogtreecommitdiffstats
path: root/wgpu/src/triangle
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2022-11-14 00:02:42 +0100
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2022-11-16 09:24:16 +0100
commit33c3c0c0aa774bb7462e3c42aa04c591a66376a7 (patch)
tree08ea046e6ac8a9ad43a7ef1f56256a056a4a4d6c /wgpu/src/triangle
parent5b0dfcd0b0a9f25a3004dbc2cad3dea8220a76a1 (diff)
downloadiced-33c3c0c0aa774bb7462e3c42aa04c591a66376a7.tar.gz
iced-33c3c0c0aa774bb7462e3c42aa04c591a66376a7.tar.bz2
iced-33c3c0c0aa774bb7462e3c42aa04c591a66376a7.zip
Group all solid triangles independently of color
Diffstat (limited to 'wgpu/src/triangle')
-rw-r--r--wgpu/src/triangle/gradient.rs268
-rw-r--r--wgpu/src/triangle/solid.rs170
2 files changed, 0 insertions, 438 deletions
diff --git a/wgpu/src/triangle/gradient.rs b/wgpu/src/triangle/gradient.rs
deleted file mode 100644
index b06cbac6..00000000
--- a/wgpu/src/triangle/gradient.rs
+++ /dev/null
@@ -1,268 +0,0 @@
-use crate::buffer::dynamic;
-use crate::settings;
-use crate::triangle;
-use encase::ShaderType;
-use glam::{IVec4, Vec4};
-use iced_graphics::gradient::Gradient;
-use iced_graphics::Transformation;
-
-pub struct Pipeline {
- pipeline: wgpu::RenderPipeline,
- pub(super) uniform_buffer: dynamic::Buffer<Uniforms>,
- pub(super) storage_buffer: dynamic::Buffer<Storage>,
- color_stop_offset: i32,
- //Need to store these and then write them all at once
- //or else they will be padded to 256 and cause gaps in the storage buffer
- color_stops_pending_write: Storage,
- bind_group_layout: wgpu::BindGroupLayout,
- bind_group: wgpu::BindGroup,
-}
-
-#[derive(Debug, ShaderType)]
-pub(super) struct Uniforms {
- transform: glam::Mat4,
- //xy = start, zw = end
- direction: Vec4,
- //x = start stop, y = end stop, zw = padding
- stop_range: IVec4,
-}
-
-#[derive(Debug, ShaderType)]
-pub(super) struct ColorStop {
- color: Vec4,
- offset: f32,
-}
-
-#[derive(ShaderType)]
-pub(super) struct Storage {
- #[size(runtime)]
- pub color_stops: Vec<ColorStop>,
-}
-
-impl Pipeline {
- /// Creates a new [GradientPipeline] using `gradient.wgsl` shader.
- pub(super) fn new(
- device: &wgpu::Device,
- format: wgpu::TextureFormat,
- antialiasing: Option<settings::Antialiasing>,
- ) -> Self {
- let uniform_buffer = dynamic::Buffer::uniform(
- device,
- "iced_wgpu::triangle::gradient uniforms",
- );
-
- //Note: with a WASM target storage buffers are not supported. Will need to use UBOs & static
- // sized array (eg like the 32-sized array on OpenGL side right now) to make gradients work
- let storage_buffer = dynamic::Buffer::storage(
- device,
- "iced_wgpu::triangle::gradient storage",
- );
-
- let bind_group_layout =
- device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
- label: Some("iced_wgpu::triangle::gradient bind group layout"),
- entries: &[
- wgpu::BindGroupLayoutEntry {
- binding: 0,
- visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
- ty: wgpu::BindingType::Buffer {
- ty: wgpu::BufferBindingType::Uniform,
- has_dynamic_offset: true,
- min_binding_size: Some(Uniforms::min_size()),
- },
- count: None,
- },
- wgpu::BindGroupLayoutEntry {
- binding: 1,
- visibility: wgpu::ShaderStages::FRAGMENT,
- ty: wgpu::BindingType::Buffer {
- ty: wgpu::BufferBindingType::Storage {
- read_only: true,
- },
- has_dynamic_offset: false,
- min_binding_size: Some(Storage::min_size()),
- },
- count: None,
- },
- ],
- });
-
- let bind_group = Pipeline::bind_group(
- device,
- uniform_buffer.raw(),
- storage_buffer.raw(),
- &bind_group_layout,
- );
-
- let layout =
- device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
- label: Some("iced_wgpu::triangle::gradient pipeline layout"),
- bind_group_layouts: &[&bind_group_layout],
- push_constant_ranges: &[],
- });
-
- let shader =
- device.create_shader_module(wgpu::ShaderModuleDescriptor {
- label: Some(
- "iced_wgpu::triangle::gradient create shader module",
- ),
- source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed(
- include_str!("../shader/gradient.wgsl"),
- )),
- });
-
- let pipeline =
- device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
- label: Some("iced_wgpu::triangle::gradient pipeline"),
- layout: Some(&layout),
- vertex: wgpu::VertexState {
- module: &shader,
- entry_point: "vs_main",
- buffers: &[triangle::vertex_buffer_layout()],
- },
- fragment: Some(wgpu::FragmentState {
- module: &shader,
- entry_point: "fs_main",
- targets: &[triangle::fragment_target(format)],
- }),
- primitive: triangle::primitive_state(),
- depth_stencil: None,
- multisample: triangle::multisample_state(antialiasing),
- multiview: None,
- });
-
- Self {
- pipeline,
- uniform_buffer,
- storage_buffer,
- color_stop_offset: 0,
- color_stops_pending_write: Storage {
- color_stops: vec![],
- },
- bind_group_layout,
- bind_group,
- }
- }
-
- /// Pushes a new gradient uniform to the CPU buffer.
- pub fn push(&mut self, transform: Transformation, gradient: &Gradient) {
- match gradient {
- Gradient::Linear(linear) => {
- let start_offset = self.color_stop_offset;
- let end_offset =
- (linear.color_stops.len() as i32) + start_offset - 1;
-
- self.uniform_buffer.push(&Uniforms {
- transform: transform.into(),
- direction: Vec4::new(
- linear.start.x,
- linear.start.y,
- linear.end.x,
- linear.end.y,
- ),
- stop_range: IVec4::new(start_offset, end_offset, 0, 0),
- });
-
- self.color_stop_offset = end_offset + 1;
-
- let stops: Vec<ColorStop> = linear
- .color_stops
- .iter()
- .map(|stop| {
- let [r, g, b, a] = stop.color.into_linear();
-
- ColorStop {
- offset: stop.offset,
- color: Vec4::new(r, g, b, a),
- }
- })
- .collect();
-
- self.color_stops_pending_write.color_stops.extend(stops);
- }
- }
- }
-
- fn bind_group(
- device: &wgpu::Device,
- uniform_buffer: &wgpu::Buffer,
- storage_buffer: &wgpu::Buffer,
- layout: &wgpu::BindGroupLayout,
- ) -> wgpu::BindGroup {
- device.create_bind_group(&wgpu::BindGroupDescriptor {
- label: Some("iced_wgpu::triangle::gradient bind group"),
- layout,
- entries: &[
- wgpu::BindGroupEntry {
- binding: 0,
- resource: wgpu::BindingResource::Buffer(
- wgpu::BufferBinding {
- buffer: uniform_buffer,
- offset: 0,
- size: Some(Uniforms::min_size()),
- },
- ),
- },
- wgpu::BindGroupEntry {
- binding: 1,
- resource: storage_buffer.as_entire_binding(),
- },
- ],
- })
- }
-
- /// Writes the contents of the gradient CPU buffer to the GPU buffer, resizing the GPU buffer
- /// beforehand if necessary.
- pub fn write(
- &mut self,
- device: &wgpu::Device,
- staging_belt: &mut wgpu::util::StagingBelt,
- encoder: &mut wgpu::CommandEncoder,
- ) {
- //first write the pending color stops to the CPU buffer
- self.storage_buffer.push(&self.color_stops_pending_write);
-
- //resize buffers if needed
- let uniforms_resized = self.uniform_buffer.resize(device);
- let storage_resized = self.storage_buffer.resize(device);
-
- if uniforms_resized || storage_resized {
- //recreate bind groups if any buffers were resized
- self.bind_group = Pipeline::bind_group(
- device,
- self.uniform_buffer.raw(),
- self.storage_buffer.raw(),
- &self.bind_group_layout,
- );
- }
-
- //write to GPU
- self.uniform_buffer.write(device, staging_belt, encoder);
- self.storage_buffer.write(device, staging_belt, encoder);
-
- //cleanup
- self.color_stop_offset = 0;
- self.color_stops_pending_write.color_stops.clear();
- }
-
- pub fn set_render_pass_pipeline<'a>(
- &'a self,
- render_pass: &mut wgpu::RenderPass<'a>,
- ) {
- render_pass.set_pipeline(&self.pipeline);
- }
-
- /// Configures the current render pass to draw the gradient at its offset stored in the
- /// [DynamicBuffer] at [index].
- pub fn configure_render_pass<'a>(
- &'a self,
- render_pass: &mut wgpu::RenderPass<'a>,
- count: usize,
- ) {
- render_pass.set_bind_group(
- 0,
- &self.bind_group,
- &[self.uniform_buffer.offset_at_index(count)],
- )
- }
-}
diff --git a/wgpu/src/triangle/solid.rs b/wgpu/src/triangle/solid.rs
deleted file mode 100644
index 2e1052f2..00000000
--- a/wgpu/src/triangle/solid.rs
+++ /dev/null
@@ -1,170 +0,0 @@
-use crate::buffer::dynamic;
-use crate::triangle;
-use crate::{settings, Color};
-use encase::ShaderType;
-use glam::Vec4;
-use iced_graphics::Transformation;
-
-pub struct Pipeline {
- pipeline: wgpu::RenderPipeline,
- pub(super) buffer: dynamic::Buffer<Uniforms>,
- bind_group_layout: wgpu::BindGroupLayout,
- bind_group: wgpu::BindGroup,
-}
-
-#[derive(Debug, Clone, Copy, ShaderType)]
-pub(super) struct Uniforms {
- transform: glam::Mat4,
- color: Vec4,
-}
-
-impl Uniforms {
- pub fn new(transform: Transformation, color: Color) -> Self {
- let [r, g, b, a] = color.into_linear();
-
- Self {
- transform: transform.into(),
- color: Vec4::new(r, g, b, a),
- }
- }
-}
-
-impl Pipeline {
- /// Creates a new [SolidPipeline] using `solid.wgsl` shader.
- pub fn new(
- device: &wgpu::Device,
- format: wgpu::TextureFormat,
- antialiasing: Option<settings::Antialiasing>,
- ) -> Self {
- let buffer = dynamic::Buffer::uniform(
- device,
- "iced_wgpu::triangle::solid uniforms",
- );
-
- let bind_group_layout =
- device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
- label: Some("iced_wgpu::triangle::solid bind group layout"),
- entries: &[wgpu::BindGroupLayoutEntry {
- binding: 0,
- visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
- ty: wgpu::BindingType::Buffer {
- ty: wgpu::BufferBindingType::Uniform,
- has_dynamic_offset: true,
- min_binding_size: Some(Uniforms::min_size()),
- },
- count: None,
- }],
- });
-
- let bind_group =
- Pipeline::bind_group(device, buffer.raw(), &bind_group_layout);
-
- let layout =
- device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
- label: Some("iced_wgpu::triangle::solid pipeline layout"),
- bind_group_layouts: &[&bind_group_layout],
- push_constant_ranges: &[],
- });
-
- let shader =
- device.create_shader_module(wgpu::ShaderModuleDescriptor {
- label: Some("iced_wgpu::triangle::solid create shader module"),
- source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed(
- include_str!("../shader/solid.wgsl"),
- )),
- });
-
- let pipeline =
- device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
- label: Some("iced_wgpu::triangle::solid pipeline"),
- layout: Some(&layout),
- vertex: wgpu::VertexState {
- module: &shader,
- entry_point: "vs_main",
- buffers: &[triangle::vertex_buffer_layout()],
- },
- fragment: Some(wgpu::FragmentState {
- module: &shader,
- entry_point: "fs_main",
- targets: &[triangle::fragment_target(format)],
- }),
- primitive: triangle::primitive_state(),
- depth_stencil: None,
- multisample: triangle::multisample_state(antialiasing),
- multiview: None,
- });
-
- Self {
- pipeline,
- buffer,
- bind_group_layout,
- bind_group,
- }
- }
-
- fn bind_group(
- device: &wgpu::Device,
- buffer: &wgpu::Buffer,
- layout: &wgpu::BindGroupLayout,
- ) -> wgpu::BindGroup {
- device.create_bind_group(&wgpu::BindGroupDescriptor {
- label: Some("iced_wgpu::triangle::solid bind group"),
- layout,
- entries: &[wgpu::BindGroupEntry {
- binding: 0,
- resource: wgpu::BindingResource::Buffer(wgpu::BufferBinding {
- buffer,
- offset: 0,
- size: Some(Uniforms::min_size()),
- }),
- }],
- })
- }
-
- /// Pushes a new solid uniform to the CPU buffer.
- pub fn push(&mut self, transform: Transformation, color: &Color) {
- self.buffer.push(&Uniforms::new(transform, *color));
- }
-
- /// Writes the contents of the solid CPU buffer to the GPU buffer, resizing the GPU buffer
- /// beforehand if necessary.
- pub fn write(
- &mut self,
- device: &wgpu::Device,
- staging_belt: &mut wgpu::util::StagingBelt,
- encoder: &mut wgpu::CommandEncoder,
- ) {
- let uniforms_resized = self.buffer.resize(device);
-
- if uniforms_resized {
- self.bind_group = Pipeline::bind_group(
- device,
- self.buffer.raw(),
- &self.bind_group_layout,
- )
- }
-
- self.buffer.write(device, staging_belt, encoder);
- }
-
- pub fn set_render_pass_pipeline<'a>(
- &'a self,
- render_pass: &mut wgpu::RenderPass<'a>,
- ) {
- render_pass.set_pipeline(&self.pipeline);
- }
-
- /// Configures the current render pass to draw the solid at its offset stored in the
- /// [DynamicBuffer] at [index].
- pub fn configure_render_pass<'a>(
- &'a self,
- render_pass: &mut wgpu::RenderPass<'a>,
- count: usize,
- ) {
- render_pass.set_bind_group(
- 0,
- &self.bind_group,
- &[self.buffer.offset_at_index(count)],
- )
- }
-}