From 848e30e0e7b788db00d5aa0089cf90f2a2eeb269 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sat, 16 Nov 2024 18:53:47 +0900 Subject: [PATCH] internal/shaderlister: compile shaders Updates #3157 --- internal/shaderlister/main.go | 97 ++++++++++++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 1 deletion(-) diff --git a/internal/shaderlister/main.go b/internal/shaderlister/main.go index 60c10523a..dc3a79da0 100644 --- a/internal/shaderlister/main.go +++ b/internal/shaderlister/main.go @@ -30,8 +30,16 @@ import ( "golang.org/x/tools/go/ast/inspector" "golang.org/x/tools/go/packages" + + "github.com/hajimehoshi/ebiten/v2/internal/graphics" + "github.com/hajimehoshi/ebiten/v2/internal/shaderir/glsl" + "github.com/hajimehoshi/ebiten/v2/internal/shaderir/hlsl" + "github.com/hajimehoshi/ebiten/v2/internal/shaderir/msl" + "github.com/hajimehoshi/ebiten/v2/internal/shaderir/pssl" ) +var flagTarget = flag.String("target", "", "shader compilation targets separated by comma (e.g. 'glsl,glsles,hlsl,msl')") + func main() { if err := xmain(); err != nil { fmt.Fprintln(os.Stderr, err) @@ -43,11 +51,40 @@ type Shader struct { Package string File string Source string + GLSL *GLSL `json:",omitempty"` + GLSLES *GLSLES `json:",omitempty"` + HLSL *HLSL `json:",omitempty"` + MSL *MSL `json:",omitempty"` + PSSL *PSSL `json:",omitempty"` +} + +type GLSL struct { + Vertex string + Fragment string +} + +type GLSLES struct { + Vertex string + Fragment string +} + +type HLSL struct { + Vertex string + Pixel string +} + +type MSL struct { + Shader string +} + +type PSSL struct { + Vertex string + Pixel string } func xmain() error { flag.Usage = func() { - fmt.Fprintln(os.Stderr, "shaderlister [package]") + fmt.Fprintln(os.Stderr, "shaderlister [-target=TARGET] [package]") os.Exit(2) } flag.Parse() @@ -62,10 +99,16 @@ func xmain() error { return err } + targets := strings.Split(*flagTarget, ",") + for i := range targets { + targets[i] = strings.TrimSpace(targets[i]) + } + // Collect shader information. // Even if no shader is found, the output should be a JSON array. Start with an empty slice, not nil. shaders := []Shader{} + var visitErr error packages.Visit(pkgs, func(pkg *packages.Package) bool { path := pkg.PkgPath // A standard library should not have a directive for shaders. Skip them. @@ -76,9 +119,61 @@ func xmain() error { if strings.HasPrefix(path, "golang.org/x/") { return true } + + origN := len(shaders) shaders = appendShaderSources(shaders, pkg) + + // Compile shaders. + for i, shader := range shaders[origN:] { + ir, err := graphics.CompileShader([]byte(shader.Source)) + if err != nil { + visitErr = fmt.Errorf("compiling shader failed: %w", err) + return false + } + + for _, target := range targets { + switch target { + case "glsl": + vs, fs := glsl.Compile(ir, glsl.GLSLVersionDefault) + shaders[origN+i].GLSL = &GLSL{ + Vertex: vs, + Fragment: fs, + } + case "glsles": + vs, fs := glsl.Compile(ir, glsl.GLSLVersionES300) + shaders[origN+i].GLSLES = &GLSLES{ + Vertex: vs, + Fragment: fs, + } + case "hlsl": + vs, ps, _ := hlsl.Compile(ir) + shaders[origN+i].HLSL = &HLSL{ + Vertex: vs, + Pixel: ps, + } + case "msl": + s := msl.Compile(ir) + shaders[origN+i].MSL = &MSL{ + Shader: s, + } + case "pssl": + vs, ps := pssl.Compile(ir) + shaders[origN+i].PSSL = &PSSL{ + Vertex: vs, + Pixel: ps, + } + default: + visitErr = fmt.Errorf("unsupported target: %s", target) + return false + } + } + } + return true }, nil) + if visitErr != nil { + return visitErr + } w := bufio.NewWriter(os.Stdout) enc := json.NewEncoder(w)