wgpu: Merge Transforms and ColorAdjustments

This commit is contained in:
Nathan Adams 2024-01-23 22:06:44 +01:00
parent 1231d2fead
commit de975a9727
13 changed files with 42 additions and 213 deletions

View File

@ -8,10 +8,9 @@ struct VertexOutput {
}; };
@group(1) @binding(0) var<uniform> transforms: common::Transforms; @group(1) @binding(0) var<uniform> transforms: common::Transforms;
@group(2) @binding(0) var<uniform> colorTransforms: common::ColorTransforms; @group(2) @binding(0) var<uniform> textureTransforms: common::TextureTransforms;
@group(3) @binding(0) var<uniform> textureTransforms: common::TextureTransforms; @group(2) @binding(1) var texture: texture_2d<f32>;
@group(3) @binding(1) var texture: texture_2d<f32>; @group(2) @binding(2) var texture_sampler: sampler;
@group(3) @binding(2) var texture_sampler: sampler;
@vertex @vertex
fn main_vertex(in: common::VertexInput) -> VertexOutput { fn main_vertex(in: common::VertexInput) -> VertexOutput {
@ -28,7 +27,7 @@ fn main_fragment(in: VertexOutput) -> @location(0) vec4<f32> {
// Unmultiply alpha, apply color transform, remultiply alpha. // Unmultiply alpha, apply color transform, remultiply alpha.
if( color.a > 0.0 ) { if( color.a > 0.0 ) {
color = vec4<f32>(color.rgb / color.a, color.a); color = vec4<f32>(color.rgb / color.a, color.a);
color = color * colorTransforms.mult_color + colorTransforms.add_color; color = color * transforms.mult_color + transforms.add_color;
#if early_saturate == true #if early_saturate == true
color = saturate(color); color = saturate(color);
#endif #endif

View File

@ -13,12 +13,11 @@ struct VertexOutput {
}; };
@group(1) @binding(0) var<uniform> transforms: common::Transforms; @group(1) @binding(0) var<uniform> transforms: common::Transforms;
@group(2) @binding(0) var<uniform> colorTransforms: common::ColorTransforms;
@vertex @vertex
fn main_vertex(in: VertexInput) -> VertexOutput { fn main_vertex(in: VertexInput) -> VertexOutput {
let pos = common::globals.view_matrix * transforms.world_matrix * vec4<f32>(in.position.x, in.position.y, 0.0, 1.0); let pos = common::globals.view_matrix * transforms.world_matrix * vec4<f32>(in.position.x, in.position.y, 0.0, 1.0);
let color = saturate(in.color * colorTransforms.mult_color + colorTransforms.add_color); let color = saturate(in.color * transforms.mult_color + transforms.add_color);
return VertexOutput(pos, vec4<f32>(color.rgb * color.a, color.a)); return VertexOutput(pos, vec4<f32>(color.rgb * color.a, color.a));
} }

View File

@ -13,10 +13,7 @@ struct Globals {
struct Transforms { struct Transforms {
/// The world matrix that transforms this object into stage space. /// The world matrix that transforms this object into stage space.
world_matrix: mat4x4<f32>, world_matrix: mat4x4<f32>,
};
/// Transform uniforms that are changed per object.
struct ColorTransforms {
/// The multiplicative color transform of this object. /// The multiplicative color transform of this object.
mult_color: vec4<f32>, mult_color: vec4<f32>,
@ -31,11 +28,6 @@ struct TextureTransforms {
texture_matrix: mat4x4<f32>, texture_matrix: mat4x4<f32>,
}; };
struct PushConstants {
transforms: Transforms,
colorTransforms: ColorTransforms,
}
/// The vertex format shared among most shaders. /// The vertex format shared among most shaders.
struct VertexInput { struct VertexInput {
/// The position of the vertex in object space. /// The position of the vertex in object space.

View File

@ -7,8 +7,7 @@ struct VertexOutput {
}; };
@group(1) @binding(0) var<uniform> transforms: common::Transforms; @group(1) @binding(0) var<uniform> transforms: common::Transforms;
@group(2) @binding(0) var<uniform> colorTransforms: common::ColorTransforms; @group(2) @binding(0) var<uniform> textureTransforms: common::TextureTransforms;
@group(3) @binding(0) var<uniform> textureTransforms: common::TextureTransforms;
struct Gradient { struct Gradient {
focal_point: f32, focal_point: f32,
@ -17,9 +16,9 @@ struct Gradient {
repeat: i32, repeat: i32,
}; };
@group(3) @binding(1) var<uniform> gradient: Gradient; @group(2) @binding(1) var<uniform> gradient: Gradient;
@group(3) @binding(2) var texture: texture_2d<f32>; @group(2) @binding(2) var texture: texture_2d<f32>;
@group(3) @binding(3) var texture_sampler: sampler; @group(2) @binding(3) var texture_sampler: sampler;
struct GradientVertexInput { struct GradientVertexInput {
/// The position of the vertex in object space. /// The position of the vertex in object space.
@ -79,7 +78,7 @@ fn main_fragment(in: VertexOutput) -> @location(0) vec4<f32> {
if( gradient.interpolation != 0 ) { if( gradient.interpolation != 0 ) {
color = common::linear_to_srgb(color); color = common::linear_to_srgb(color);
} }
let out = saturate(color * colorTransforms.mult_color + colorTransforms.add_color); let out = saturate(color * transforms.mult_color + transforms.add_color);
let alpha = saturate(out.a); let alpha = saturate(out.a);
return vec4<f32>(out.rgb * alpha, alpha); return vec4<f32>(out.rgb * alpha, alpha);
} }

View File

@ -4,7 +4,7 @@ use crate::pipelines::VERTEX_BUFFERS_DESCRIPTION_POS;
use crate::shaders::Shaders; use crate::shaders::Shaders;
use crate::{ use crate::{
create_buffer_with_data, BitmapSamplers, Pipelines, PosColorVertex, PosVertex, create_buffer_with_data, BitmapSamplers, Pipelines, PosColorVertex, PosVertex,
TextureTransforms, DEFAULT_COLOR_ADJUSTMENTS, TextureTransforms,
}; };
use fnv::FnvHashMap; use fnv::FnvHashMap;
use std::fmt::Debug; use std::fmt::Debug;
@ -23,7 +23,6 @@ pub struct Descriptors {
copy_srgb_pipeline: Mutex<FnvHashMap<(u32, wgpu::TextureFormat), Arc<wgpu::RenderPipeline>>>, copy_srgb_pipeline: Mutex<FnvHashMap<(u32, wgpu::TextureFormat), Arc<wgpu::RenderPipeline>>>,
pub shaders: Shaders, pub shaders: Shaders,
pipelines: Mutex<FnvHashMap<(u32, wgpu::TextureFormat), Arc<Pipelines>>>, pipelines: Mutex<FnvHashMap<(u32, wgpu::TextureFormat), Arc<Pipelines>>>,
pub default_color_bind_group: wgpu::BindGroup,
pub filters: Filters, pub filters: Filters,
} }
@ -45,20 +44,6 @@ impl Descriptors {
let bitmap_samplers = BitmapSamplers::new(&device); let bitmap_samplers = BitmapSamplers::new(&device);
let shaders = Shaders::new(&device); let shaders = Shaders::new(&device);
let quad = Quad::new(&device); let quad = Quad::new(&device);
let default_color_transform = create_buffer_with_data(
&device,
bytemuck::cast_slice(&[DEFAULT_COLOR_ADJUSTMENTS]),
wgpu::BufferUsages::UNIFORM,
create_debug_label!("Default colors"),
);
let default_color_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
label: create_debug_label!("Default colors").as_deref(),
layout: &bind_layouts.color_transforms,
entries: &[wgpu::BindGroupEntry {
binding: 0,
resource: default_color_transform.as_entire_binding(),
}],
});
let filters = Filters::new(&device); let filters = Filters::new(&device);
Self { Self {
@ -74,7 +59,6 @@ impl Descriptors {
copy_srgb_pipeline: Default::default(), copy_srgb_pipeline: Default::default(),
shaders, shaders,
pipelines: Default::default(), pipelines: Default::default(),
default_color_bind_group,
filters, filters,
} }
} }

View File

@ -1,5 +1,5 @@
use crate::descriptors::Descriptors; use crate::descriptors::Descriptors;
use crate::{ColorAdjustments, Transforms}; use crate::Transforms;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::mem; use std::mem;
@ -7,17 +7,12 @@ const ESTIMATED_OBJECTS_PER_CHUNK: u64 = 200;
pub struct DynamicTransforms { pub struct DynamicTransforms {
pub transform: Inner<Transforms>, pub transform: Inner<Transforms>,
pub color: Inner<ColorAdjustments>,
} }
impl DynamicTransforms { impl DynamicTransforms {
pub fn new(descriptors: &Descriptors) -> Self { pub fn new(descriptors: &Descriptors) -> Self {
Self { Self {
transform: Inner::new(&descriptors.device, &descriptors.bind_layouts.transforms), transform: Inner::new(&descriptors.device, &descriptors.bind_layouts.transforms),
color: Inner::new(
&descriptors.device,
&descriptors.bind_layouts.color_transforms,
),
} }
} }
} }

View File

@ -1,11 +1,10 @@
use crate::globals::GlobalsUniform; use crate::globals::GlobalsUniform;
use crate::{ColorAdjustments, GradientUniforms, TextureTransforms, Transforms}; use crate::{GradientUniforms, TextureTransforms, Transforms};
#[derive(Debug)] #[derive(Debug)]
pub struct BindLayouts { pub struct BindLayouts {
pub globals: wgpu::BindGroupLayout, pub globals: wgpu::BindGroupLayout,
pub transforms: wgpu::BindGroupLayout, pub transforms: wgpu::BindGroupLayout,
pub color_transforms: wgpu::BindGroupLayout,
pub bitmap: wgpu::BindGroupLayout, pub bitmap: wgpu::BindGroupLayout,
pub gradient: wgpu::BindGroupLayout, pub gradient: wgpu::BindGroupLayout,
pub blend: wgpu::BindGroupLayout, pub blend: wgpu::BindGroupLayout,
@ -30,22 +29,6 @@ impl BindLayouts {
label: uniform_buffer_layout_label.as_deref(), label: uniform_buffer_layout_label.as_deref(),
}); });
let color_transforms = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
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: wgpu::BufferSize::new(
std::mem::size_of::<ColorAdjustments>() as u64,
),
},
count: None,
}],
label: create_debug_label!("Color transforms bind group layout").as_deref(),
});
let globals_layout_label = create_debug_label!("Globals bind group layout"); let globals_layout_label = create_debug_label!("Globals bind group layout");
let globals = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { let globals = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
label: globals_layout_label.as_deref(), label: globals_layout_label.as_deref(),
@ -181,7 +164,6 @@ impl BindLayouts {
Self { Self {
globals, globals,
transforms, transforms,
color_transforms,
bitmap, bitmap,
gradient, gradient,
blend, blend,

View File

@ -73,6 +73,8 @@ pub enum MaskState {
#[derive(Copy, Clone, Debug, Pod, Zeroable)] #[derive(Copy, Clone, Debug, Pod, Zeroable)]
pub struct Transforms { pub struct Transforms {
world_matrix: [[f32; 4]; 4], world_matrix: [[f32; 4]; 4],
mult_color: [f32; 4],
add_color: [f32; 4],
} }
#[repr(C)] #[repr(C)]
@ -81,27 +83,6 @@ struct TextureTransforms {
u_matrix: [[f32; 4]; 4], u_matrix: [[f32; 4]; 4],
} }
#[repr(C)]
#[derive(Copy, Clone, Debug, Pod, Zeroable, PartialEq)]
pub struct ColorAdjustments {
mult_color: [f32; 4],
add_color: [f32; 4],
}
pub const DEFAULT_COLOR_ADJUSTMENTS: ColorAdjustments = ColorAdjustments {
mult_color: [1.0, 1.0, 1.0, 1.0],
add_color: [0.0, 0.0, 0.0, 0.0],
};
impl From<&swf::ColorTransform> for ColorAdjustments {
fn from(transform: &swf::ColorTransform) -> Self {
Self {
mult_color: transform.mult_rgba_normalized(),
add_color: transform.add_rgba_normalized(),
}
}
}
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug, Pod, Zeroable)] #[derive(Copy, Clone, Debug, Pod, Zeroable)]
struct PosVertex { struct PosVertex {

View File

@ -86,11 +86,7 @@ impl Pipelines {
msaa_sample_count: u32, msaa_sample_count: u32,
bind_layouts: &BindLayouts, bind_layouts: &BindLayouts,
) -> Self { ) -> Self {
let colort_bindings = vec![ let colort_bindings = vec![&bind_layouts.globals, &bind_layouts.transforms];
&bind_layouts.globals,
&bind_layouts.transforms,
&bind_layouts.color_transforms,
];
let color_pipelines = create_shape_pipeline( let color_pipelines = create_shape_pipeline(
"Color", "Color",
@ -107,7 +103,6 @@ impl Pipelines {
let gradient_bindings = vec![ let gradient_bindings = vec![
&bind_layouts.globals, &bind_layouts.globals,
&bind_layouts.transforms, &bind_layouts.transforms,
&bind_layouts.color_transforms,
&bind_layouts.gradient, &bind_layouts.gradient,
]; ];
@ -146,7 +141,6 @@ impl Pipelines {
let bitmap_blend_bindings = vec![ let bitmap_blend_bindings = vec![
&bind_layouts.globals, &bind_layouts.globals,
&bind_layouts.transforms, &bind_layouts.transforms,
&bind_layouts.color_transforms,
&bind_layouts.bitmap, &bind_layouts.bitmap,
]; ];

View File

@ -154,19 +154,13 @@ impl Surface {
for chunk in chunks { for chunk in chunks {
match chunk { match chunk {
Chunk::Draw(chunk, needs_stencil, transform_buffers, color_buffers) => { Chunk::Draw(chunk, needs_stencil, transform_buffers) => {
transform_buffers.copy_to( transform_buffers.copy_to(
staging_belt, staging_belt,
&descriptors.device, &descriptors.device,
draw_encoder, draw_encoder,
&dynamic_transforms.transform.buffer, &dynamic_transforms.transform.buffer,
); );
color_buffers.copy_to(
staging_belt,
&descriptors.device,
draw_encoder,
&dynamic_transforms.color.buffer,
);
let mut render_pass = let mut render_pass =
draw_encoder.begin_render_pass(&wgpu::RenderPassDescriptor { draw_encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: create_debug_label!( label: create_debug_label!(

View File

@ -7,7 +7,7 @@ use crate::dynamic_transforms::DynamicTransforms;
use crate::mesh::{as_mesh, DrawType, Mesh}; use crate::mesh::{as_mesh, DrawType, Mesh};
use crate::surface::target::CommandTarget; use crate::surface::target::CommandTarget;
use crate::surface::Surface; use crate::surface::Surface;
use crate::{as_texture, ColorAdjustments, Descriptors, MaskState, Pipelines, Transforms}; use crate::{as_texture, Descriptors, MaskState, Pipelines, Transforms};
use ruffle_render::backend::ShapeHandle; use ruffle_render::backend::ShapeHandle;
use ruffle_render::bitmap::BitmapHandle; use ruffle_render::bitmap::BitmapHandle;
use ruffle_render::commands::{Command, RenderBlendMode}; use ruffle_render::commands::{Command, RenderBlendMode};
@ -71,14 +71,12 @@ impl<'pass, 'frame: 'pass, 'global: 'frame> CommandRenderer<'pass, 'frame, 'glob
DrawCommand::RenderBitmap { DrawCommand::RenderBitmap {
bitmap, bitmap,
transform_buffer, transform_buffer,
color_buffer,
smoothing, smoothing,
blend_mode, blend_mode,
render_stage3d, render_stage3d,
} => self.render_bitmap( } => self.render_bitmap(
bitmap, bitmap,
*transform_buffer, *transform_buffer,
*color_buffer,
*smoothing, *smoothing,
*blend_mode, *blend_mode,
*render_stage3d, *render_stage3d,
@ -87,18 +85,13 @@ impl<'pass, 'frame: 'pass, 'global: 'frame> CommandRenderer<'pass, 'frame, 'glob
_texture, _texture,
binds, binds,
transform_buffer, transform_buffer,
color_buffer,
blend_mode, blend_mode,
} => self.render_texture(*transform_buffer, *color_buffer, binds, *blend_mode), } => self.render_texture(*transform_buffer, binds, *blend_mode),
DrawCommand::RenderShape { DrawCommand::RenderShape {
shape, shape,
transform_buffer, transform_buffer,
color_buffer, } => self.render_shape(shape, *transform_buffer),
} => self.render_shape(shape, *transform_buffer, *color_buffer), DrawCommand::DrawRect { transform_buffer } => self.draw_rect(*transform_buffer),
DrawCommand::DrawRect {
transform_buffer,
color_buffer,
} => self.draw_rect(*transform_buffer, *color_buffer),
DrawCommand::PushMask => self.push_mask(), DrawCommand::PushMask => self.push_mask(),
DrawCommand::ActivateMask => self.activate_mask(), DrawCommand::ActivateMask => self.activate_mask(),
DrawCommand::DeactivateMask => self.deactivate_mask(), DrawCommand::DeactivateMask => self.deactivate_mask(),
@ -125,7 +118,7 @@ impl<'pass, 'frame: 'pass, 'global: 'frame> CommandRenderer<'pass, 'frame, 'glob
.set_pipeline(self.pipelines.gradients.stencilless_pipeline()); .set_pipeline(self.pipelines.gradients.stencilless_pipeline());
} }
self.render_pass.set_bind_group(3, bind_group, &[]); self.render_pass.set_bind_group(2, bind_group, &[]);
} }
pub fn prep_bitmap( pub fn prep_bitmap(
@ -152,7 +145,7 @@ impl<'pass, 'frame: 'pass, 'global: 'frame> CommandRenderer<'pass, 'frame, 'glob
} }
} }
self.render_pass.set_bind_group(3, bind_group, &[]); self.render_pass.set_bind_group(2, bind_group, &[]);
} }
pub fn draw( pub fn draw(
@ -172,7 +165,6 @@ impl<'pass, 'frame: 'pass, 'global: 'frame> CommandRenderer<'pass, 'frame, 'glob
&mut self, &mut self,
bitmap: &'frame BitmapHandle, bitmap: &'frame BitmapHandle,
transform_buffer: wgpu::DynamicOffset, transform_buffer: wgpu::DynamicOffset,
color_buffer: wgpu::DynamicOffset,
smoothing: bool, smoothing: bool,
blend_mode: TrivialBlend, blend_mode: TrivialBlend,
render_stage3d: bool, render_stage3d: bool,
@ -198,11 +190,6 @@ impl<'pass, 'frame: 'pass, 'global: 'frame> CommandRenderer<'pass, 'frame, 'glob
&self.dynamic_transforms.transform.bind_group, &self.dynamic_transforms.transform.bind_group,
&[transform_buffer], &[transform_buffer],
); );
self.render_pass.set_bind_group(
2,
&self.dynamic_transforms.color.bind_group,
&[color_buffer],
);
self.draw( self.draw(
self.descriptors.quad.vertices_pos.slice(..), self.descriptors.quad.vertices_pos.slice(..),
@ -217,7 +204,6 @@ impl<'pass, 'frame: 'pass, 'global: 'frame> CommandRenderer<'pass, 'frame, 'glob
pub fn render_texture( pub fn render_texture(
&mut self, &mut self,
transform_buffer: wgpu::DynamicOffset, transform_buffer: wgpu::DynamicOffset,
color_buffer: wgpu::DynamicOffset,
bind_group: &'frame wgpu::BindGroup, bind_group: &'frame wgpu::BindGroup,
blend_mode: TrivialBlend, blend_mode: TrivialBlend,
) { ) {
@ -231,11 +217,6 @@ impl<'pass, 'frame: 'pass, 'global: 'frame> CommandRenderer<'pass, 'frame, 'glob
&self.dynamic_transforms.transform.bind_group, &self.dynamic_transforms.transform.bind_group,
&[transform_buffer], &[transform_buffer],
); );
self.render_pass.set_bind_group(
2,
&self.dynamic_transforms.color.bind_group,
&[color_buffer],
);
self.draw( self.draw(
self.descriptors.quad.vertices_pos.slice(..), self.descriptors.quad.vertices_pos.slice(..),
@ -251,7 +232,6 @@ impl<'pass, 'frame: 'pass, 'global: 'frame> CommandRenderer<'pass, 'frame, 'glob
&mut self, &mut self,
shape: &'frame ShapeHandle, shape: &'frame ShapeHandle,
transform_buffer: wgpu::DynamicOffset, transform_buffer: wgpu::DynamicOffset,
color_buffer: wgpu::DynamicOffset,
) { ) {
if cfg!(feature = "render_debug_labels") { if cfg!(feature = "render_debug_labels") {
self.render_pass.push_debug_group("render_shape"); self.render_pass.push_debug_group("render_shape");
@ -287,11 +267,6 @@ impl<'pass, 'frame: 'pass, 'global: 'frame> CommandRenderer<'pass, 'frame, 'glob
&self.dynamic_transforms.transform.bind_group, &self.dynamic_transforms.transform.bind_group,
&[transform_buffer], &[transform_buffer],
); );
self.render_pass.set_bind_group(
2,
&self.dynamic_transforms.color.bind_group,
&[color_buffer],
);
self.draw( self.draw(
mesh.vertex_buffer.slice(draw.vertices.clone()), mesh.vertex_buffer.slice(draw.vertices.clone()),
@ -304,11 +279,7 @@ impl<'pass, 'frame: 'pass, 'global: 'frame> CommandRenderer<'pass, 'frame, 'glob
} }
} }
pub fn draw_rect( pub fn draw_rect(&mut self, transform_buffer: wgpu::DynamicOffset) {
&mut self,
transform_buffer: wgpu::DynamicOffset,
color_buffer: wgpu::DynamicOffset,
) {
if cfg!(feature = "render_debug_labels") { if cfg!(feature = "render_debug_labels") {
self.render_pass.push_debug_group("draw_rect"); self.render_pass.push_debug_group("draw_rect");
} }
@ -319,11 +290,6 @@ impl<'pass, 'frame: 'pass, 'global: 'frame> CommandRenderer<'pass, 'frame, 'glob
&self.dynamic_transforms.transform.bind_group, &self.dynamic_transforms.transform.bind_group,
&[transform_buffer], &[transform_buffer],
); );
self.render_pass.set_bind_group(
2,
&self.dynamic_transforms.color.bind_group,
&[color_buffer],
);
self.draw( self.draw(
self.descriptors.quad.vertices_pos_color.slice(..), self.descriptors.quad.vertices_pos_color.slice(..),
@ -377,7 +343,7 @@ impl<'pass, 'frame: 'pass, 'global: 'frame> CommandRenderer<'pass, 'frame, 'glob
} }
pub enum Chunk { pub enum Chunk {
Draw(Vec<DrawCommand>, bool, BufferBuilder, BufferBuilder), Draw(Vec<DrawCommand>, bool, BufferBuilder),
Blend(PoolOrArcTexture, ChunkBlendMode, bool), Blend(PoolOrArcTexture, ChunkBlendMode, bool),
} }
@ -392,7 +358,6 @@ pub enum DrawCommand {
RenderBitmap { RenderBitmap {
bitmap: BitmapHandle, bitmap: BitmapHandle,
transform_buffer: wgpu::DynamicOffset, transform_buffer: wgpu::DynamicOffset,
color_buffer: wgpu::DynamicOffset,
smoothing: bool, smoothing: bool,
blend_mode: TrivialBlend, blend_mode: TrivialBlend,
render_stage3d: bool, render_stage3d: bool,
@ -401,17 +366,14 @@ pub enum DrawCommand {
_texture: PoolOrArcTexture, _texture: PoolOrArcTexture,
binds: wgpu::BindGroup, binds: wgpu::BindGroup,
transform_buffer: wgpu::DynamicOffset, transform_buffer: wgpu::DynamicOffset,
color_buffer: wgpu::DynamicOffset,
blend_mode: TrivialBlend, blend_mode: TrivialBlend,
}, },
RenderShape { RenderShape {
shape: ShapeHandle, shape: ShapeHandle,
transform_buffer: wgpu::DynamicOffset, transform_buffer: wgpu::DynamicOffset,
color_buffer: wgpu::DynamicOffset,
}, },
DrawRect { DrawRect {
transform_buffer: wgpu::DynamicOffset, transform_buffer: wgpu::DynamicOffset,
color_buffer: wgpu::DynamicOffset,
}, },
PushMask, PushMask,
ActivateMask, ActivateMask,
@ -448,22 +410,19 @@ pub fn chunk_blends<'a>(
let mut needs_stencil = false; let mut needs_stencil = false;
let mut num_masks = 0; let mut num_masks = 0;
let mut transforms = BufferBuilder::new_for_uniform(&descriptors.limits); let mut transforms = BufferBuilder::new_for_uniform(&descriptors.limits);
let mut color_adjustments = BufferBuilder::new_for_uniform(&descriptors.limits);
transforms.set_buffer_limit(dynamic_transforms.transform.buffer.size()); transforms.set_buffer_limit(dynamic_transforms.transform.buffer.size());
color_adjustments.set_buffer_limit(dynamic_transforms.color.buffer.size());
fn add_to_current( fn add_to_current(
result: &mut Vec<Chunk>, result: &mut Vec<Chunk>,
current: &mut Vec<DrawCommand>, current: &mut Vec<DrawCommand>,
transforms: &mut BufferBuilder, transforms: &mut BufferBuilder,
color_adjustments: &mut BufferBuilder,
dynamic_transforms: &DynamicTransforms, dynamic_transforms: &DynamicTransforms,
needs_stencil: bool, needs_stencil: bool,
descriptors: &Descriptors, descriptors: &Descriptors,
matrix: Matrix, matrix: Matrix,
color_transform: ColorTransform, color_transform: ColorTransform,
command_builder: impl FnOnce(wgpu::DynamicOffset, wgpu::DynamicOffset) -> DrawCommand, command_builder: impl FnOnce(wgpu::DynamicOffset) -> DrawCommand,
) { ) {
let transform = Transforms { let transform = Transforms {
world_matrix: [ world_matrix: [
@ -477,15 +436,12 @@ pub fn chunk_blends<'a>(
1.0, 1.0,
], ],
], ],
mult_color: color_transform.mult_rgba_normalized(),
add_color: color_transform.add_rgba_normalized(),
}; };
let color = ColorAdjustments::from(&color_transform); if let Ok(transform_range) = transforms.add(&[transform]) {
if let (Ok(transform_range), Ok(color_range)) = (
transforms.add(&[transform]),
color_adjustments.add(&[color]),
) {
current.push(command_builder( current.push(command_builder(
transform_range.start as wgpu::DynamicOffset, transform_range.start as wgpu::DynamicOffset,
color_range.start as wgpu::DynamicOffset,
)); ));
} else { } else {
result.push(Chunk::Draw( result.push(Chunk::Draw(
@ -495,22 +451,13 @@ pub fn chunk_blends<'a>(
transforms, transforms,
BufferBuilder::new_for_uniform(&descriptors.limits), BufferBuilder::new_for_uniform(&descriptors.limits),
), ),
std::mem::replace(
color_adjustments,
BufferBuilder::new_for_uniform(&descriptors.limits),
),
)); ));
transforms.set_buffer_limit(dynamic_transforms.transform.buffer.size()); transforms.set_buffer_limit(dynamic_transforms.transform.buffer.size());
color_adjustments.set_buffer_limit(dynamic_transforms.color.buffer.size());
let transform_range = transforms let transform_range = transforms
.add(&[transform]) .add(&[transform])
.expect("Buffer must be able to fit a new thing, it was just emptied"); .expect("Buffer must be able to fit a new thing, it was just emptied");
let color_range = color_adjustments
.add(&[color])
.expect("Buffer must be able to fit a new thing, it was just emptied");
current.push(command_builder( current.push(command_builder(
transform_range.start as wgpu::DynamicOffset, transform_range.start as wgpu::DynamicOffset,
color_range.start as wgpu::DynamicOffset,
)); ));
} }
} }
@ -587,17 +534,15 @@ pub fn chunk_blends<'a>(
&mut result, &mut result,
&mut current, &mut current,
&mut transforms, &mut transforms,
&mut color_adjustments,
dynamic_transforms, dynamic_transforms,
needs_stencil, needs_stencil,
descriptors, descriptors,
transform.matrix, transform.matrix,
transform.color_transform, transform.color_transform,
|transform_buffer, color_buffer| DrawCommand::RenderTexture { |transform_buffer| DrawCommand::RenderTexture {
_texture: texture, _texture: texture,
binds: bind_group, binds: bind_group,
transform_buffer, transform_buffer,
color_buffer,
blend_mode, blend_mode,
}, },
); );
@ -611,14 +556,9 @@ pub fn chunk_blends<'a>(
&mut transforms, &mut transforms,
BufferBuilder::new_for_uniform(&descriptors.limits), BufferBuilder::new_for_uniform(&descriptors.limits),
), ),
std::mem::replace(
&mut color_adjustments,
BufferBuilder::new_for_uniform(&descriptors.limits),
),
)); ));
} }
transforms.set_buffer_limit(dynamic_transforms.transform.buffer.size()); transforms.set_buffer_limit(dynamic_transforms.transform.buffer.size());
color_adjustments.set_buffer_limit(dynamic_transforms.color.buffer.size());
let chunk_blend_mode = match blend_type { let chunk_blend_mode = match blend_type {
BlendType::Complex(complex) => ChunkBlendMode::Complex(complex), BlendType::Complex(complex) => ChunkBlendMode::Complex(complex),
BlendType::Shader(shader) => ChunkBlendMode::Shader(shader), BlendType::Shader(shader) => ChunkBlendMode::Shader(shader),
@ -652,16 +592,14 @@ pub fn chunk_blends<'a>(
&mut result, &mut result,
&mut current, &mut current,
&mut transforms, &mut transforms,
&mut color_adjustments,
dynamic_transforms, dynamic_transforms,
needs_stencil, needs_stencil,
descriptors, descriptors,
matrix, matrix,
transform.color_transform, transform.color_transform,
|transform_buffer, color_buffer| DrawCommand::RenderBitmap { |transform_buffer| DrawCommand::RenderBitmap {
bitmap, bitmap,
transform_buffer, transform_buffer,
color_buffer,
smoothing, smoothing,
blend_mode: TrivialBlend::Normal, blend_mode: TrivialBlend::Normal,
render_stage3d: false, render_stage3d: false,
@ -681,16 +619,14 @@ pub fn chunk_blends<'a>(
&mut result, &mut result,
&mut current, &mut current,
&mut transforms, &mut transforms,
&mut color_adjustments,
dynamic_transforms, dynamic_transforms,
needs_stencil, needs_stencil,
descriptors, descriptors,
matrix, matrix,
transform.color_transform, transform.color_transform,
|transform_buffer, color_buffer| DrawCommand::RenderBitmap { |transform_buffer| DrawCommand::RenderBitmap {
bitmap, bitmap,
transform_buffer, transform_buffer,
color_buffer,
smoothing: false, smoothing: false,
blend_mode: TrivialBlend::Normal, blend_mode: TrivialBlend::Normal,
render_stage3d: true, render_stage3d: true,
@ -701,23 +637,20 @@ pub fn chunk_blends<'a>(
&mut result, &mut result,
&mut current, &mut current,
&mut transforms, &mut transforms,
&mut color_adjustments,
dynamic_transforms, dynamic_transforms,
needs_stencil, needs_stencil,
descriptors, descriptors,
transform.matrix, transform.matrix,
transform.color_transform, transform.color_transform,
|transform_buffer, color_buffer| DrawCommand::RenderShape { |transform_buffer| DrawCommand::RenderShape {
shape, shape,
transform_buffer, transform_buffer,
color_buffer,
}, },
), ),
Command::DrawRect { color, matrix } => add_to_current( Command::DrawRect { color, matrix } => add_to_current(
&mut result, &mut result,
&mut current, &mut current,
&mut transforms, &mut transforms,
&mut color_adjustments,
dynamic_transforms, dynamic_transforms,
needs_stencil, needs_stencil,
descriptors, descriptors,
@ -729,10 +662,7 @@ pub fn chunk_blends<'a>(
a_multiply: Fixed8::from_f32(f32::from(color.a) / 255.0), a_multiply: Fixed8::from_f32(f32::from(color.a) / 255.0),
..Default::default() ..Default::default()
}, },
|transform_buffer, color_buffer| DrawCommand::DrawRect { |transform_buffer| DrawCommand::DrawRect { transform_buffer },
transform_buffer,
color_buffer,
},
), ),
Command::PushMask => { Command::PushMask => {
needs_stencil = true; needs_stencil = true;
@ -756,12 +686,7 @@ pub fn chunk_blends<'a>(
} }
if !current.is_empty() { if !current.is_empty() {
result.push(Chunk::Draw( result.push(Chunk::Draw(current, needs_stencil, transforms));
current,
needs_stencil,
transforms,
color_adjustments,
));
} }
result result

View File

@ -469,6 +469,8 @@ fn get_whole_frame_bind_group<'a>(
[0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 1.0, 0.0],
[0.0, 0.0, 0.0, 1.0], [0.0, 0.0, 0.0, 1.0],
], ],
mult_color: [1.0, 1.0, 1.0, 1.0],
add_color: [0.0, 0.0, 0.0, 0.0],
}; };
let transforms_buffer = create_buffer_with_data( let transforms_buffer = create_buffer_with_data(
&descriptors.device, &descriptors.device,

View File

@ -28,17 +28,11 @@ These should be set for the whole render pass and be immutable during it.
## Group 1: Mesh transforms ## Group 1: Mesh transforms
These should be set for the current mesh being rendered. These should be set for the current mesh being rendered.
| Index | Type | Description | Availability | | Index | Type | Description | Availability |
|:-----:|---------|:------------------|--------------| |:-----:|---------|:----------------------------------|--------------|
| 0 | uniform | World matrix | Vertex | | 0 | uniform | World matrix and color transforms | Vertex |
# Bitmaps ## Group 2: Texture transforms
## Group 2: Color transforms
| Index | Type | Description | Availability |
|:-----:|------------|:-------------------------------------|--------------|
| 0 | uniform | Color adjustments | Fragment |
## Group 3: Texture transforms
| Index | Type | Description | Availability | | Index | Type | Description | Availability |
|:-----:|------------|:-------------------------------------|--------------| |:-----:|------------|:-------------------------------------|--------------|
| 0 | uniform | Transformation matrix of the texture | Vertex | | 0 | uniform | Transformation matrix of the texture | Vertex |
@ -46,12 +40,7 @@ These should be set for the current mesh being rendered.
| 2 | sampler | Sampler used for the texture | Fragment | | 2 | sampler | Sampler used for the texture | Fragment |
# Gradient # Gradient
## Group 2: Color transforms ## Group 2: Texture transforms
| Index | Type | Description | Availability |
|:-----:|------------|:-------------------------------------|--------------|
| 0 | uniform | Color adjustments | Fragment |
## Group 3: Texture transforms
Index 1 is a storage buffer when supported by the device, or a uniform buffer otherwise. Index 1 is a storage buffer when supported by the device, or a uniform buffer otherwise.
Storage buffers are more efficient and waste less memory, but are not as widely supported (ie WebGL) Storage buffers are more efficient and waste less memory, but are not as widely supported (ie WebGL)
@ -59,9 +48,3 @@ Storage buffers are more efficient and waste less memory, but are not as widely
|:-----:|--------------------|:--------------------------------------|--------------| |:-----:|--------------------|:--------------------------------------|--------------|
| 0 | uniform | Transformation matrix of the gradient | Vertex | | 0 | uniform | Transformation matrix of the gradient | Vertex |
| 1 | uniform or storage | Gradient information, colors etc | Fragment | | 1 | uniform or storage | Gradient information, colors etc | Fragment |
# Color
## Group 2: Color transforms
| Index | Type | Description | Availability |
|:-----:|------------|:-------------------------------------|--------------|
| 0 | uniform | Color adjustments | Fragment |