-
-
Notifications
You must be signed in to change notification settings - Fork 87
/
Copy pathshader.go
125 lines (106 loc) · 3.07 KB
/
shader.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
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
// Copyright (c) 2024, Cogent Core. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package gpu
import (
"io/fs"
"os"
"path/filepath"
"cogentcore.org/core/base/errors"
"github.com/cogentcore/webgpu/wgpu"
)
// Shader manages a single Shader program, which can have multiple
// entry points. See ShaderEntry for entry points into Shaders.
type Shader struct {
Name string
module *wgpu.ShaderModule
device Device
}
func NewShader(name string, dev *Device) *Shader {
sh := &Shader{Name: name}
sh.device = *dev
return sh
}
// OpenFile loads given WGSL ".wgl" code from file for the Shader.
func (sh *Shader) OpenFile(fname string) error {
if sh.Name == "" {
sh.Name = fname
}
b, err := os.ReadFile(fname)
if errors.Log(err) != nil {
return err
}
cp := errors.Log1(os.Getwd())
return sh.OpenCode(IncludeFS(os.DirFS(cp), "", string(b))) // todo: maybe not ideal
}
// OpenFileFS loads given WGSL ".wgl" code from file for the Shader.
func (sh *Shader) OpenFileFS(fsys fs.FS, fname string) error {
if sh.Name == "" {
sh.Name = fname
}
b, err := fs.ReadFile(fsys, fname)
if errors.Log(err) != nil {
return err
}
return sh.OpenCode(IncludeFS(fsys, filepath.Dir(fname), string(b)))
}
// OpenCode loads given WGSL ".wgl" code for the Shader.
func (sh *Shader) OpenCode(code string) error {
module, err := sh.device.Device.CreateShaderModule(&wgpu.ShaderModuleDescriptor{
Label: sh.Name,
WGSLDescriptor: &wgpu.ShaderModuleWGSLDescriptor{Code: code},
})
if errors.Log(err) != nil {
return err
}
sh.module = module
return nil
}
// Release destroys the shader
func (sh *Shader) Release() {
if sh.module == nil {
return
}
sh.module.Release()
sh.module = nil
}
// ShaderEntry is an entry point into a Shader. There can be multiple
// entry points per shader.
type ShaderEntry struct {
// Shader has the code
Shader *Shader
// Type of shader entry point.
Type ShaderTypes
// Entry is the name of the function to call for this Entry.
// Conventionally, it is some variant on "main"
Entry string
}
// NewShaderEntry returns a new ShaderEntry with given settings
func NewShaderEntry(sh *Shader, typ ShaderTypes, entry string) *ShaderEntry {
se := &ShaderEntry{Shader: sh, Type: typ, Entry: entry}
return se
}
// ShaderTypes is a list of GPU shader types
type ShaderTypes int32
const (
UnknownShader ShaderTypes = iota
VertexShader
FragmentShader
ComputeShader
)
var ShaderStageFlags = map[ShaderTypes]wgpu.ShaderStage{
UnknownShader: wgpu.ShaderStageNone,
VertexShader: wgpu.ShaderStageVertex,
FragmentShader: wgpu.ShaderStageFragment,
ComputeShader: wgpu.ShaderStageCompute,
}
/*
var ShaderPipelineFlags = map[ShaderTypes]vk.PipelineStageFlagBits{
VertexShader: vk.PipelineStageVertexShaderBit,
TessCtrlShader: vk.PipelineStageTessellationControlShaderBit,
TessEvalShader: vk.PipelineStageTessellationEvaluationShaderBit,
GeometryShader: vk.PipelineStageGeometryShaderBit,
FragmentShader: vk.PipelineStageFragmentShaderBit,
ComputeShader: vk.PipelineStageComputeShaderBit,
}
*/