11use crate :: Context ;
2- use crate :: shader_runtime:: { FULLSCREEN_VERTEX_SHADER_NAME , ShaderRuntime } ;
2+ use crate :: shader_runtime:: { FULLSCREEN_VERTEX_SHADER_NAME , ShaderRuntime , Shaders } ;
3+ use bytemuck:: NoUninit ;
34use futures:: lock:: Mutex ;
45use graphene_core:: raster_types:: { GPU , Raster } ;
56use graphene_core:: table:: { Table , TableRow } ;
67use std:: borrow:: Cow ;
78use std:: collections:: HashMap ;
9+ use wgpu:: util:: { BufferInitDescriptor , DeviceExt } ;
810use wgpu:: {
9- BindGroupDescriptor , BindGroupEntry , BindingResource , ColorTargetState , Face , FragmentState , FrontFace , LoadOp , Operations , PolygonMode , PrimitiveState , PrimitiveTopology ,
10- RenderPassColorAttachment , RenderPassDescriptor , RenderPipelineDescriptor , ShaderModuleDescriptor , ShaderSource , StoreOp , TextureDescriptor , TextureDimension , TextureFormat ,
11+ BindGroupDescriptor , BindGroupEntry , BindingResource , Buffer , BufferBinding , BufferUsages , ColorTargetState , Face , FragmentState , FrontFace , LoadOp , Operations , PolygonMode , PrimitiveState ,
12+ PrimitiveTopology , RenderPassColorAttachment , RenderPassDescriptor , RenderPipelineDescriptor , ShaderModuleDescriptor , ShaderSource , StoreOp , TextureDescriptor , TextureDimension , TextureFormat ,
1113 TextureViewDescriptor , VertexState ,
1214} ;
1315
@@ -25,18 +27,20 @@ impl PerPixelAdjustShaderRuntime {
2527}
2628
2729impl ShaderRuntime {
28- pub async fn run_per_pixel_adjust ( & self , input : Table < Raster < GPU > > , info : & PerPixelAdjustInfo < ' _ > ) -> Table < Raster < GPU > > {
30+ pub async fn run_per_pixel_adjust < T : NoUninit > ( & self , shaders : & Shaders < ' _ > , textures : Table < Raster < GPU > > , args : & T ) -> Table < Raster < GPU > > {
2931 let mut cache = self . per_pixel_adjust . pipeline_cache . lock ( ) . await ;
3032 let pipeline = cache
31- . entry ( info. fragment_shader_name . to_owned ( ) )
32- . or_insert_with ( || PerPixelAdjustGraphicsPipeline :: new ( & self . context , & info) ) ;
33- pipeline. run ( & self . context , input)
34- }
35- }
33+ . entry ( shaders. fragment_shader_name . to_owned ( ) )
34+ . or_insert_with ( || PerPixelAdjustGraphicsPipeline :: new ( & self . context , & shaders) ) ;
3635
37- pub struct PerPixelAdjustInfo < ' a > {
38- pub wgsl_shader : & ' a str ,
39- pub fragment_shader_name : & ' a str ,
36+ let device = & self . context . device ;
37+ let arg_buffer = device. create_buffer_init ( & BufferInitDescriptor {
38+ label : Some ( & format ! ( "{} arg buffer" , pipeline. name. as_str( ) ) ) ,
39+ usage : BufferUsages :: STORAGE ,
40+ contents : bytemuck:: bytes_of ( args) ,
41+ } ) ;
42+ pipeline. dispatch ( & self . context , textures, & arg_buffer)
43+ }
4044}
4145
4246pub struct PerPixelAdjustGraphicsPipeline {
@@ -45,11 +49,14 @@ pub struct PerPixelAdjustGraphicsPipeline {
4549}
4650
4751impl PerPixelAdjustGraphicsPipeline {
48- pub fn new ( context : & Context , info : & PerPixelAdjustInfo ) -> Self {
52+ pub fn new ( context : & Context , info : & Shaders ) -> Self {
4953 let device = & context. device ;
5054 let name = info. fragment_shader_name . to_owned ( ) ;
55+
5156 // TODO workaround to naga removing `:`
52- let fragment_name = name. replace ( ":" , "" ) ;
57+ let fragment_name = & name;
58+ let fragment_name = & fragment_name[ ( fragment_name. find ( "::" ) . unwrap ( ) + 2 ) ..] ;
59+ let fragment_name = fragment_name. replace ( ":" , "" ) ;
5360
5461 let shader_module = device. create_shader_module ( ShaderModuleDescriptor {
5562 label : Some ( & format ! ( "PerPixelAdjust {} wgsl shader" , name) ) ,
@@ -91,12 +98,12 @@ impl PerPixelAdjustGraphicsPipeline {
9198 Self { pipeline, name }
9299 }
93100
94- pub fn run ( & self , context : & Context , input : Table < Raster < GPU > > ) -> Table < Raster < GPU > > {
101+ pub fn dispatch ( & self , context : & Context , textures : Table < Raster < GPU > > , arg_buffer : & Buffer ) -> Table < Raster < GPU > > {
95102 let device = & context. device ;
96103 let name = self . name . as_str ( ) ;
97104
98105 let mut cmd = device. create_command_encoder ( & wgpu:: CommandEncoderDescriptor { label : Some ( "gpu_invert" ) } ) ;
99- let out = input
106+ let out = textures
100107 . iter ( )
101108 . map ( |instance| {
102109 let tex_in = & instance. element . texture ;
@@ -107,10 +114,20 @@ impl PerPixelAdjustGraphicsPipeline {
107114 label : Some ( & format ! ( "{name} bind group" ) ) ,
108115 // `get_bind_group_layout` allocates unnecessary memory, we could create it manually to not do that
109116 layout : & self . pipeline . get_bind_group_layout ( 0 ) ,
110- entries : & [ BindGroupEntry {
111- binding : 0 ,
112- resource : BindingResource :: TextureView ( & view_in) ,
113- } ] ,
117+ entries : & [
118+ BindGroupEntry {
119+ binding : 0 ,
120+ resource : BindingResource :: Buffer ( BufferBinding {
121+ buffer : arg_buffer,
122+ offset : 0 ,
123+ size : None ,
124+ } ) ,
125+ } ,
126+ BindGroupEntry {
127+ binding : 1 ,
128+ resource : BindingResource :: TextureView ( & view_in) ,
129+ } ,
130+ ] ,
114131 } ) ;
115132
116133 let tex_out = device. create_texture ( & TextureDescriptor {
0 commit comments