gpu: setup OpenGL ES texture uniforms automatically from shader metadata

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2020-02-20 21:39:29 +01:00
parent 5c359bbf89
commit 4e3bfd5b1b
6 changed files with 77 additions and 30 deletions
+43 -6
View File
@@ -27,6 +27,12 @@ type shaderArgs struct {
Header string
}
// TextureBinding matches gpu.TextureBinding.
type TextureBinding struct {
Name string
Binding int
}
// InputLocation matches gpu.InputLocation.
type InputLocation struct {
Name string
@@ -90,6 +96,7 @@ func generate() error {
hlsl []byte
inputs []InputLocation
uniforms []UniformLocation
textures []TextureBinding
uniformSize int
}
args := [nvariants]shaderArgs{
@@ -109,7 +116,7 @@ func generate() error {
}
// Make the GL ES 2 source compatible with desktop GL 3.
gles2 = "#version 100\n" + gles2
inputs, uniforms, uniformSize, err := parseReflection(reflect)
inputs, uniforms, textures, uniformSize, err := parseReflection(reflect)
if err != nil {
return err
}
@@ -138,6 +145,7 @@ func generate() error {
variants[i].hlsl = hlslc
variants[i].inputs = inputs
variants[i].uniforms = uniforms
variants[i].textures = textures
variants[i].uniformSize = uniformSize
}
name := filepath.Base(shader)
@@ -165,8 +173,17 @@ func generate() error {
fmt.Fprintf(&out, "{Name: %q, Type: %d, Size: %d, Offset: %d},\n", u.Name, u.Type, u.Size, u.Offset)
}
fmt.Fprintf(&out, "},\n")
}
if src.uniformSize != 0 {
fmt.Fprintf(&out, "UniformSize: %d,\n", src.uniformSize)
}
if len(src.textures) > 0 {
fmt.Fprintf(&out, "Textures: []TextureBinding{\n")
for _, t := range src.textures {
fmt.Fprintf(&out, "{Name: %q, Binding: %d},\n", t.Name, t.Binding)
}
fmt.Fprintf(&out, "},\n")
}
fmt.Fprintf(&out, "GLES2: %#v,\n", src.gles2)
fmt.Fprintf(&out, "/*\n%s\n*/\n", src.hlslSrc)
fmt.Fprintf(&out, "HLSL: %#v,\n", src.hlsl)
@@ -191,7 +208,7 @@ func generate() error {
return ioutil.WriteFile("shaders.go", gosrc, 0644)
}
func parseReflection(jsonData []byte) ([]InputLocation, []UniformLocation, int, error) {
func parseReflection(jsonData []byte) ([]InputLocation, []UniformLocation, []TextureBinding, int, error) {
type InputReflection struct {
ID int `json:"id"`
Name string `json:"name"`
@@ -214,9 +231,18 @@ func parseReflection(jsonData []byte) ([]InputLocation, []UniformLocation, int,
Size int `json:"block_size"`
Members []UniformMemberReflection `json:"members"`
}
type TextureReflection struct {
ID int `json:"id"`
Name string `json:"name"`
Set int `json:"set"`
Binding int `json:"binding"`
Dimension string `json:"dimension"`
Format string `json:"format"`
}
type shaderReflection struct {
Inputs []InputReflection `json:"inputs"`
UniformBuffers []UniformBufferReflection `json:"uniform_buffers"`
Textures []TextureReflection `json:"textures"`
}
type shaderMetadata struct {
VS shaderReflection `json:"vs"`
@@ -224,14 +250,14 @@ func parseReflection(jsonData []byte) ([]InputLocation, []UniformLocation, int,
}
var reflect shaderMetadata
if err := json.Unmarshal(jsonData, &reflect); err != nil {
return nil, nil, 0, fmt.Errorf("parseReflection: %v", err)
return nil, nil, nil, 0, fmt.Errorf("parseReflection: %v", err)
}
var inputs []InputLocation
inputRef := reflect.VS.Inputs
for _, input := range inputRef {
dataType, dataSize, err := parseDataType(input.Type)
if err != nil {
return nil, nil, 0, fmt.Errorf("parseReflection: %v", err)
return nil, nil, nil, 0, fmt.Errorf("parseReflection: %v", err)
}
inputs = append(inputs, InputLocation{
Name: input.Name,
@@ -255,7 +281,7 @@ func parseReflection(jsonData []byte) ([]InputLocation, []UniformLocation, int,
for _, member := range block.Members {
dataType, size, err := parseDataType(member.Type)
if err != nil {
return nil, nil, 0, fmt.Errorf("parseReflection: %v", err)
return nil, nil, nil, 0, fmt.Errorf("parseReflection: %v", err)
}
ublocks = append(ublocks, UniformLocation{
// Synthetic name generated by glslcc.
@@ -267,7 +293,18 @@ func parseReflection(jsonData []byte) ([]InputLocation, []UniformLocation, int,
}
blockOffset += block.Size
}
return inputs, ublocks, blockOffset, nil
textures := reflect.VS.Textures
if len(textures) == 0 {
textures = reflect.FS.Textures
}
var texBinds []TextureBinding
for _, texture := range textures {
texBinds = append(texBinds, TextureBinding{
Name: texture.Name,
Binding: texture.Binding,
})
}
return inputs, ublocks, texBinds, blockOffset, nil
}
func parseDataType(t string) (DataType, int, error) {