From f7ce7244d017ec16545a3e52b6e7cf634bbffd4a Mon Sep 17 00:00:00 2001 From: shan Date: Wed, 5 Oct 2022 11:32:59 -0700 Subject: Adjusted gradient uniforms to be more tightly packed. --- wgpu/src/shader/triangle_gradient.wgsl | 29 ++++++++++++++----------- wgpu/src/triangle/gradient.rs | 39 +++++++++++++++++----------------- 2 files changed, 37 insertions(+), 31 deletions(-) diff --git a/wgpu/src/shader/triangle_gradient.wgsl b/wgpu/src/shader/triangle_gradient.wgsl index cb35b61c..df7158af 100644 --- a/wgpu/src/shader/triangle_gradient.wgsl +++ b/wgpu/src/shader/triangle_gradient.wgsl @@ -1,10 +1,10 @@ // uniforms struct GradientUniforms { transform: mat4x4, - @size(16) start: vec2, - @size(16) end: vec2, - @size(16) start_stop: i32, - @size(16) end_stop: i32, + //xy = start, wz = end + position: vec4, + //x = start, y = end, zw = padding + stop_range: vec4, } struct Stop { @@ -13,7 +13,7 @@ struct Stop { }; @group(0) @binding(0) -var gradient_uniforms: GradientUniforms; +var uniforms: GradientUniforms; @group(0) @binding(1) var color_stops: array; @@ -26,7 +26,7 @@ struct VertexOutput { @vertex fn vs_main(@location(0) input: vec2) -> VertexOutput { var output: VertexOutput; - output.position = gradient_uniforms.transform * vec4(input.xy, 0.0, 1.0); + output.position = uniforms.transform * vec4(input.xy, 0.0, 1.0); output.raw_position = input; return output; @@ -34,13 +34,18 @@ fn vs_main(@location(0) input: vec2) -> VertexOutput { @fragment fn fs_gradient(input: VertexOutput) -> @location(0) vec4 { - let v1 = gradient_uniforms.end - gradient_uniforms.start; - let v2 = input.raw_position.xy - gradient_uniforms.start; + let start = uniforms.position.xy; + let end = uniforms.position.zw; + let start_stop = uniforms.stop_range.x; + let end_stop = uniforms.stop_range.y; + + let v1 = end - start; + let v2 = input.raw_position.xy - start; let unit = normalize(v1); let offset = dot(unit, v2) / length(v1); - let min_stop = color_stops[gradient_uniforms.start_stop]; - let max_stop = color_stops[gradient_uniforms.end_stop]; + let min_stop = color_stops[start_stop]; + let max_stop = color_stops[end_stop]; var color: vec4; @@ -51,8 +56,8 @@ fn fs_gradient(input: VertexOutput) -> @location(0) vec4 { } else { var min = min_stop; var max = max_stop; - var min_index = gradient_uniforms.start_stop; - var max_index = gradient_uniforms.end_stop; + var min_index = start_stop; + var max_index = end_stop; loop { if (min_index >= max_index - 1) { diff --git a/wgpu/src/triangle/gradient.rs b/wgpu/src/triangle/gradient.rs index e8c6d7db..c647e6af 100644 --- a/wgpu/src/triangle/gradient.rs +++ b/wgpu/src/triangle/gradient.rs @@ -5,7 +5,7 @@ use crate::triangle::{ default_triangle_primitive_state, vertex_buffer_layout, }; use encase::ShaderType; -use glam::{Vec2, Vec4}; +use glam::{IVec4, Vec4}; use iced_graphics::gradient::Gradient; use iced_graphics::Transformation; @@ -21,17 +21,13 @@ pub(super) struct GradientPipeline { bind_group: wgpu::BindGroup, } -//TODO I can tightly pack this by rearranging/consolidating some fields #[derive(Debug, ShaderType)] pub(super) struct GradientUniforms { transform: glam::Mat4, - start: Vec2, - #[align(16)] - end: Vec2, - #[align(16)] - start_stop: i32, - #[align(16)] - end_stop: i32, + //xy = start, zw = end + direction: Vec4, + //x = start, y = end, zw = padding + stop_range: IVec4, } #[derive(Debug, ShaderType)] @@ -58,7 +54,7 @@ impl GradientPipeline { "iced_wgpu::triangle [GRADIENT] uniforms", ); - //TODO: With a WASM target storage buffers are not supported. Will need to use UBOs & static + //TODO: With a WASM target storage buffers are not supported. Will need to use UBOs & static // sized array (64 on OpenGL side right now) to make gradients work let storage_buffer = DynamicBuffer::storage( device, @@ -143,7 +139,9 @@ impl GradientPipeline { uniform_buffer, storage_buffer, color_stop_offset: 0, - color_stops_pending_write: GradientStorage { color_stops: vec![] }, + color_stops_pending_write: GradientStorage { + color_stops: vec![], + }, bind_group_layout, bind_group, } @@ -159,10 +157,13 @@ impl GradientPipeline { self.uniform_buffer.push(&GradientUniforms { transform: transform.into(), - start: Vec2::new(linear.start.x, linear.start.y), - end: Vec2::new(linear.end.x, linear.end.y), - start_stop: start_offset, - end_stop: end_offset, + 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; @@ -202,13 +203,13 @@ impl GradientPipeline { wgpu::BufferBinding { buffer: uniform_buffer, offset: 0, - size: Some(GradientUniforms::min_size()) - } - ) + size: Some(GradientUniforms::min_size()), + }, + ), }, wgpu::BindGroupEntry { binding: 1, - resource: storage_buffer.as_entire_binding() + resource: storage_buffer.as_entire_binding(), }, ], }) -- cgit