-
Notifications
You must be signed in to change notification settings - Fork 0
/
wasmgpu_helpers.go
99 lines (86 loc) · 2.86 KB
/
wasmgpu_helpers.go
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
package engine
import (
"fmt"
"github.com/hulkholden/gowebgpu/common/wgsltypes"
"github.com/mokiat/gog/opt"
"github.com/mokiat/wasmgpu"
)
var vertexFormatTypeMap = map[wgsltypes.TypeName]wasmgpu.GPUVertexFormat{
"f32": wasmgpu.GPUVertexFormatFloat32,
"i32": wasmgpu.GPUVertexFormatSint32,
"u32": wasmgpu.GPUVertexFormatUint32,
"vec2<f32>": wasmgpu.GPUVertexFormatFloat32x2,
"vec3<f32>": wasmgpu.GPUVertexFormatFloat32x3,
"vec4<f32>": wasmgpu.GPUVertexFormatFloat32x4,
}
func makeGPUVertexAttribute(shaderLocation int, s wgsltypes.Struct, fieldName string) wasmgpu.GPUVertexAttribute {
field, ok := s.FieldMap[fieldName]
if !ok {
panic(fmt.Sprintf("field %s.%s does not exist", s.Name, fieldName))
}
return wasmgpu.GPUVertexAttribute{
ShaderLocation: wasmgpu.GPUIndex32(shaderLocation),
Format: mustFormatFromFieldType(field.WGSLType.Name),
Offset: wasmgpu.GPUSize64(s.MustOffsetOf(fieldName)),
}
}
func mustFormatFromFieldType(fieldType wgsltypes.TypeName) wasmgpu.GPUVertexFormat {
format, ok := vertexFormatTypeMap[fieldType]
if !ok {
panic("unhandled wgsltype: " + fieldType)
}
return format
}
func MakeGPUBindingGroupEntries(resources ...wasmgpu.GPUBindingResource) []wasmgpu.GPUBindGroupEntry {
entries := make([]wasmgpu.GPUBindGroupEntry, len(resources))
for idx, resource := range resources {
entries[idx] = wasmgpu.GPUBindGroupEntry{
Binding: wasmgpu.GPUIndex32(idx),
Resource: resource,
}
}
return entries
}
type BufferDescriptor struct {
Struct *wgsltypes.Struct
// Instanced specifices whether the buffer is stepped as a vertex or instance buffer.
Instanced bool
}
type VertexAttribute struct {
BufferIndex int
FieldName string
}
type VertexBuffers struct {
Layout []wasmgpu.GPUVertexBufferLayout
Buffers []wasmgpu.GPUBuffer
}
func NewVertexBuffers(bufDefs []BufferDescriptor, vtxAttrs []VertexAttribute) *VertexBuffers {
result := make([]wasmgpu.GPUVertexBufferLayout, len(bufDefs))
for idx, bd := range bufDefs {
stepMode := wasmgpu.GPUVertexStepModeVertex
if bd.Instanced {
stepMode = wasmgpu.GPUVertexStepModeInstance
}
result[idx] = wasmgpu.GPUVertexBufferLayout{
ArrayStride: wasmgpu.GPUSize64(bd.Struct.Size),
StepMode: opt.V(stepMode),
}
}
for idx, a := range vtxAttrs {
if a.BufferIndex >= len(result) {
panic("buffer index out of bounds")
}
attribute := makeGPUVertexAttribute(idx, *bufDefs[a.BufferIndex].Struct, a.FieldName)
result[a.BufferIndex].Attributes = append(result[a.BufferIndex].Attributes, attribute)
}
return &VertexBuffers{
Layout: result,
Buffers: make([]wasmgpu.GPUBuffer, len(result)),
}
}
func (v *VertexBuffers) Bind(passEncoder wasmgpu.GPURenderPassEncoder) {
unspecified := opt.Unspecified[wasmgpu.GPUSize64]()
for idx, buffer := range v.Buffers {
passEncoder.SetVertexBuffer(wasmgpu.GPUIndex32(idx), buffer, unspecified, unspecified)
}
}