render: Store view_matrix as a global in wgpu renderer, and only change it when changed
This commit is contained in:
parent
a2d53df49c
commit
bbd8fc768c
|
@ -1,12 +1,12 @@
|
|||
#version 450
|
||||
|
||||
layout(set = 0, binding = 2) uniform Colors {
|
||||
layout(set = 1, binding = 2) uniform Colors {
|
||||
vec4 mult_color;
|
||||
vec4 add_color;
|
||||
};
|
||||
|
||||
layout(set = 0, binding = 3) uniform texture2D t_color;
|
||||
layout(set = 1, binding = 0) uniform sampler s_color;
|
||||
layout(set = 1, binding = 3) uniform texture2D t_color;
|
||||
layout(set = 2, binding = 0) uniform sampler s_color;
|
||||
|
||||
layout(location=0) in vec2 frag_uv;
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,11 +1,14 @@
|
|||
#version 450
|
||||
|
||||
layout(set = 0, binding = 0) uniform Transforms {
|
||||
layout(set = 0, binding = 0) uniform Globals {
|
||||
mat4 view_matrix;
|
||||
};
|
||||
|
||||
layout(set = 1, binding = 0) uniform Transforms {
|
||||
mat4 world_matrix;
|
||||
};
|
||||
|
||||
layout(set = 0, binding = 1) uniform Colors {
|
||||
layout(set = 1, binding = 1) uniform Colors {
|
||||
vec4 mult_color;
|
||||
vec4 add_color;
|
||||
};
|
||||
|
|
Binary file not shown.
|
@ -1,11 +1,11 @@
|
|||
#version 450
|
||||
|
||||
layout(set = 0, binding = 2) uniform Colors {
|
||||
layout(set = 1, binding = 2) uniform Colors {
|
||||
vec4 mult_color;
|
||||
vec4 add_color;
|
||||
};
|
||||
|
||||
layout(std430, set = 0, binding = 3) buffer Gradient {
|
||||
layout(std430, set = 1, binding = 3) buffer Gradient {
|
||||
vec4 u_colors[16];
|
||||
float u_ratios[16];
|
||||
int u_gradient_type;
|
||||
|
|
Binary file not shown.
|
@ -1,11 +1,14 @@
|
|||
#version 450
|
||||
|
||||
layout(set = 0, binding = 0) uniform Transforms {
|
||||
layout(set = 0, binding = 0) uniform Globals {
|
||||
mat4 view_matrix;
|
||||
};
|
||||
|
||||
layout(set = 1, binding = 0) uniform Transforms {
|
||||
mat4 world_matrix;
|
||||
};
|
||||
|
||||
layout(set = 0, binding = 1) uniform Texture {
|
||||
layout(set = 1, binding = 1) uniform Texture {
|
||||
mat4 u_matrix;
|
||||
};
|
||||
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,114 @@
|
|||
use bytemuck::{Pod, Zeroable};
|
||||
use wgpu::util::DeviceExt;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Globals {
|
||||
layout: wgpu::BindGroupLayout,
|
||||
bind_group: wgpu::BindGroup,
|
||||
buffer: wgpu::Buffer,
|
||||
viewport_width: u32,
|
||||
viewport_height: u32,
|
||||
dirty: bool,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
struct GlobalsUniform {
|
||||
view_matrix: [[f32; 4]; 4],
|
||||
}
|
||||
|
||||
unsafe impl Pod for GlobalsUniform {}
|
||||
unsafe impl Zeroable for GlobalsUniform {}
|
||||
|
||||
impl Globals {
|
||||
pub fn new(device: &wgpu::Device) -> Self {
|
||||
let layout_label = create_debug_label!("Globals bind group layout");
|
||||
let layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
label: layout_label.as_deref(),
|
||||
entries: &[wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStage::VERTEX,
|
||||
ty: wgpu::BindingType::UniformBuffer {
|
||||
dynamic: false,
|
||||
min_binding_size: None,
|
||||
},
|
||||
count: None,
|
||||
}],
|
||||
});
|
||||
|
||||
let buffer_label = create_debug_label!("Globals buffer");
|
||||
let buffer = device.create_buffer(&wgpu::BufferDescriptor {
|
||||
label: buffer_label.as_deref(),
|
||||
size: std::mem::size_of::<GlobalsUniform>() as u64,
|
||||
usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
|
||||
mapped_at_creation: false,
|
||||
});
|
||||
|
||||
let bind_group_label = create_debug_label!("Globals bind group");
|
||||
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||
label: bind_group_label.as_deref(),
|
||||
layout: &layout,
|
||||
entries: &[wgpu::BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: wgpu::BindingResource::Buffer {
|
||||
buffer: &buffer,
|
||||
offset: 0,
|
||||
size: wgpu::BufferSize::new(std::mem::size_of::<GlobalsUniform>() as u64),
|
||||
},
|
||||
}],
|
||||
});
|
||||
|
||||
Self {
|
||||
layout,
|
||||
bind_group,
|
||||
buffer,
|
||||
viewport_width: 0,
|
||||
viewport_height: 0,
|
||||
dirty: true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_resolution(&mut self, viewport_width: u32, viewport_height: u32) {
|
||||
if viewport_width != self.viewport_width && viewport_height != self.viewport_height {
|
||||
self.viewport_width = viewport_width;
|
||||
self.viewport_height = viewport_height;
|
||||
self.dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_uniform(&mut self, device: &wgpu::Device, encoder: &mut wgpu::CommandEncoder) {
|
||||
if !self.dirty {
|
||||
return;
|
||||
}
|
||||
self.dirty = false;
|
||||
let temp_label = create_debug_label!("Temporary globals buffer");
|
||||
let temp_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: temp_label.as_deref(),
|
||||
contents: bytemuck::cast_slice(&[GlobalsUniform {
|
||||
view_matrix: [
|
||||
[1.0 / (self.viewport_width as f32 / 2.0), 0.0, 0.0, 0.0],
|
||||
[0.0, -1.0 / (self.viewport_height as f32 / 2.0), 0.0, 0.0],
|
||||
[0.0, 0.0, 1.0, 0.0],
|
||||
[-1.0, 1.0, 0.0, 1.0],
|
||||
],
|
||||
}]),
|
||||
usage: wgpu::BufferUsage::COPY_SRC,
|
||||
});
|
||||
|
||||
encoder.copy_buffer_to_buffer(
|
||||
&temp_buffer,
|
||||
0,
|
||||
&self.buffer,
|
||||
0,
|
||||
std::mem::size_of::<GlobalsUniform>() as u64,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn layout(&self) -> &wgpu::BindGroupLayout {
|
||||
&self.layout
|
||||
}
|
||||
|
||||
pub fn bind_group(&self) -> &wgpu::BindGroup {
|
||||
&self.bind_group
|
||||
}
|
||||
}
|
|
@ -20,9 +20,8 @@ use crate::pipelines::Pipelines;
|
|||
use crate::shapes::{Draw, DrawType, GradientUniforms, IncompleteDrawType, Mesh};
|
||||
use crate::target::{RenderTarget, RenderTargetFrame, SwapChainTarget};
|
||||
use crate::utils::{
|
||||
build_view_matrix, create_buffer_with_data, format_list, get_backend_names,
|
||||
gradient_spread_mode_index, ruffle_path_to_lyon_path, swf_bitmap_to_gl_matrix,
|
||||
swf_to_gl_matrix,
|
||||
create_buffer_with_data, format_list, get_backend_names, gradient_spread_mode_index,
|
||||
ruffle_path_to_lyon_path, swf_bitmap_to_gl_matrix, swf_to_gl_matrix,
|
||||
};
|
||||
use enum_map::Enum;
|
||||
use ruffle_core::color_transform::ColorTransform;
|
||||
|
@ -33,6 +32,7 @@ type Error = Box<dyn std::error::Error>;
|
|||
mod utils;
|
||||
|
||||
mod bitmaps;
|
||||
mod globals;
|
||||
mod pipelines;
|
||||
mod shapes;
|
||||
pub mod target;
|
||||
|
@ -41,6 +41,7 @@ pub mod target;
|
|||
pub mod clap;
|
||||
|
||||
use crate::bitmaps::BitmapSamplers;
|
||||
use crate::globals::Globals;
|
||||
use ruffle_core::swf::{Matrix, Twips};
|
||||
use std::path::Path;
|
||||
pub use wgpu;
|
||||
|
@ -48,6 +49,7 @@ pub use wgpu;
|
|||
pub struct Descriptors {
|
||||
pub device: wgpu::Device,
|
||||
queue: wgpu::Queue,
|
||||
globals: Globals,
|
||||
pipelines: Pipelines,
|
||||
bitmap_samplers: BitmapSamplers,
|
||||
msaa_sample_count: u32,
|
||||
|
@ -59,11 +61,18 @@ impl Descriptors {
|
|||
let msaa_sample_count = 4;
|
||||
|
||||
let bitmap_samplers = BitmapSamplers::new(&device);
|
||||
let pipelines = Pipelines::new(&device, msaa_sample_count, bitmap_samplers.layout())?;
|
||||
let globals = Globals::new(&device);
|
||||
let pipelines = Pipelines::new(
|
||||
&device,
|
||||
msaa_sample_count,
|
||||
bitmap_samplers.layout(),
|
||||
globals.layout(),
|
||||
)?;
|
||||
|
||||
Ok(Self {
|
||||
device,
|
||||
queue,
|
||||
globals,
|
||||
pipelines,
|
||||
bitmap_samplers,
|
||||
msaa_sample_count,
|
||||
|
@ -80,7 +89,6 @@ pub struct WgpuRenderBackend<T: RenderTarget> {
|
|||
meshes: Vec<Mesh>,
|
||||
viewport_width: f32,
|
||||
viewport_height: f32,
|
||||
view_matrix: [[f32; 4]; 4],
|
||||
textures: Vec<(swf::CharacterId, Texture)>,
|
||||
mask_state: MaskState,
|
||||
num_masks: u32,
|
||||
|
@ -100,7 +108,6 @@ pub enum MaskState {
|
|||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
struct Transforms {
|
||||
view_matrix: [[f32; 4]; 4],
|
||||
world_matrix: [[f32; 4]; 4],
|
||||
}
|
||||
|
||||
|
@ -203,7 +210,7 @@ impl WgpuRenderBackend<SwapChainTarget> {
|
|||
}
|
||||
|
||||
impl<T: RenderTarget> WgpuRenderBackend<T> {
|
||||
pub fn new(descriptors: Descriptors, target: T) -> Result<Self, Error> {
|
||||
pub fn new(mut descriptors: Descriptors, target: T) -> Result<Self, Error> {
|
||||
let extent = wgpu::Extent3d {
|
||||
width: target.width(),
|
||||
height: target.height(),
|
||||
|
@ -239,7 +246,10 @@ impl<T: RenderTarget> WgpuRenderBackend<T> {
|
|||
|
||||
let viewport_width = target.width() as f32;
|
||||
let viewport_height = target.height() as f32;
|
||||
let view_matrix = build_view_matrix(target.width(), target.height());
|
||||
|
||||
descriptors
|
||||
.globals
|
||||
.set_resolution(target.width(), target.height());
|
||||
|
||||
Ok(Self {
|
||||
descriptors,
|
||||
|
@ -250,7 +260,6 @@ impl<T: RenderTarget> WgpuRenderBackend<T> {
|
|||
meshes: Vec::new(),
|
||||
viewport_width,
|
||||
viewport_height,
|
||||
view_matrix,
|
||||
textures: Vec::new(),
|
||||
|
||||
num_masks: 0,
|
||||
|
@ -785,7 +794,7 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
|
|||
|
||||
self.viewport_width = width as f32;
|
||||
self.viewport_height = height as f32;
|
||||
self.view_matrix = build_view_matrix(width, height);
|
||||
self.descriptors.globals.set_resolution(width, height);
|
||||
}
|
||||
|
||||
fn register_shape(&mut self, shape: DistilledShape) -> ShapeHandle {
|
||||
|
@ -894,6 +903,9 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
|
|||
}),
|
||||
}),
|
||||
});
|
||||
self.descriptors
|
||||
.globals
|
||||
.update_uniform(&self.descriptors.device, encoder);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -930,10 +942,7 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
|
|||
|
||||
let transforms_ubo = create_buffer_with_data(
|
||||
&self.descriptors.device,
|
||||
bytemuck::cast_slice(&[Transforms {
|
||||
view_matrix: self.view_matrix,
|
||||
world_matrix,
|
||||
}]),
|
||||
bytemuck::cast_slice(&[Transforms { world_matrix }]),
|
||||
wgpu::BufferUsage::UNIFORM,
|
||||
create_debug_label!("Bitmap {} transforms transfer buffer", bitmap.0),
|
||||
);
|
||||
|
@ -1026,9 +1035,10 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
|
|||
.bitmap
|
||||
.pipeline_for(self.mask_state),
|
||||
);
|
||||
render_pass.set_bind_group(0, &bind_group, &[]);
|
||||
render_pass.set_bind_group(0, self.descriptors.globals.bind_group(), &[]);
|
||||
render_pass.set_bind_group(1, &bind_group, &[]);
|
||||
render_pass.set_bind_group(
|
||||
1,
|
||||
2,
|
||||
self.descriptors.bitmap_samplers.get_bind_group(false, true),
|
||||
&[],
|
||||
);
|
||||
|
@ -1094,10 +1104,7 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
|
|||
|
||||
let transforms_temp = create_buffer_with_data(
|
||||
&self.descriptors.device,
|
||||
bytemuck::cast_slice(&[Transforms {
|
||||
view_matrix: self.view_matrix,
|
||||
world_matrix,
|
||||
}]),
|
||||
bytemuck::cast_slice(&[Transforms { world_matrix }]),
|
||||
wgpu::BufferUsage::COPY_SRC,
|
||||
create_debug_label!("Shape {} transforms transfer buffer", mesh.shape_id),
|
||||
);
|
||||
|
@ -1170,7 +1177,7 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
|
|||
.pipeline_for(self.mask_state),
|
||||
);
|
||||
render_pass.set_bind_group(
|
||||
1,
|
||||
2,
|
||||
self.descriptors
|
||||
.bitmap_samplers
|
||||
.get_bind_group(*is_repeating, *is_smoothed),
|
||||
|
@ -1179,7 +1186,8 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
|
|||
}
|
||||
}
|
||||
|
||||
render_pass.set_bind_group(0, &draw.bind_group, &[]);
|
||||
render_pass.set_bind_group(0, self.descriptors.globals.bind_group(), &[]);
|
||||
render_pass.set_bind_group(1, &draw.bind_group, &[]);
|
||||
render_pass.set_vertex_buffer(0, draw.vertex_buffer.slice(..));
|
||||
render_pass.set_index_buffer(draw.index_buffer.slice(..));
|
||||
|
||||
|
@ -1230,10 +1238,7 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
|
|||
|
||||
let transforms_ubo = create_buffer_with_data(
|
||||
&self.descriptors.device,
|
||||
bytemuck::cast_slice(&[Transforms {
|
||||
view_matrix: self.view_matrix,
|
||||
world_matrix,
|
||||
}]),
|
||||
bytemuck::cast_slice(&[Transforms { world_matrix }]),
|
||||
wgpu::BufferUsage::UNIFORM,
|
||||
create_debug_label!("Rectangle transfer buffer"),
|
||||
);
|
||||
|
@ -1311,7 +1316,8 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
|
|||
.color
|
||||
.pipeline_for(self.mask_state),
|
||||
);
|
||||
render_pass.set_bind_group(0, &bind_group, &[]);
|
||||
render_pass.set_bind_group(0, self.descriptors.globals.bind_group(), &[]);
|
||||
render_pass.set_bind_group(1, &bind_group, &[]);
|
||||
render_pass.set_vertex_buffer(0, self.quad_vbo.slice(..));
|
||||
render_pass.set_index_buffer(self.quad_ibo.slice(..));
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ impl Pipelines {
|
|||
device: &wgpu::Device,
|
||||
msaa_sample_count: u32,
|
||||
sampler_layout: &wgpu::BindGroupLayout,
|
||||
globals_layout: &wgpu::BindGroupLayout,
|
||||
) -> Result<Self, Error> {
|
||||
let color_vs =
|
||||
device.create_shader_module(wgpu::include_spirv!("../shaders/color.vert.spv"));
|
||||
|
@ -54,6 +55,7 @@ impl Pipelines {
|
|||
&color_fs,
|
||||
msaa_sample_count,
|
||||
&vertex_buffers_description,
|
||||
globals_layout,
|
||||
),
|
||||
bitmap: create_bitmap_pipeline(
|
||||
&device,
|
||||
|
@ -62,6 +64,7 @@ impl Pipelines {
|
|||
msaa_sample_count,
|
||||
&vertex_buffers_description,
|
||||
sampler_layout,
|
||||
globals_layout,
|
||||
),
|
||||
gradient: create_gradient_pipeline(
|
||||
&device,
|
||||
|
@ -69,6 +72,7 @@ impl Pipelines {
|
|||
&gradient_fs,
|
||||
msaa_sample_count,
|
||||
&vertex_buffers_description,
|
||||
globals_layout,
|
||||
),
|
||||
})
|
||||
}
|
||||
|
@ -124,6 +128,7 @@ fn create_color_pipelines(
|
|||
fragment_shader: &wgpu::ShaderModule,
|
||||
msaa_sample_count: u32,
|
||||
vertex_buffers_description: &[wgpu::VertexBufferDescriptor<'_>],
|
||||
globals_layout: &wgpu::BindGroupLayout,
|
||||
) -> ShapePipeline {
|
||||
let bind_layout_label = create_debug_label!("Color shape bind group");
|
||||
let bind_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
|
@ -153,7 +158,7 @@ fn create_color_pipelines(
|
|||
let pipeline_layout_label = create_debug_label!("Color shape pipeline layout");
|
||||
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: pipeline_layout_label.as_deref(),
|
||||
bind_group_layouts: &[&bind_layout],
|
||||
bind_group_layouts: &[globals_layout, &bind_layout],
|
||||
push_constant_ranges: &[],
|
||||
});
|
||||
|
||||
|
@ -300,6 +305,7 @@ fn create_bitmap_pipeline(
|
|||
msaa_sample_count: u32,
|
||||
vertex_buffers_description: &[wgpu::VertexBufferDescriptor<'_>],
|
||||
sampler_layout: &wgpu::BindGroupLayout,
|
||||
globals_layout: &wgpu::BindGroupLayout,
|
||||
) -> ShapePipeline {
|
||||
let bind_layout_label = create_debug_label!("Bitmap shape bind group");
|
||||
let bind_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
|
@ -348,7 +354,7 @@ fn create_bitmap_pipeline(
|
|||
let pipeline_layout_label = create_debug_label!("Bitmap shape pipeline layout");
|
||||
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: pipeline_layout_label.as_deref(),
|
||||
bind_group_layouts: &[&bind_layout, sampler_layout],
|
||||
bind_group_layouts: &[globals_layout, &bind_layout, sampler_layout],
|
||||
push_constant_ranges: &[],
|
||||
});
|
||||
|
||||
|
@ -494,6 +500,7 @@ fn create_gradient_pipeline(
|
|||
fragment_shader: &wgpu::ShaderModule,
|
||||
msaa_sample_count: u32,
|
||||
vertex_buffers_description: &[wgpu::VertexBufferDescriptor<'_>],
|
||||
globals_layout: &wgpu::BindGroupLayout,
|
||||
) -> ShapePipeline {
|
||||
let bind_layout_label = create_debug_label!("Gradient shape bind group");
|
||||
let bind_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
|
@ -542,7 +549,7 @@ fn create_gradient_pipeline(
|
|||
let pipeline_layout_label = create_debug_label!("Gradient shape pipeline layout");
|
||||
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: pipeline_layout_label.as_deref(),
|
||||
bind_group_layouts: &[&bind_layout],
|
||||
bind_group_layouts: &[globals_layout, &bind_layout],
|
||||
push_constant_ranges: &[],
|
||||
});
|
||||
|
||||
|
|
|
@ -169,15 +169,6 @@ pub fn swf_bitmap_to_gl_matrix(
|
|||
]
|
||||
}
|
||||
|
||||
pub fn build_view_matrix(viewport_width: u32, viewport_height: u32) -> [[f32; 4]; 4] {
|
||||
[
|
||||
[1.0 / (viewport_width as f32 / 2.0), 0.0, 0.0, 0.0],
|
||||
[0.0, -1.0 / (viewport_height as f32 / 2.0), 0.0, 0.0],
|
||||
[0.0, 0.0, 1.0, 0.0],
|
||||
[-1.0, 1.0, 0.0, 1.0],
|
||||
]
|
||||
}
|
||||
|
||||
/// Map for SWF gradient spread mode to the uniform value used by the gradient shader.
|
||||
pub fn gradient_spread_mode_index(spread: GradientSpread) -> i32 {
|
||||
match spread {
|
||||
|
|
Loading…
Reference in New Issue