From 4818768965f1bff39e6c12ecfe76afa05d8c38b5 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sun, 26 May 2024 22:58:12 +0900 Subject: [PATCH] shaderprecomp: remove `ShaderSourceID` `ShaderSourceID` was confusing as there was no guarantee the same ID is used for the same source if Ebitengine versions are different. `ShaderSource` should be kept as the built-in shader contents should not be exposed. Updates #2861 Closes #2999 --- examples/shaderprecomp/fxc/gen.go | 30 +++++++---------- examples/shaderprecomp/metallib/gen.go | 21 +++++------- examples/shaderprecomp/register_darwin.go | 10 ++---- examples/shaderprecomp/register_windows.go | 12 +++---- .../graphicsdriver/directx/shader_windows.go | 4 +-- .../graphicsdriver/metal/shader_darwin.go | 4 +-- .../playstation5/shader_paystation5.go | 6 +--- shaderprecomp/shaderprecomp.go | 33 ++----------------- shaderprecomp/shaderprecomp_darwin.go | 3 +- shaderprecomp/shaderprecomp_playstation5.go | 3 +- shaderprecomp/shaderprecomp_windows.go | 3 +- 11 files changed, 37 insertions(+), 92 deletions(-) diff --git a/examples/shaderprecomp/fxc/gen.go b/examples/shaderprecomp/fxc/gen.go index 7a6457469..4f7c4203f 100644 --- a/examples/shaderprecomp/fxc/gen.go +++ b/examples/shaderprecomp/fxc/gen.go @@ -40,7 +40,7 @@ func run() error { if errors.Is(err, exec.ErrNotFound) { fmt.Fprintln(os.Stderr, "fxc.exe not found. Please install Windows SDK.") fmt.Fprintln(os.Stderr, "See https://learn.microsoft.com/en-us/windows/win32/direct3dtools/fxc for more details.") - fmt.Fprintln(os.Stderr, "On PowerShell, you can add a path to the PATH environment variable temporarily like:") + fmt.Fprintln(os.Stderr, "HINT: On PowerShell, you can add a path to the PATH environment variable temporarily like:") fmt.Fprintln(os.Stderr) fmt.Fprintln(os.Stderr, ` & (Get-Process -Id $PID).Path { $env:PATH="C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64;"+$env:PATH; go generate .\examples\shaderprecomp\fxc\ }`) fmt.Fprintln(os.Stderr) @@ -61,33 +61,27 @@ func run() error { if err != nil { return err } - defaultSrc, err := shaderprecomp.NewShaderSource(defaultSrcBytes) - if err != nil { - return err - } - srcs = append(srcs, defaultSrc) + srcs = append(srcs, shaderprecomp.NewShaderSource(defaultSrcBytes)) - for _, src := range srcs { + for i, src := range srcs { // Avoid using errgroup.Group. // Compiling sources in parallel causes a mixed error message on the console. - if err := compile(src, tmpdir); err != nil { + if err := compile(src, i, tmpdir); err != nil { return err } } return nil } -func generateHSLSFiles(source *shaderprecomp.ShaderSource, tmpdir string) (vs, ps string, err error) { - id := source.ID().String() - - vsHLSLFilePath := filepath.Join(tmpdir, id+"_vs.hlsl") +func generateHSLSFiles(source *shaderprecomp.ShaderSource, index int, tmpdir string) (vs, ps string, err error) { + vsHLSLFilePath := filepath.Join(tmpdir, fmt.Sprintf("%d_vs.hlsl", index)) vsf, err := os.Create(vsHLSLFilePath) if err != nil { return "", "", err } defer vsf.Close() - psHLSLFilePath := filepath.Join(tmpdir, id+"_ps.hlsl") + psHLSLFilePath := filepath.Join(tmpdir, fmt.Sprintf("%d_ps.hlsl", index)) psf, err := os.Create(psHLSLFilePath) if err != nil { return "", "", err @@ -101,17 +95,15 @@ func generateHSLSFiles(source *shaderprecomp.ShaderSource, tmpdir string) (vs, p return vsHLSLFilePath, psHLSLFilePath, nil } -func compile(source *shaderprecomp.ShaderSource, tmpdir string) error { +func compile(source *shaderprecomp.ShaderSource, index int, tmpdir string) error { // Generate HLSL files. Make sure this process doesn't have any handlers of the files. // Without closing the files, fxc.exe cannot access the files. - vsHLSLFilePath, psHLSLFilePath, err := generateHSLSFiles(source, tmpdir) + vsHLSLFilePath, psHLSLFilePath, err := generateHSLSFiles(source, index, tmpdir) if err != nil { return err } - id := source.ID().String() - - vsFXCFilePath := id + "_vs.fxc" + vsFXCFilePath := fmt.Sprintf("%d_vs.fxc", index) cmd := exec.Command("fxc.exe", "/nologo", "/O3", "/T", shaderprecomp.HLSLVertexShaderProfile, "/E", shaderprecomp.HLSLVertexShaderEntryPoint, "/Fo", vsFXCFilePath, vsHLSLFilePath) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr @@ -119,7 +111,7 @@ func compile(source *shaderprecomp.ShaderSource, tmpdir string) error { return err } - psFXCFilePath := id + "_ps.fxc" + psFXCFilePath := fmt.Sprintf("%d_ps.fxc", index) cmd = exec.Command("fxc.exe", "/nologo", "/O3", "/T", shaderprecomp.HLSLPixelShaderProfile, "/E", shaderprecomp.HLSLPixelShaderEntryPoint, "/Fo", psFXCFilePath, psHLSLFilePath) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr diff --git a/examples/shaderprecomp/metallib/gen.go b/examples/shaderprecomp/metallib/gen.go index 1804c9da9..50264e8f2 100644 --- a/examples/shaderprecomp/metallib/gen.go +++ b/examples/shaderprecomp/metallib/gen.go @@ -20,6 +20,7 @@ package main import ( + "fmt" "os" "os/exec" "path/filepath" @@ -46,26 +47,20 @@ func run() error { if err != nil { return err } - defaultSrc, err := shaderprecomp.NewShaderSource(defaultSrcBytes) - if err != nil { - return err - } - srcs = append(srcs, defaultSrc) + srcs = append(srcs, shaderprecomp.NewShaderSource(defaultSrcBytes)) - for _, src := range srcs { + for i, src := range srcs { // Avoid using errgroup.Group. // Compiling sources in parallel causes a mixed error message on the console. - if err := compile(src, tmpdir); err != nil { + if err := compile(src, i, tmpdir); err != nil { return err } } return nil } -func compile(source *shaderprecomp.ShaderSource, tmpdir string) error { - id := source.ID().String() - - metalFilePath := filepath.Join(tmpdir, id+".metal") +func compile(source *shaderprecomp.ShaderSource, index int, tmpdir string) error { + metalFilePath := filepath.Join(tmpdir, fmt.Sprintf("%d.metal", index)) f, err := os.Create(metalFilePath) if err != nil { @@ -80,14 +75,14 @@ func compile(source *shaderprecomp.ShaderSource, tmpdir string) error { return err } - irFilePath := filepath.Join(tmpdir, id+".ir") + irFilePath := filepath.Join(tmpdir, fmt.Sprintf("%d.ir", index)) cmd := exec.Command("xcrun", "-sdk", "macosx", "metal", "-o", irFilePath, "-c", metalFilePath) cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { return err } - metallibFilePath := id + ".metallib" + metallibFilePath := fmt.Sprintf("%d.metallib", index) cmd = exec.Command("xcrun", "-sdk", "macosx", "metallib", "-o", metallibFilePath, irFilePath) cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { diff --git a/examples/shaderprecomp/register_darwin.go b/examples/shaderprecomp/register_darwin.go index b5b250cfd..c2fcb0902 100644 --- a/examples/shaderprecomp/register_darwin.go +++ b/examples/shaderprecomp/register_darwin.go @@ -29,14 +29,10 @@ var metallibs embed.FS func registerPrecompiledShaders() error { srcs := shaderprecomp.AppendBuildinShaderSources(nil) - defaultShaderSource, err := shaderprecomp.NewShaderSource(defaultShaderSourceBytes) - if err != nil { - return err - } - srcs = append(srcs, defaultShaderSource) + srcs = append(srcs, shaderprecomp.NewShaderSource(defaultShaderSourceBytes)) - for _, src := range srcs { - name := src.ID().String() + ".metallib" + for i, src := range srcs { + name := fmt.Sprintf("%d.metallib", i) lib, err := metallibs.ReadFile("metallib/" + name) if err != nil { if errors.Is(err, fs.ErrNotExist) { diff --git a/examples/shaderprecomp/register_windows.go b/examples/shaderprecomp/register_windows.go index 34ac7437a..f27b84ecf 100644 --- a/examples/shaderprecomp/register_windows.go +++ b/examples/shaderprecomp/register_windows.go @@ -31,14 +31,10 @@ var fxcs embed.FS func registerPrecompiledShaders() error { srcs := shaderprecomp.AppendBuildinShaderSources(nil) - defaultShaderSource, err := shaderprecomp.NewShaderSource(defaultShaderSourceBytes) - if err != nil { - return err - } - srcs = append(srcs, defaultShaderSource) + srcs = append(srcs, shaderprecomp.NewShaderSource(defaultShaderSourceBytes)) - for _, src := range srcs { - vsname := src.ID().String() + "_vs.fxc" + for i, src := range srcs { + vsname := fmt.Sprintf("%d_vs.fxc", i) vs, err := fxcs.ReadFile("fxc/" + vsname) if err != nil { if errors.Is(err, fs.ErrNotExist) { @@ -48,7 +44,7 @@ func registerPrecompiledShaders() error { return err } - psname := src.ID().String() + "_ps.fxc" + psname := fmt.Sprintf("%d_ps.fxc", i) ps, err := fxcs.ReadFile("fxc/" + psname) if err != nil { if errors.Is(err, fs.ErrNotExist) { diff --git a/internal/graphicsdriver/directx/shader_windows.go b/internal/graphicsdriver/directx/shader_windows.go index 172ec1638..311567659 100644 --- a/internal/graphicsdriver/directx/shader_windows.go +++ b/internal/graphicsdriver/directx/shader_windows.go @@ -70,8 +70,8 @@ func (c *precompiledFXCs) get(hash shaderir.SourceHash) ([]byte, []byte) { var thePrecompiledFXCs precompiledFXCs -func RegisterPrecompiledFXCs(hash shaderir.SourceHash, vertex, pixel []byte) { - thePrecompiledFXCs.put(hash, vertex, pixel) +func RegisterPrecompiledFXCs(source []byte, vertex, pixel []byte) { + thePrecompiledFXCs.put(shaderir.CalcSourceHash(source), vertex, pixel) } var vertexShaderCache = map[string]*_ID3DBlob{} diff --git a/internal/graphicsdriver/metal/shader_darwin.go b/internal/graphicsdriver/metal/shader_darwin.go index 2ec9c9934..dce5ebc8a 100644 --- a/internal/graphicsdriver/metal/shader_darwin.go +++ b/internal/graphicsdriver/metal/shader_darwin.go @@ -51,8 +51,8 @@ func (c *precompiledLibraries) get(hash shaderir.SourceHash) []byte { var thePrecompiledLibraries precompiledLibraries -func RegisterPrecompiledLibrary(hash shaderir.SourceHash, bin []byte) { - thePrecompiledLibraries.put(hash, bin) +func RegisterPrecompiledLibrary(source []byte, bin []byte) { + thePrecompiledLibraries.put(shaderir.CalcSourceHash(source), bin) } type shaderRpsKey struct { diff --git a/internal/graphicsdriver/playstation5/shader_paystation5.go b/internal/graphicsdriver/playstation5/shader_paystation5.go index 8128f874c..c4c9ef1e5 100644 --- a/internal/graphicsdriver/playstation5/shader_paystation5.go +++ b/internal/graphicsdriver/playstation5/shader_paystation5.go @@ -18,10 +18,6 @@ package playstation5 -import ( - "github.com/hajimehoshi/ebiten/v2/internal/shaderir" -) - -func RegisterPrecompiledShaders(hash shaderir.SourceHash, vertex, pixel []byte) { +func RegisterPrecompiledShaders(source []byte, vertex, pixel []byte) { // TODO: Implement this. } diff --git a/shaderprecomp/shaderprecomp.go b/shaderprecomp/shaderprecomp.go index 650ebc1b5..94eb0b408 100644 --- a/shaderprecomp/shaderprecomp.go +++ b/shaderprecomp/shaderprecomp.go @@ -16,8 +16,6 @@ package shaderprecomp import ( "github.com/hajimehoshi/ebiten/v2/internal/builtinshader" - "github.com/hajimehoshi/ebiten/v2/internal/graphics" - "github.com/hajimehoshi/ebiten/v2/internal/shaderir" ) // AppendBuildinShaderSources appends all the built-in shader sources to the given slice. @@ -27,11 +25,7 @@ import ( // AppendBuildinShaderSources is concurrent-safe. func AppendBuildinShaderSources(sources []*ShaderSource) []*ShaderSource { for _, s := range builtinshader.AppendShaderSources(nil) { - src, err := NewShaderSource(s) - if err != nil { - panic(err) - } - sources = append(sources, src) + sources = append(sources, NewShaderSource(s)) } return sources } @@ -39,32 +33,11 @@ func AppendBuildinShaderSources(sources []*ShaderSource) []*ShaderSource { // ShaderSource is an object encapsulating a shader source code. type ShaderSource struct { source []byte - id ShaderSourceID } // NewShaderSource creates a new ShaderSource object from the given source code. -func NewShaderSource(source []byte) (*ShaderSource, error) { - hash, err := graphics.CalcSourceHash(source) - if err != nil { - return nil, err - } +func NewShaderSource(source []byte) *ShaderSource { return &ShaderSource{ source: source, - id: ShaderSourceID(hash), - }, nil -} - -// ID returns a unique identifier for the shader source. -// The ShaderSourceID value must be the same for the same shader source and the same Ebitengine version. -// There is no guarantee that the ShaderSourceID value is the same between different Ebitengine versions. -func (s *ShaderSource) ID() ShaderSourceID { - return s.id -} - -// ShaderSourceID is a uniuqe identifier for a shader source. -type ShaderSourceID [16]byte - -// String returns a string representation of the shader source ID. -func (s ShaderSourceID) String() string { - return shaderir.SourceHash(s).String() + } } diff --git a/shaderprecomp/shaderprecomp_darwin.go b/shaderprecomp/shaderprecomp_darwin.go index b795ba685..51bb06843 100644 --- a/shaderprecomp/shaderprecomp_darwin.go +++ b/shaderprecomp/shaderprecomp_darwin.go @@ -21,7 +21,6 @@ import ( "github.com/hajimehoshi/ebiten/v2/internal/graphics" "github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/metal" - "github.com/hajimehoshi/ebiten/v2/internal/shaderir" "github.com/hajimehoshi/ebiten/v2/internal/shaderir/msl" ) @@ -45,5 +44,5 @@ func CompileToMSL(w io.Writer, source *ShaderSource) error { // // RegisterMetalLibrary is concurrent-safe. func RegisterMetalLibrary(source *ShaderSource, library []byte) { - metal.RegisterPrecompiledLibrary(shaderir.SourceHash(source.ID()), library) + metal.RegisterPrecompiledLibrary(source.source, library) } diff --git a/shaderprecomp/shaderprecomp_playstation5.go b/shaderprecomp/shaderprecomp_playstation5.go index 102ed5b0c..71229a048 100644 --- a/shaderprecomp/shaderprecomp_playstation5.go +++ b/shaderprecomp/shaderprecomp_playstation5.go @@ -21,7 +21,6 @@ import ( "github.com/hajimehoshi/ebiten/v2/internal/graphics" "github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/playstation5" - "github.com/hajimehoshi/ebiten/v2/internal/shaderir" "github.com/hajimehoshi/ebiten/v2/internal/shaderir/pssl" ) @@ -47,5 +46,5 @@ func CompileToPSSL(vertexWriter, pixelWriter io.Writer, source *ShaderSource) er // // RegisterPlayStationShaders is concurrent-safe. func RegisterPlayStationShaders(source *ShaderSource, vertexShader, pixelShader []byte) { - playstation5.RegisterPrecompiledShaders(shaderir.SourceHash(source.ID()), vertexShader, pixelShader) + playstation5.RegisterPrecompiledShaders(source.source, vertexShader, pixelShader) } diff --git a/shaderprecomp/shaderprecomp_windows.go b/shaderprecomp/shaderprecomp_windows.go index 27c9de404..19121e5c6 100644 --- a/shaderprecomp/shaderprecomp_windows.go +++ b/shaderprecomp/shaderprecomp_windows.go @@ -21,7 +21,6 @@ import ( "github.com/hajimehoshi/ebiten/v2/internal/graphics" "github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/directx" - "github.com/hajimehoshi/ebiten/v2/internal/shaderir" "github.com/hajimehoshi/ebiten/v2/internal/shaderir/hlsl" ) @@ -63,5 +62,5 @@ func CompileToHLSL(vertexWriter, pixelWriter io.Writer, source *ShaderSource) er // // RegisterFXCs is concurrent-safe. func RegisterFXCs(source *ShaderSource, vertexFXC, pixelFXC []byte) { - directx.RegisterPrecompiledFXCs(shaderir.SourceHash(source.ID()), vertexFXC, pixelFXC) + directx.RegisterPrecompiledFXCs(source.source, vertexFXC, pixelFXC) }