-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathTextureBinding.ts
127 lines (112 loc) · 4.29 KB
/
TextureBinding.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import { Binding, BindingMemoryAccessType, BindingParams, BindingType } from './Binding'
import { getBindGroupLayoutTextureBindingType, getTextureBindingWGSLVarType } from './utils'
/** Defines a {@link TextureBinding} {@link TextureBinding#resource | resource} */
export type TextureBindingResource = GPUTexture | GPUExternalTexture | null
/**
* An object defining all possible {@link TextureBinding} class instancing parameters
*/
export interface TextureBindingParams extends BindingParams {
/** {@link TextureBinding} {@link TextureBinding#resource | resource} */
texture: TextureBindingResource
/** The {@link GPUTexture | texture} format to use */
format?: GPUTextureFormat
/** The storage {@link GPUTexture | texture} binding memory access types (read only, write only or read/write) */
access?: BindingMemoryAccessType
/** The {@link GPUTexture | texture} view dimension to use */
viewDimension?: GPUTextureViewDimension
/** Whethe the {@link GPUTexture | texture} is a multisampled texture. Mainly used internally by depth textures if needed. */
multisampled?: boolean
}
/**
* Used to handle {@link GPUTexture} and {@link GPUExternalTexture} bindings.
*
* Provide both {@link TextureBinding#resourceLayout | resourceLayout} and {@link TextureBinding#resource | resource} to the {@link GPUBindGroupLayout} and {@link GPUBindGroup}.<br>
* Also create the appropriate WGSL code snippet to add to the shaders.
*/
export class TextureBinding extends Binding {
/** Our {@link TextureBinding} resource, i.e. a {@link GPUTexture} or {@link GPUExternalTexture} */
texture: TextureBindingResource
/** An array of strings to append to our shaders code declaring all the WGSL variables representing this {@link TextureBinding} */
wgslGroupFragment: string[]
/** Options used to create this {@link TextureBinding} */
options: TextureBindingParams
/**
* TextureBinding constructor
* @param parameters - {@link TextureBindingParams | parameters} used to create our {@link TextureBinding}
*/
constructor({
label = 'Texture',
name = 'texture',
bindingType,
visibility,
texture,
format = 'rgba8unorm',
access = 'write',
viewDimension = '2d',
multisampled = false,
}: TextureBindingParams) {
bindingType = bindingType ?? 'texture'
if (bindingType === 'storage') {
visibility = 'compute'
}
super({ label, name, bindingType, visibility })
this.options = {
...this.options,
texture,
format,
access,
viewDimension,
multisampled,
}
this.resource = texture // should be a texture or an external texture
this.setWGSLFragment()
}
/**
* Get bind group layout entry resource, either for {@link GPUBindGroupLayoutEntry#texture | texture} or {@link GPUBindGroupLayoutEntry#externalTexture | external texture}
* @readonly
*/
get resourceLayout():
| GPUTextureBindingLayout
| GPUExternalTextureBindingLayout
| GPUStorageTextureBindingLayout
| null {
return getBindGroupLayoutTextureBindingType(this)
}
/**
* Get the {@link GPUBindGroupEntry#resource | bind group resource}
*/
get resource(): GPUExternalTexture | GPUTextureView | null {
return this.texture instanceof GPUTexture
? this.texture.createView({ label: this.options.label + ' view', dimension: this.options.viewDimension })
: this.texture instanceof GPUExternalTexture
? this.texture
: null
}
/**
* Set the {@link GPUBindGroupEntry#resource | bind group resource}
* @param value - new bind group resource
*/
set resource(value: TextureBindingResource) {
// resource changed, update bind group!
if (value || this.texture) this.shouldResetBindGroup = true
this.texture = value
}
/**
* Set or update our {@link Binding#bindingType | bindingType} and our WGSL code snippet
* @param bindingType - the new {@link Binding#bindingType | binding type}
*/
setBindingType(bindingType: BindingType) {
if (bindingType !== this.bindingType) {
// binding type has changed!
if (bindingType) this.shouldResetBindGroupLayout = true
this.bindingType = bindingType
this.setWGSLFragment()
}
}
/**
* Set the correct WGSL code snippet.
*/
setWGSLFragment() {
this.wgslGroupFragment = [`${getTextureBindingWGSLVarType(this)}`]
}
}