wgpu: Globals should now belong to the Surface and doesn't need to be mutable anymore
This commit is contained in:
parent
d2185733b4
commit
915040ba06
|
@ -7,8 +7,8 @@ use crate::target::TextureTarget;
|
||||||
use crate::uniform_buffer::BufferStorage;
|
use crate::uniform_buffer::BufferStorage;
|
||||||
use crate::utils::remove_srgb;
|
use crate::utils::remove_srgb;
|
||||||
use crate::{
|
use crate::{
|
||||||
as_texture, format_list, get_backend_names, BufferDimensions, Descriptors, Error, Globals,
|
as_texture, format_list, get_backend_names, BufferDimensions, Descriptors, Error, RenderTarget,
|
||||||
RenderTarget, SwapChainTarget, Texture, TextureOffscreen, Transforms,
|
SwapChainTarget, Texture, TextureOffscreen, Transforms,
|
||||||
};
|
};
|
||||||
use gc_arena::MutationContext;
|
use gc_arena::MutationContext;
|
||||||
use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle};
|
use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle};
|
||||||
|
@ -25,11 +25,10 @@ use std::sync::Arc;
|
||||||
use swf::Color;
|
use swf::Color;
|
||||||
use wgpu::Extent3d;
|
use wgpu::Extent3d;
|
||||||
|
|
||||||
const DEFAULT_SAMPLE_COUNT: u32 = 1;
|
const DEFAULT_SAMPLE_COUNT: u32 = 4;
|
||||||
|
|
||||||
pub struct WgpuRenderBackend<T: RenderTarget> {
|
pub struct WgpuRenderBackend<T: RenderTarget> {
|
||||||
descriptors: Arc<Descriptors>,
|
descriptors: Arc<Descriptors>,
|
||||||
globals: Globals,
|
|
||||||
uniform_buffers_storage: BufferStorage<Transforms>,
|
uniform_buffers_storage: BufferStorage<Transforms>,
|
||||||
target: T,
|
target: T,
|
||||||
surface: Surface,
|
surface: Surface,
|
||||||
|
@ -158,15 +157,11 @@ impl<T: RenderTarget> WgpuRenderBackend<T> {
|
||||||
frame_buffer_format,
|
frame_buffer_format,
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut globals = Globals::new(&descriptors.device, &descriptors.bind_layouts.globals);
|
|
||||||
globals.set_resolution(target.width(), target.height());
|
|
||||||
|
|
||||||
let uniform_buffers_storage =
|
let uniform_buffers_storage =
|
||||||
BufferStorage::from_alignment(descriptors.limits.min_uniform_buffer_offset_alignment);
|
BufferStorage::from_alignment(descriptors.limits.min_uniform_buffer_offset_alignment);
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
descriptors,
|
descriptors,
|
||||||
globals,
|
|
||||||
uniform_buffers_storage,
|
uniform_buffers_storage,
|
||||||
target,
|
target,
|
||||||
surface,
|
surface,
|
||||||
|
@ -282,7 +277,6 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
|
||||||
frame_buffer_format,
|
frame_buffer_format,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.globals.set_resolution(width, height);
|
|
||||||
self.viewport_scale_factor = dimensions.scale_factor;
|
self.viewport_scale_factor = dimensions.scale_factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -404,7 +398,6 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
|
||||||
a: f64::from(clear.a) / 255.0,
|
a: f64::from(clear.a) / 255.0,
|
||||||
}),
|
}),
|
||||||
&self.descriptors,
|
&self.descriptors,
|
||||||
&mut self.globals,
|
|
||||||
&mut self.uniform_buffers_storage,
|
&mut self.uniform_buffers_storage,
|
||||||
&self.meshes,
|
&self.meshes,
|
||||||
commands,
|
commands,
|
||||||
|
@ -414,7 +407,7 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
|
||||||
command_buffers.push(srgb.copy_srgb(
|
command_buffers.push(srgb.copy_srgb(
|
||||||
frame_output.view(),
|
frame_output.view(),
|
||||||
&self.descriptors,
|
&self.descriptors,
|
||||||
&self.globals,
|
&self.surface.globals(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -577,9 +570,6 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
|
||||||
buffer_dimensions: texture_offscreen.buffer_dimensions.clone(),
|
buffer_dimensions: texture_offscreen.buffer_dimensions.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let (old_width, old_height) = self.globals.resolution();
|
|
||||||
self.globals.set_resolution(width, height);
|
|
||||||
|
|
||||||
let frame_output = target
|
let frame_output = target
|
||||||
.get_next_texture()
|
.get_next_texture()
|
||||||
.expect("TextureTargetFrame.get_next_texture is infallible");
|
.expect("TextureTargetFrame.get_next_texture is infallible");
|
||||||
|
@ -588,7 +578,6 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
|
||||||
frame_output.view(),
|
frame_output.view(),
|
||||||
None,
|
None,
|
||||||
&self.descriptors,
|
&self.descriptors,
|
||||||
&mut self.globals,
|
|
||||||
&mut self.uniform_buffers_storage,
|
&mut self.uniform_buffers_storage,
|
||||||
&self.meshes,
|
&self.meshes,
|
||||||
commands,
|
commands,
|
||||||
|
@ -612,8 +601,6 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
self.globals.set_resolution(old_width, old_height);
|
|
||||||
|
|
||||||
Ok(image.unwrap())
|
Ok(image.unwrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,10 +5,7 @@ use wgpu::util::DeviceExt;
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Globals {
|
pub struct Globals {
|
||||||
bind_group: wgpu::BindGroup,
|
bind_group: wgpu::BindGroup,
|
||||||
buffer: wgpu::Buffer,
|
_buffer: wgpu::Buffer,
|
||||||
viewport_width: u32,
|
|
||||||
viewport_height: u32,
|
|
||||||
dirty: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
@ -18,15 +15,24 @@ struct GlobalsUniform {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Globals {
|
impl Globals {
|
||||||
pub fn new(device: &wgpu::Device, layout: &wgpu::BindGroupLayout) -> Self {
|
pub fn new(
|
||||||
let buffer_label = create_debug_label!("Globals buffer");
|
device: &wgpu::Device,
|
||||||
let buffer = device.create_buffer(&wgpu::BufferDescriptor {
|
layout: &wgpu::BindGroupLayout,
|
||||||
label: buffer_label.as_deref(),
|
viewport_width: u32,
|
||||||
size: std::mem::size_of::<GlobalsUniform>() as u64,
|
viewport_height: u32,
|
||||||
usage: wgpu::BufferUsages::UNIFORM
|
) -> Self {
|
||||||
| wgpu::BufferUsages::COPY_DST
|
let temp_label = create_debug_label!("Globals buffer");
|
||||||
| wgpu::BufferUsages::STORAGE,
|
let buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||||
mapped_at_creation: false,
|
label: temp_label.as_deref(),
|
||||||
|
contents: bytemuck::cast_slice(&[GlobalsUniform {
|
||||||
|
view_matrix: [
|
||||||
|
[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],
|
||||||
|
],
|
||||||
|
}]),
|
||||||
|
usage: wgpu::BufferUsages::UNIFORM,
|
||||||
});
|
});
|
||||||
|
|
||||||
let bind_group_label = create_debug_label!("Globals bind group");
|
let bind_group_label = create_debug_label!("Globals bind group");
|
||||||
|
@ -45,53 +51,10 @@ impl Globals {
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
bind_group,
|
bind_group,
|
||||||
buffer,
|
_buffer: buffer,
|
||||||
viewport_width: 0,
|
|
||||||
viewport_height: 0,
|
|
||||||
dirty: true,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolution(&self) -> (u32, u32) {
|
|
||||||
(self.viewport_width, self.viewport_height)
|
|
||||||
}
|
|
||||||
|
|
||||||
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::BufferUsages::COPY_SRC,
|
|
||||||
});
|
|
||||||
|
|
||||||
encoder.copy_buffer_to_buffer(
|
|
||||||
&temp_buffer,
|
|
||||||
0,
|
|
||||||
&self.buffer,
|
|
||||||
0,
|
|
||||||
std::mem::size_of::<GlobalsUniform>() as u64,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn bind_group(&self) -> &wgpu::BindGroup {
|
pub fn bind_group(&self) -> &wgpu::BindGroup {
|
||||||
&self.bind_group
|
&self.bind_group
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,7 @@ pub struct Surface {
|
||||||
frame_buffer: Option<FrameBuffer>,
|
frame_buffer: Option<FrameBuffer>,
|
||||||
depth: DepthTexture,
|
depth: DepthTexture,
|
||||||
pipelines: Arc<Pipelines>,
|
pipelines: Arc<Pipelines>,
|
||||||
|
globals: Globals,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Surface {
|
impl Surface {
|
||||||
|
@ -91,22 +92,28 @@ impl Surface {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let globals = Globals::new(
|
||||||
|
&descriptors.device,
|
||||||
|
&descriptors.bind_layouts.globals,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
);
|
||||||
|
|
||||||
let depth = DepthTexture::new(&descriptors.device, msaa_sample_count, width, height);
|
let depth = DepthTexture::new(&descriptors.device, msaa_sample_count, width, height);
|
||||||
let pipelines = descriptors.pipelines(msaa_sample_count, frame_buffer_format);
|
let pipelines = descriptors.pipelines(msaa_sample_count, frame_buffer_format);
|
||||||
Self {
|
Self {
|
||||||
frame_buffer,
|
frame_buffer,
|
||||||
depth,
|
depth,
|
||||||
pipelines,
|
pipelines,
|
||||||
|
globals,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
|
||||||
pub fn draw_commands(
|
pub fn draw_commands(
|
||||||
&self,
|
&self,
|
||||||
frame_view: &wgpu::TextureView,
|
frame_view: &wgpu::TextureView,
|
||||||
clear_color: Option<wgpu::Color>,
|
clear_color: Option<wgpu::Color>,
|
||||||
descriptors: &Descriptors,
|
descriptors: &Descriptors,
|
||||||
globals: &mut Globals,
|
|
||||||
uniform_buffers_storage: &mut BufferStorage<Transforms>,
|
uniform_buffers_storage: &mut BufferStorage<Transforms>,
|
||||||
meshes: &Vec<Mesh>,
|
meshes: &Vec<Mesh>,
|
||||||
commands: CommandList,
|
commands: CommandList,
|
||||||
|
@ -127,8 +134,6 @@ impl Surface {
|
||||||
label: uniform_encoder_label.as_deref(),
|
label: uniform_encoder_label.as_deref(),
|
||||||
});
|
});
|
||||||
|
|
||||||
globals.update_uniform(&descriptors.device, &mut draw_encoder);
|
|
||||||
|
|
||||||
let load = match clear_color {
|
let load = match clear_color {
|
||||||
Some(color) => wgpu::LoadOp::Clear(color),
|
Some(color) => wgpu::LoadOp::Clear(color),
|
||||||
None => wgpu::LoadOp::Load,
|
None => wgpu::LoadOp::Load,
|
||||||
|
@ -157,7 +162,7 @@ impl Surface {
|
||||||
}),
|
}),
|
||||||
label: None,
|
label: None,
|
||||||
});
|
});
|
||||||
render_pass.set_bind_group(0, globals.bind_group(), &[]);
|
render_pass.set_bind_group(0, self.globals.bind_group(), &[]);
|
||||||
|
|
||||||
uniform_buffers_storage.recall();
|
uniform_buffers_storage.recall();
|
||||||
let mut uniform_buffer = UniformBuffer::new(uniform_buffers_storage);
|
let mut uniform_buffer = UniformBuffer::new(uniform_buffers_storage);
|
||||||
|
@ -177,4 +182,8 @@ impl Surface {
|
||||||
|
|
||||||
vec![uniform_encoder.finish(), draw_encoder.finish()]
|
vec![uniform_encoder.finish(), draw_encoder.finish()]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn globals(&self) -> &Globals {
|
||||||
|
&self.globals
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue