-
Notifications
You must be signed in to change notification settings - Fork 4
/
shader.go
104 lines (89 loc) · 2.82 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
// Copyright (c) 2022, 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.
// This is initially adapted from https://github.com/vulkan-go/asche
// Copyright © 2017 Maxim Kupriianov <max@kc.vc>, under the MIT License
package vgpu
import (
"log"
"os"
"unsafe"
vk "github.com/goki/vulkan"
)
// Shader manages a single Shader program
type Shader struct {
Name string
Type ShaderTypes
VkModule vk.ShaderModule
}
// Init initializes the shader
func (sh *Shader) Init(name string, typ ShaderTypes) {
sh.Name = name
sh.Type = typ
}
// OpenFile loads given SPIR-V ".spv" code from file for the Shader.
func (sh *Shader) OpenFile(dev vk.Device, fname string) error {
b, err := os.ReadFile(fname)
if err != nil {
log.Printf("vgpu.Shader OpenFile: %s\n", err)
return err
}
return sh.OpenCode(dev, b)
}
// OpenCode loads given SPIR-V ".spv" code for the Shader.
func (sh *Shader) OpenCode(dev vk.Device, code []byte) error {
uicode := SliceUint32(code)
var module vk.ShaderModule
ret := vk.CreateShaderModule(dev, &vk.ShaderModuleCreateInfo{
SType: vk.StructureTypeShaderModuleCreateInfo,
CodeSize: uint64(len(code)),
PCode: uicode,
}, nil, &module)
if IsError(ret) {
return NewError(ret)
}
sh.VkModule = module
return nil
}
// Free deletes the shader module, which can be done after the pipeline
// is created.
func (sh *Shader) Free(dev vk.Device) {
if sh.VkModule == vk.NullShaderModule {
return
}
vk.DestroyShaderModule(dev, sh.VkModule, nil)
sh.VkModule = vk.NullShaderModule
}
// todo: use 1.17 unsafe.Slice function
// https://stackoverflow.com/questions/11924196/convert-between-slices-of-different-types
func SliceUint32(data []byte) []uint32 {
return (*[ByteCopyMemoryLimit / 4]uint32)(unsafe.Pointer(unsafe.Pointer(&(data[0]))))[:len(data)/4]
}
// ShaderTypes is a list of GPU shader types
type ShaderTypes int32
const (
VertexShader ShaderTypes = iota
TessCtrlShader
TessEvalShader
GeometryShader
FragmentShader
ComputeShader
AllShaders
)
var ShaderStageFlags = map[ShaderTypes]vk.ShaderStageFlagBits{
VertexShader: vk.ShaderStageVertexBit,
TessCtrlShader: vk.ShaderStageTessellationControlBit,
TessEvalShader: vk.ShaderStageTessellationEvaluationBit,
GeometryShader: vk.ShaderStageGeometryBit,
FragmentShader: vk.ShaderStageFragmentBit,
ComputeShader: vk.ShaderStageComputeBit,
AllShaders: vk.ShaderStageAll,
}
var ShaderPipelineFlags = map[ShaderTypes]vk.PipelineStageFlagBits{
VertexShader: vk.PipelineStageVertexShaderBit,
TessCtrlShader: vk.PipelineStageTessellationControlShaderBit,
TessEvalShader: vk.PipelineStageTessellationEvaluationShaderBit,
GeometryShader: vk.PipelineStageGeometryShaderBit,
FragmentShader: vk.PipelineStageFragmentShaderBit,
ComputeShader: vk.PipelineStageComputeShaderBit,
}