mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
shaderprecomp: remove ShaderSource
and ShaderSourceID
This change simplifies the APIs to avoid some confusions around IDs. Updates #2861 Closes #2999
This commit is contained in:
parent
3279688dd6
commit
8be3bb41d5
@ -20,8 +20,10 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"hash/fnv"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@ -57,11 +59,7 @@ func run() error {
|
|||||||
|
|
||||||
srcs := shaderprecomp.AppendBuildinShaderSources(nil)
|
srcs := shaderprecomp.AppendBuildinShaderSources(nil)
|
||||||
|
|
||||||
defaultSrcBytes, err := os.ReadFile(filepath.Join("..", "defaultshader.go"))
|
defaultSrc, err := os.ReadFile(filepath.Join("..", "defaultshader.go"))
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defaultSrc, err := shaderprecomp.NewShaderSource(defaultSrcBytes)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -77,9 +75,7 @@ func run() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateHSLSFiles(source *shaderprecomp.ShaderSource, tmpdir string) (vs, ps string, err error) {
|
func generateHSLSFiles(source []byte, id string, tmpdir string) (vs, ps string, err error) {
|
||||||
id := source.ID().String()
|
|
||||||
|
|
||||||
vsHLSLFilePath := filepath.Join(tmpdir, id+"_vs.hlsl")
|
vsHLSLFilePath := filepath.Join(tmpdir, id+"_vs.hlsl")
|
||||||
vsf, err := os.Create(vsHLSLFilePath)
|
vsf, err := os.Create(vsHLSLFilePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -101,16 +97,18 @@ func generateHSLSFiles(source *shaderprecomp.ShaderSource, tmpdir string) (vs, p
|
|||||||
return vsHLSLFilePath, psHLSLFilePath, nil
|
return vsHLSLFilePath, psHLSLFilePath, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func compile(source *shaderprecomp.ShaderSource, tmpdir string) error {
|
func compile(kageSource []byte, tmpdir string) error {
|
||||||
|
h := fnv.New32()
|
||||||
|
_, _ = h.Write(kageSource)
|
||||||
|
id := hex.EncodeToString(h.Sum(nil))
|
||||||
|
|
||||||
// Generate HLSL files. Make sure this process doesn't have any handlers of the files.
|
// 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.
|
// Without closing the files, fxc.exe cannot access the files.
|
||||||
vsHLSLFilePath, psHLSLFilePath, err := generateHSLSFiles(source, tmpdir)
|
vsHLSLFilePath, psHLSLFilePath, err := generateHSLSFiles(kageSource, id, tmpdir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
id := source.ID().String()
|
|
||||||
|
|
||||||
vsFXCFilePath := id + "_vs.fxc"
|
vsFXCFilePath := id + "_vs.fxc"
|
||||||
cmd := exec.Command("fxc.exe", "/nologo", "/O3", "/T", shaderprecomp.HLSLVertexShaderProfile, "/E", shaderprecomp.HLSLVertexShaderEntryPoint, "/Fo", vsFXCFilePath, vsHLSLFilePath)
|
cmd := exec.Command("fxc.exe", "/nologo", "/O3", "/T", shaderprecomp.HLSLVertexShaderProfile, "/E", shaderprecomp.HLSLVertexShaderEntryPoint, "/Fo", vsFXCFilePath, vsHLSLFilePath)
|
||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/hex"
|
||||||
|
"hash/fnv"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@ -42,11 +44,7 @@ func run() error {
|
|||||||
|
|
||||||
srcs := shaderprecomp.AppendBuildinShaderSources(nil)
|
srcs := shaderprecomp.AppendBuildinShaderSources(nil)
|
||||||
|
|
||||||
defaultSrcBytes, err := os.ReadFile(filepath.Join("..", "defaultshader.go"))
|
defaultSrc, err := os.ReadFile(filepath.Join("..", "defaultshader.go"))
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defaultSrc, err := shaderprecomp.NewShaderSource(defaultSrcBytes)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -62,8 +60,10 @@ func run() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func compile(source *shaderprecomp.ShaderSource, tmpdir string) error {
|
func compile(kageSource []byte, tmpdir string) error {
|
||||||
id := source.ID().String()
|
h := fnv.New32()
|
||||||
|
_, _ = h.Write(kageSource)
|
||||||
|
id := hex.EncodeToString(h.Sum(nil))
|
||||||
|
|
||||||
metalFilePath := filepath.Join(tmpdir, id+".metal")
|
metalFilePath := filepath.Join(tmpdir, id+".metal")
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ func compile(source *shaderprecomp.ShaderSource, tmpdir string) error {
|
|||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
if err := shaderprecomp.CompileToMSL(f, source); err != nil {
|
if err := shaderprecomp.CompileToMSL(f, kageSource); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := f.Sync(); err != nil {
|
if err := f.Sync(); err != nil {
|
||||||
|
@ -16,8 +16,10 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"embed"
|
"embed"
|
||||||
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"hash/fnv"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
@ -29,14 +31,16 @@ var metallibs embed.FS
|
|||||||
|
|
||||||
func registerPrecompiledShaders() error {
|
func registerPrecompiledShaders() error {
|
||||||
srcs := shaderprecomp.AppendBuildinShaderSources(nil)
|
srcs := shaderprecomp.AppendBuildinShaderSources(nil)
|
||||||
defaultShaderSource, err := shaderprecomp.NewShaderSource(defaultShaderSourceBytes)
|
srcs = append(srcs, defaultShaderSourceBytes)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
srcs = append(srcs, defaultShaderSource)
|
|
||||||
|
|
||||||
for _, src := range srcs {
|
for _, src := range srcs {
|
||||||
name := src.ID().String() + ".metallib"
|
// Calculate the hash of the source code to identify the Metal library.
|
||||||
|
// FNV is used as it is fast and the hash does not need to be secure.
|
||||||
|
h := fnv.New32()
|
||||||
|
_, _ = h.Write(src)
|
||||||
|
id := hex.EncodeToString(h.Sum(nil))
|
||||||
|
|
||||||
|
name := id + ".metallib"
|
||||||
lib, err := metallibs.ReadFile("metallib/" + name)
|
lib, err := metallibs.ReadFile("metallib/" + name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, fs.ErrNotExist) {
|
if errors.Is(err, fs.ErrNotExist) {
|
||||||
|
@ -16,8 +16,10 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"embed"
|
"embed"
|
||||||
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"hash/fnv"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
@ -31,14 +33,16 @@ var fxcs embed.FS
|
|||||||
|
|
||||||
func registerPrecompiledShaders() error {
|
func registerPrecompiledShaders() error {
|
||||||
srcs := shaderprecomp.AppendBuildinShaderSources(nil)
|
srcs := shaderprecomp.AppendBuildinShaderSources(nil)
|
||||||
defaultShaderSource, err := shaderprecomp.NewShaderSource(defaultShaderSourceBytes)
|
srcs = append(srcs, defaultShaderSourceBytes)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
srcs = append(srcs, defaultShaderSource)
|
|
||||||
|
|
||||||
for _, src := range srcs {
|
for _, src := range srcs {
|
||||||
vsname := src.ID().String() + "_vs.fxc"
|
// Calculate the hash of the source code to identify the Metal library.
|
||||||
|
// FNV is used as it is fast and the hash does not need to be secure.
|
||||||
|
h := fnv.New32()
|
||||||
|
_, _ = h.Write(src)
|
||||||
|
id := hex.EncodeToString(h.Sum(nil))
|
||||||
|
|
||||||
|
vsname := id + "_vs.fxc"
|
||||||
vs, err := fxcs.ReadFile("fxc/" + vsname)
|
vs, err := fxcs.ReadFile("fxc/" + vsname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, fs.ErrNotExist) {
|
if errors.Is(err, fs.ErrNotExist) {
|
||||||
@ -48,7 +52,7 @@ func registerPrecompiledShaders() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
psname := src.ID().String() + "_ps.fxc"
|
psname := id + "_ps.fxc"
|
||||||
ps, err := fxcs.ReadFile("fxc/" + psname)
|
ps, err := fxcs.ReadFile("fxc/" + psname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, fs.ErrNotExist) {
|
if errors.Is(err, fs.ErrNotExist) {
|
||||||
|
@ -70,8 +70,8 @@ func (c *precompiledFXCs) get(hash shaderir.SourceHash) ([]byte, []byte) {
|
|||||||
|
|
||||||
var thePrecompiledFXCs precompiledFXCs
|
var thePrecompiledFXCs precompiledFXCs
|
||||||
|
|
||||||
func RegisterPrecompiledFXCs(hash shaderir.SourceHash, vertex, pixel []byte) {
|
func RegisterPrecompiledFXCs(kageSource []byte, vertex, pixel []byte) {
|
||||||
thePrecompiledFXCs.put(hash, vertex, pixel)
|
thePrecompiledFXCs.put(shaderir.CalcSourceHash(kageSource), vertex, pixel)
|
||||||
}
|
}
|
||||||
|
|
||||||
var vertexShaderCache = map[string]*_ID3DBlob{}
|
var vertexShaderCache = map[string]*_ID3DBlob{}
|
||||||
|
@ -51,8 +51,8 @@ func (c *precompiledLibraries) get(hash shaderir.SourceHash) []byte {
|
|||||||
|
|
||||||
var thePrecompiledLibraries precompiledLibraries
|
var thePrecompiledLibraries precompiledLibraries
|
||||||
|
|
||||||
func RegisterPrecompiledLibrary(hash shaderir.SourceHash, bin []byte) {
|
func RegisterPrecompiledLibrary(kageSource []byte, bin []byte) {
|
||||||
thePrecompiledLibraries.put(hash, bin)
|
thePrecompiledLibraries.put(shaderir.CalcSourceHash(kageSource), bin)
|
||||||
}
|
}
|
||||||
|
|
||||||
type shaderRpsKey struct {
|
type shaderRpsKey struct {
|
||||||
|
@ -16,8 +16,6 @@ package shaderprecomp
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/builtinshader"
|
"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.
|
// AppendBuildinShaderSources appends all the built-in shader sources to the given slice.
|
||||||
@ -25,46 +23,6 @@ import (
|
|||||||
// Do not modify the content of the shader source.
|
// Do not modify the content of the shader source.
|
||||||
//
|
//
|
||||||
// AppendBuildinShaderSources is concurrent-safe.
|
// AppendBuildinShaderSources is concurrent-safe.
|
||||||
func AppendBuildinShaderSources(sources []*ShaderSource) []*ShaderSource {
|
func AppendBuildinShaderSources(sources [][]byte) [][]byte {
|
||||||
for _, s := range builtinshader.AppendShaderSources(nil) {
|
return builtinshader.AppendShaderSources(sources)
|
||||||
src, err := NewShaderSource(s)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
sources = append(sources, src)
|
|
||||||
}
|
|
||||||
return sources
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
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()
|
|
||||||
}
|
}
|
||||||
|
@ -21,15 +21,14 @@ import (
|
|||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
|
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/metal"
|
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/metal"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/shaderir"
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/shaderir/msl"
|
"github.com/hajimehoshi/ebiten/v2/internal/shaderir/msl"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CompileToMSL compiles the shader source to Metal Shader Language, and writes the result to w.
|
// CompileToMSL compiles the shader source to Metal Shader Language, and writes the result to w.
|
||||||
//
|
//
|
||||||
// CompileToMSL is concurrent-safe.
|
// CompileToMSL is concurrent-safe.
|
||||||
func CompileToMSL(w io.Writer, source *ShaderSource) error {
|
func CompileToMSL(w io.Writer, kageSource []byte) error {
|
||||||
ir, err := graphics.CompileShader(source.source)
|
ir, err := graphics.CompileShader(kageSource)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -44,6 +43,6 @@ func CompileToMSL(w io.Writer, source *ShaderSource) error {
|
|||||||
// For more details, see https://developer.apple.com/documentation/metal/shader_libraries/building_a_shader_library_by_precompiling_source_files.
|
// For more details, see https://developer.apple.com/documentation/metal/shader_libraries/building_a_shader_library_by_precompiling_source_files.
|
||||||
//
|
//
|
||||||
// RegisterMetalLibrary is concurrent-safe.
|
// RegisterMetalLibrary is concurrent-safe.
|
||||||
func RegisterMetalLibrary(source *ShaderSource, library []byte) {
|
func RegisterMetalLibrary(kageSource []byte, library []byte) {
|
||||||
metal.RegisterPrecompiledLibrary(shaderir.SourceHash(source.ID()), library)
|
metal.RegisterPrecompiledLibrary(kageSource, library)
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,6 @@ import (
|
|||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
|
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/directx"
|
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/directx"
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/shaderir"
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/shaderir/hlsl"
|
"github.com/hajimehoshi/ebiten/v2/internal/shaderir/hlsl"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -42,8 +41,8 @@ const (
|
|||||||
// CompileToHLSL compiles the shader source to High-Level Shader Language to writers.
|
// CompileToHLSL compiles the shader source to High-Level Shader Language to writers.
|
||||||
//
|
//
|
||||||
// CompileToHLSL is concurrent-safe.
|
// CompileToHLSL is concurrent-safe.
|
||||||
func CompileToHLSL(vertexWriter, pixelWriter io.Writer, source *ShaderSource) error {
|
func CompileToHLSL(vertexWriter, pixelWriter io.Writer, kageSource []byte) error {
|
||||||
ir, err := graphics.CompileShader(source.source)
|
ir, err := graphics.CompileShader(kageSource)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -62,6 +61,6 @@ func CompileToHLSL(vertexWriter, pixelWriter io.Writer, source *ShaderSource) er
|
|||||||
// For more details, see https://learn.microsoft.com/en-us/windows/win32/direct3dtools/dx-graphics-tools-fxc-using.
|
// For more details, see https://learn.microsoft.com/en-us/windows/win32/direct3dtools/dx-graphics-tools-fxc-using.
|
||||||
//
|
//
|
||||||
// RegisterFXCs is concurrent-safe.
|
// RegisterFXCs is concurrent-safe.
|
||||||
func RegisterFXCs(source *ShaderSource, vertexFXC, pixelFXC []byte) {
|
func RegisterFXCs(kageSource []byte, vertexFXC, pixelFXC []byte) {
|
||||||
directx.RegisterPrecompiledFXCs(shaderir.SourceHash(source.ID()), vertexFXC, pixelFXC)
|
directx.RegisterPrecompiledFXCs(kageSource, vertexFXC, pixelFXC)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user