diff --git a/librashader-runtime-wgpu/src/buffer.rs b/librashader-runtime-wgpu/src/buffer.rs index 63a203c9..6f517ff5 100644 --- a/librashader-runtime-wgpu/src/buffer.rs +++ b/librashader-runtime-wgpu/src/buffer.rs @@ -1,5 +1,4 @@ use std::ops::{Deref, DerefMut}; -use std::sync::Arc; pub struct WgpuStagedBuffer { buffer: wgpu::Buffer, @@ -8,7 +7,7 @@ pub struct WgpuStagedBuffer { impl WgpuStagedBuffer { pub fn new( - device: &Arc, + device: &wgpu::Device, usage: wgpu::BufferUsages, size: wgpu::BufferAddress, label: wgpu::Label<'static>, diff --git a/librashader-runtime-wgpu/src/filter_chain.rs b/librashader-runtime-wgpu/src/filter_chain.rs index 54203bcb..304b2fbd 100644 --- a/librashader-runtime-wgpu/src/filter_chain.rs +++ b/librashader-runtime-wgpu/src/filter_chain.rs @@ -88,7 +88,7 @@ pub(crate) struct FilterCommon { pub samplers: SamplerSet, pub config: RuntimeParameters, pub(crate) draw_quad: DrawQuad, - device: Arc, + pub(crate) device: Arc, pub(crate) queue: Arc, } @@ -184,7 +184,7 @@ impl FilterChainWgpu { // initialize passes let filters = Self::init_passes( - Arc::clone(&device), + &device, passes, &semantics, options.and_then(|o| o.adapter_info.as_ref()), @@ -192,7 +192,7 @@ impl FilterChainWgpu { )?; let samplers = SamplerSet::new(&device); - let mut mipmapper = MipmapGen::new(Arc::clone(&device)); + let mut mipmapper = MipmapGen::new(&device); let luts = FilterChainWgpu::load_luts( &device, &queue, @@ -204,7 +204,7 @@ impl FilterChainWgpu { // let framebuffer_gen = || { Ok::<_, error::FilterChainError>(OwnedImage::new( - Arc::clone(&device), + &device, Size::new(1, 1), 1, TextureFormat::Bgra8Unorm, @@ -286,7 +286,7 @@ impl FilterChainWgpu { let _old_back = std::mem::replace( &mut back, OwnedImage::new( - Arc::clone(&self.common.device), + &self.common.device, input.size().into(), 1, input.format().into(), @@ -294,14 +294,14 @@ impl FilterChainWgpu { ); } - back.copy_from(cmd, input); + back.copy_from(&self.common.device, cmd, input); self.history_framebuffers.push_front(back) } } fn init_passes( - device: Arc, + device: &wgpu::Device, passes: Vec, semantics: &ShaderSemantics, adapter_info: Option<&wgpu::AdapterInfo>, @@ -354,7 +354,7 @@ impl FilterChainWgpu { }; let graphics_pipeline = WgpuGraphicsPipeline::new( - Arc::clone(&device), + &device, &wgsl, &reflection, render_pass_format.unwrap_or(TextureFormat::Rgba8Unorm), @@ -363,7 +363,6 @@ impl FilterChainWgpu { ); Ok(FilterPass { - device: Arc::clone(&device), reflection, uniform_storage, uniform_bindings, @@ -458,7 +457,7 @@ impl FilterChainWgpu { &mut self.output_framebuffers, &mut self.feedback_framebuffers, passes, - &(), + &self.common.device, Some(&mut |index: usize, pass: &FilterPass, output: &OwnedImage, @@ -506,7 +505,7 @@ impl FilterChainWgpu { FilterMode::Nearest, ); - target.generate_mipmaps(cmd, &mut self.mipmapper, &sampler); + target.generate_mipmaps(&self.common.device, cmd, &mut self.mipmapper, &sampler); } source = self.common.output_textures[index].clone().unwrap(); @@ -519,7 +518,8 @@ impl FilterChainWgpu { let index = passes_len - 1; if !pass.graphics_pipeline.has_format(viewport.output.format) { // need to recompile - pass.graphics_pipeline.recompile(viewport.output.format); + pass.graphics_pipeline + .recompile(&self.common.device, viewport.output.format); } source.filter_mode = pass.meta.filter; diff --git a/librashader-runtime-wgpu/src/filter_pass.rs b/librashader-runtime-wgpu/src/filter_pass.rs index aaafa5bb..25bd9267 100644 --- a/librashader-runtime-wgpu/src/filter_pass.rs +++ b/librashader-runtime-wgpu/src/filter_pass.rs @@ -23,14 +23,13 @@ use std::sync::Arc; use wgpu::{BindGroupDescriptor, BindGroupEntry, BindingResource, BufferBinding, ShaderStages}; pub struct FilterPass { - pub device: Arc, pub reflection: ShaderReflection, pub(crate) uniform_storage: UniformStorage< NoUniformBinder, Option<()>, WgpuStagedBuffer, WgpuStagedBuffer, - Arc, + wgpu::Device, >, pub uniform_bindings: FastHashMap, pub source: ShaderSource, @@ -56,7 +55,7 @@ impl BindSemantics, WgpuStagedBuffer, WgpuStagedBuff &'a mut FastHashMap>, &'a mut FastHashMap>, ); - type DeviceContext = Arc; + type DeviceContext = wgpu::Device; type UniformOffset = MemberOffset; #[inline(always)] @@ -162,13 +161,13 @@ impl FilterPass { } } - let main_bind_group = self.device.create_bind_group(&BindGroupDescriptor { + let main_bind_group = parent.device.create_bind_group(&BindGroupDescriptor { label: Some("librashader main bind group"), layout: &self.graphics_pipeline.layout.main_bind_group_layout, entries: &main_heap_array, }); - let sampler_bind_group = self.device.create_bind_group(&BindGroupDescriptor { + let sampler_bind_group = parent.device.create_bind_group(&BindGroupDescriptor { label: Some("librashader sampler bind group"), layout: &self.graphics_pipeline.layout.sampler_bind_group_layout, entries: &sampler_heap_array, @@ -216,7 +215,7 @@ impl FilterPass { sampler_heap: &'a mut FastHashMap>, ) { Self::bind_semantics( - &self.device, + &parent.device, &parent.samplers, &mut self.uniform_storage, &mut (main_heap, sampler_heap), diff --git a/librashader-runtime-wgpu/src/graphics_pipeline.rs b/librashader-runtime-wgpu/src/graphics_pipeline.rs index be58f9aa..c550b611 100644 --- a/librashader-runtime-wgpu/src/graphics_pipeline.rs +++ b/librashader-runtime-wgpu/src/graphics_pipeline.rs @@ -9,7 +9,6 @@ use librashader_runtime::quad::VertexInput; use librashader_runtime::render_target::RenderTarget; use std::borrow::Cow; use std::convert::Infallible; -use std::sync::Arc; use wgpu::{ BindGroupLayout, BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingType, BufferBindingType, BufferSize, CommandEncoder, Operations, PipelineLayout, PushConstantRange, @@ -32,14 +31,13 @@ pub struct PipelineLayoutObjects { vertex_entry_name: String, vertex: ShaderModule, fragment: ShaderModule, - device: Arc, } impl PipelineLayoutObjects { pub fn new( reflection: &ShaderReflection, shader_assembly: &ShaderCompilerOutput, - device: Arc, + device: &wgpu::Device, ) -> Self { let vertex = device.create_shader_module(wgpu::ShaderModuleDescriptor { label: Some("vertex"), @@ -147,76 +145,75 @@ impl PipelineLayoutObjects { vertex_entry_name: shader_assembly.context.vertex.entry_points[0].name.clone(), vertex, fragment, - device, } } pub fn create_pipeline( &self, + device: &wgpu::Device, framebuffer_format: TextureFormat, cache: Option<&wgpu::PipelineCache>, ) -> wgpu::RenderPipeline { - self.device - .create_render_pipeline(&wgpu::RenderPipelineDescriptor { - label: Some("Render Pipeline"), - layout: Some(&self.layout), - vertex: wgpu::VertexState { - module: &self.vertex, - entry_point: Some(&self.vertex_entry_name), - compilation_options: wgpu::PipelineCompilationOptions::default(), - buffers: &[VertexBufferLayout { - array_stride: std::mem::size_of::() as wgpu::BufferAddress, - step_mode: wgpu::VertexStepMode::Vertex, - attributes: &[ - wgpu::VertexAttribute { - format: wgpu::VertexFormat::Float32x4, - offset: bytemuck::offset_of!(VertexInput, position) - as wgpu::BufferAddress, - shader_location: 0, - }, - wgpu::VertexAttribute { - format: wgpu::VertexFormat::Float32x2, - offset: bytemuck::offset_of!(VertexInput, texcoord) - as wgpu::BufferAddress, - shader_location: 1, - }, - ], - }], - }, - fragment: Some(wgpu::FragmentState { - module: &self.fragment, - entry_point: Some(&self.fragment_entry_name), - compilation_options: wgpu::PipelineCompilationOptions::default(), - targets: &[Some(wgpu::ColorTargetState { - format: framebuffer_format, - blend: None, - write_mask: wgpu::ColorWrites::ALL, - })], - }), - primitive: wgpu::PrimitiveState { - topology: wgpu::PrimitiveTopology::TriangleStrip, - strip_index_format: None, - front_face: wgpu::FrontFace::Ccw, - cull_mode: None, - unclipped_depth: false, - polygon_mode: wgpu::PolygonMode::Fill, - conservative: false, - }, - depth_stencil: None, - multisample: wgpu::MultisampleState { - count: 1, - mask: !0, - alpha_to_coverage_enabled: false, - }, - multiview: None, - cache, - }) + device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: Some("Render Pipeline"), + layout: Some(&self.layout), + vertex: wgpu::VertexState { + module: &self.vertex, + entry_point: Some(&self.vertex_entry_name), + compilation_options: wgpu::PipelineCompilationOptions::default(), + buffers: &[VertexBufferLayout { + array_stride: std::mem::size_of::() as wgpu::BufferAddress, + step_mode: wgpu::VertexStepMode::Vertex, + attributes: &[ + wgpu::VertexAttribute { + format: wgpu::VertexFormat::Float32x4, + offset: bytemuck::offset_of!(VertexInput, position) + as wgpu::BufferAddress, + shader_location: 0, + }, + wgpu::VertexAttribute { + format: wgpu::VertexFormat::Float32x2, + offset: bytemuck::offset_of!(VertexInput, texcoord) + as wgpu::BufferAddress, + shader_location: 1, + }, + ], + }], + }, + fragment: Some(wgpu::FragmentState { + module: &self.fragment, + entry_point: Some(&self.fragment_entry_name), + compilation_options: wgpu::PipelineCompilationOptions::default(), + targets: &[Some(wgpu::ColorTargetState { + format: framebuffer_format, + blend: None, + write_mask: wgpu::ColorWrites::ALL, + })], + }), + primitive: wgpu::PrimitiveState { + topology: wgpu::PrimitiveTopology::TriangleStrip, + strip_index_format: None, + front_face: wgpu::FrontFace::Ccw, + cull_mode: None, + unclipped_depth: false, + polygon_mode: wgpu::PolygonMode::Fill, + conservative: false, + }, + depth_stencil: None, + multisample: wgpu::MultisampleState { + count: 1, + mask: !0, + alpha_to_coverage_enabled: false, + }, + multiview: None, + cache, + }) } } impl WgpuGraphicsPipeline { pub fn new( - device: Arc, + device: &wgpu::Device, shader_assembly: &ShaderCompilerOutput, reflection: &ShaderReflection, render_pass_format: TextureFormat, @@ -256,7 +253,7 @@ impl WgpuGraphicsPipeline { let mut render_pipelines = FastHashMap::default(); render_pipelines.insert( render_pass_format, - layout.create_pipeline(render_pass_format, cache.as_ref()), + layout.create_pipeline(device, render_pass_format, cache.as_ref()), ); Self { layout, @@ -269,8 +266,10 @@ impl WgpuGraphicsPipeline { self.render_pipelines.contains_key(&format) } - pub fn recompile(&mut self, format: TextureFormat) { - let render_pipeline = self.layout.create_pipeline(format, self.cache.as_ref()); + pub fn recompile(&mut self, device: &wgpu::Device, format: TextureFormat) { + let render_pipeline = self + .layout + .create_pipeline(device, format, self.cache.as_ref()); self.render_pipelines.insert(format, render_pipeline); } diff --git a/librashader-runtime-wgpu/src/luts.rs b/librashader-runtime-wgpu/src/luts.rs index 84ae875c..88648482 100644 --- a/librashader-runtime-wgpu/src/luts.rs +++ b/librashader-runtime-wgpu/src/luts.rs @@ -61,6 +61,7 @@ impl LutTexture { if config.mipmap { mipmapper.generate_mipmaps( + device, cmd, &texture, &*sampler_set.get( diff --git a/librashader-runtime-wgpu/src/mipmap.rs b/librashader-runtime-wgpu/src/mipmap.rs index 2f5bc06f..797c05a5 100644 --- a/librashader-runtime-wgpu/src/mipmap.rs +++ b/librashader-runtime-wgpu/src/mipmap.rs @@ -1,9 +1,7 @@ use librashader_common::map::FastHashMap; use std::borrow::Cow; -use std::sync::Arc; pub struct MipmapGen { - device: Arc, shader: wgpu::ShaderModule, pipeline_cache: FastHashMap, } @@ -41,14 +39,13 @@ impl MipmapGen { pipeline } - pub fn new(device: Arc) -> Self { + pub fn new(device: &wgpu::Device) -> Self { let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { label: None, source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("../shader/blit.wgsl"))), }); Self { - device, shader, pipeline_cache: Default::default(), } @@ -56,6 +53,7 @@ impl MipmapGen { pub fn generate_mipmaps( &mut self, + device: &wgpu::Device, cmd: &mut wgpu::CommandEncoder, texture: &wgpu::Texture, sampler: &wgpu::Sampler, @@ -65,7 +63,7 @@ impl MipmapGen { let pipeline = &*self .pipeline_cache .entry(format) - .or_insert_with(|| Self::create_pipeline(&self.device, &self.shader, format)); + .or_insert_with(|| Self::create_pipeline(&device, &self.shader, format)); let views = (0..miplevels) .map(|mip| { @@ -84,7 +82,7 @@ impl MipmapGen { for target_mip in 1..miplevels as usize { let bind_group_layout = pipeline.get_bind_group_layout(0); - let bind_group = self.device.create_bind_group(&wgpu::BindGroupDescriptor { + let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { layout: &bind_group_layout, entries: &[ wgpu::BindGroupEntry { diff --git a/librashader-runtime-wgpu/src/texture.rs b/librashader-runtime-wgpu/src/texture.rs index 0f60b9ed..34c2b3dc 100644 --- a/librashader-runtime-wgpu/src/texture.rs +++ b/librashader-runtime-wgpu/src/texture.rs @@ -8,7 +8,6 @@ use std::sync::Arc; use wgpu::TextureFormat; pub struct OwnedImage { - device: Arc, pub image: Arc, pub view: Arc, pub max_miplevels: u32, @@ -33,7 +32,7 @@ impl AsRef for InputImage { impl OwnedImage { pub fn new( - device: Arc, + device: &wgpu::Device, size: Size, max_miplevels: u32, format: TextureFormat, @@ -64,7 +63,6 @@ impl OwnedImage { }); Self { - device, image: Arc::new(texture), view: Arc::new(view), max_miplevels, @@ -75,6 +73,7 @@ impl OwnedImage { pub fn scale( &mut self, + device: &wgpu::Device, scaling: Scale2D, format: TextureFormat, viewport_size: &Size, @@ -88,12 +87,7 @@ impl OwnedImage { || (!mipmap && self.max_miplevels != 1) || format != self.image.format() { - let mut new = OwnedImage::new( - Arc::clone(&self.device), - size, - self.max_miplevels, - format.into(), - ); + let mut new = OwnedImage::new(device, size, self.max_miplevels, format.into()); std::mem::swap(self, &mut new); } size @@ -109,15 +103,15 @@ impl OwnedImage { } } - pub fn copy_from(&mut self, cmd: &mut wgpu::CommandEncoder, source: &wgpu::Texture) { + pub fn copy_from( + &mut self, + device: &wgpu::Device, + cmd: &mut wgpu::CommandEncoder, + source: &wgpu::Texture, + ) { let source_size = source.size().into(); if source.format() != self.image.format() || self.size != source_size { - let mut new = OwnedImage::new( - Arc::clone(&self.device), - source_size, - self.max_miplevels, - source.format(), - ); + let mut new = OwnedImage::new(device, source_size, self.max_miplevels, source.format()); std::mem::swap(self, &mut new); } @@ -131,19 +125,21 @@ impl OwnedImage { pub fn clear(&self, cmd: &mut wgpu::CommandEncoder) { cmd.clear_texture(&self.image, &wgpu::ImageSubresourceRange::default()); } + pub fn generate_mipmaps( &self, + device: &wgpu::Device, cmd: &mut wgpu::CommandEncoder, mipmapper: &mut MipmapGen, sampler: &wgpu::Sampler, ) { - mipmapper.generate_mipmaps(cmd, &self.image, sampler, self.max_miplevels); + mipmapper.generate_mipmaps(device, cmd, &self.image, sampler, self.max_miplevels); } } impl ScaleFramebuffer for OwnedImage { type Error = FilterChainError; - type Context = (); + type Context = wgpu::Device; fn scale( &mut self, @@ -153,11 +149,12 @@ impl ScaleFramebuffer for OwnedImage { source_size: &Size, original_size: &Size, should_mipmap: bool, - _context: &Self::Context, + device: &Self::Context, ) -> Result, Self::Error> { let format: Option = format.into(); let format = format.unwrap_or(TextureFormat::Bgra8Unorm); Ok(self.scale( + device, scaling, format, viewport_size,