mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-07 10:25:37 +00:00
gpu,gpu/gl: implement shader uniform buffers
Emulate them for the OpenGL ES backend because 2.0 doesn't support uniform buffers. The future d3d backend only supports uniform (constant) buffers. Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
+19
-14
@@ -85,16 +85,17 @@ func generate() error {
|
||||
for _, shader := range shaders {
|
||||
const nvariants = 2
|
||||
var variants [nvariants]struct {
|
||||
gles2 string
|
||||
hlslSrc string
|
||||
hlsl []byte
|
||||
inputs []InputLocation
|
||||
uniforms []UniformLocation
|
||||
gles2 string
|
||||
hlslSrc string
|
||||
hlsl []byte
|
||||
inputs []InputLocation
|
||||
uniforms []UniformLocation
|
||||
uniformSize int
|
||||
}
|
||||
args := [nvariants]shaderArgs{
|
||||
{
|
||||
FetchColorExpr: `color.color`,
|
||||
Header: `layout(binding=0) uniform Color { vec4 color; } color;`,
|
||||
FetchColorExpr: `_color`,
|
||||
Header: `layout(binding=0) uniform Color { vec4 _color; };`,
|
||||
},
|
||||
{
|
||||
FetchColorExpr: `texture(tex, vUV)`,
|
||||
@@ -108,7 +109,7 @@ func generate() error {
|
||||
}
|
||||
// Make the GL ES 2 source compatible with desktop GL 3.
|
||||
gles2 = "#version 100\n" + gles2
|
||||
inputs, uniforms, err := parseReflection(reflect)
|
||||
inputs, uniforms, uniformSize, err := parseReflection(reflect)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -137,6 +138,7 @@ func generate() error {
|
||||
variants[i].hlsl = hlslc
|
||||
variants[i].inputs = inputs
|
||||
variants[i].uniforms = uniforms
|
||||
variants[i].uniformSize = uniformSize
|
||||
}
|
||||
name := filepath.Base(shader)
|
||||
name = strings.ReplaceAll(name, ".", "_")
|
||||
@@ -163,6 +165,7 @@ 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")
|
||||
fmt.Fprintf(&out, "UniformSize: %d,\n", src.uniformSize)
|
||||
}
|
||||
fmt.Fprintf(&out, "GLES2: %#v,\n", src.gles2)
|
||||
fmt.Fprintf(&out, "/*\n%s\n*/\n", src.hlslSrc)
|
||||
@@ -188,7 +191,7 @@ func generate() error {
|
||||
return ioutil.WriteFile("shaders.go", gosrc, 0644)
|
||||
}
|
||||
|
||||
func parseReflection(jsonData []byte) ([]InputLocation, []UniformLocation, error) {
|
||||
func parseReflection(jsonData []byte) ([]InputLocation, []UniformLocation, int, error) {
|
||||
type InputReflection struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
@@ -221,14 +224,14 @@ func parseReflection(jsonData []byte) ([]InputLocation, []UniformLocation, error
|
||||
}
|
||||
var reflect shaderMetadata
|
||||
if err := json.Unmarshal(jsonData, &reflect); err != nil {
|
||||
return nil, nil, fmt.Errorf("parseReflection: %v", err)
|
||||
return 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, err
|
||||
return nil, nil, 0, fmt.Errorf("parseReflection: %v", err)
|
||||
}
|
||||
inputs = append(inputs, InputLocation{
|
||||
Name: input.Name,
|
||||
@@ -247,22 +250,24 @@ func parseReflection(jsonData []byte) ([]InputLocation, []UniformLocation, error
|
||||
if len(shaderBlocks) == 0 {
|
||||
shaderBlocks = reflect.FS.UniformBuffers
|
||||
}
|
||||
blockOffset := 0
|
||||
for _, block := range shaderBlocks {
|
||||
for _, member := range block.Members {
|
||||
dataType, size, err := parseDataType(member.Type)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, nil, 0, fmt.Errorf("parseReflection: %v", err)
|
||||
}
|
||||
ublocks = append(ublocks, UniformLocation{
|
||||
// Synthetic name generated by glslcc.
|
||||
Name: fmt.Sprintf("_%d.%s", block.ID, member.Name),
|
||||
Type: dataType,
|
||||
Size: size,
|
||||
Offset: member.Offset,
|
||||
Offset: blockOffset + member.Offset,
|
||||
})
|
||||
}
|
||||
blockOffset += block.Size
|
||||
}
|
||||
return inputs, ublocks, nil
|
||||
return inputs, ublocks, blockOffset, nil
|
||||
}
|
||||
|
||||
func parseDataType(t string) (DataType, int, error) {
|
||||
|
||||
Reference in New Issue
Block a user