mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-03 16:35:36 +00:00
gpu: setup OpenGL ES texture uniforms automatically from shader metadata
Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
+43
-6
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user