1
1
use 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 ;
3
4
use futures:: lock:: Mutex ;
4
5
use graphene_core:: raster_types:: { GPU , Raster } ;
5
6
use graphene_core:: table:: { Table , TableRow } ;
6
7
use std:: borrow:: Cow ;
7
8
use std:: collections:: HashMap ;
9
+ use wgpu:: util:: { BufferInitDescriptor , DeviceExt } ;
8
10
use 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 ,
11
13
TextureViewDescriptor , VertexState ,
12
14
} ;
13
15
@@ -25,18 +27,20 @@ impl PerPixelAdjustShaderRuntime {
25
27
}
26
28
27
29
impl 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 > > {
29
31
let mut cache = self . per_pixel_adjust . pipeline_cache . lock ( ) . await ;
30
32
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) ) ;
36
35
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
+ }
40
44
}
41
45
42
46
pub struct PerPixelAdjustGraphicsPipeline {
@@ -45,11 +49,14 @@ pub struct PerPixelAdjustGraphicsPipeline {
45
49
}
46
50
47
51
impl PerPixelAdjustGraphicsPipeline {
48
- pub fn new ( context : & Context , info : & PerPixelAdjustInfo ) -> Self {
52
+ pub fn new ( context : & Context , info : & Shaders ) -> Self {
49
53
let device = & context. device ;
50
54
let name = info. fragment_shader_name . to_owned ( ) ;
55
+
51
56
// 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 ( ":" , "" ) ;
53
60
54
61
let shader_module = device. create_shader_module ( ShaderModuleDescriptor {
55
62
label : Some ( & format ! ( "PerPixelAdjust {} wgsl shader" , name) ) ,
@@ -91,12 +98,12 @@ impl PerPixelAdjustGraphicsPipeline {
91
98
Self { pipeline, name }
92
99
}
93
100
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 > > {
95
102
let device = & context. device ;
96
103
let name = self . name . as_str ( ) ;
97
104
98
105
let mut cmd = device. create_command_encoder ( & wgpu:: CommandEncoderDescriptor { label : Some ( "gpu_invert" ) } ) ;
99
- let out = input
106
+ let out = textures
100
107
. iter ( )
101
108
. map ( |instance| {
102
109
let tex_in = & instance. element . texture ;
@@ -107,10 +114,20 @@ impl PerPixelAdjustGraphicsPipeline {
107
114
label : Some ( & format ! ( "{name} bind group" ) ) ,
108
115
// `get_bind_group_layout` allocates unnecessary memory, we could create it manually to not do that
109
116
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
+ ] ,
114
131
} ) ;
115
132
116
133
let tex_out = device. create_texture ( & TextureDescriptor {
0 commit comments