mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-09 20:47:26 +01:00
parent
5d4a68b0ea
commit
10d9660125
2
.gitignore
vendored
2
.gitignore
vendored
@ -8,5 +8,7 @@
|
|||||||
go.work
|
go.work
|
||||||
go.work.sum
|
go.work.sum
|
||||||
|
|
||||||
|
*.fxc
|
||||||
|
!dummy.fxc
|
||||||
*.metallib
|
*.metallib
|
||||||
!dummy.metallib
|
!dummy.metallib
|
||||||
|
1
examples/shaderprecomp/fxc/dummy.fxc
Normal file
1
examples/shaderprecomp/fxc/dummy.fxc
Normal file
@ -0,0 +1 @@
|
|||||||
|
This is a dummy .fxc file to trick Go's embed package.
|
130
examples/shaderprecomp/fxc/gen.go
Normal file
130
examples/shaderprecomp/fxc/gen.go
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
// Copyright 2024 The Ebitengine Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
//go:build ignore
|
||||||
|
|
||||||
|
// This is a program to generate precompiled HLSL blobs (FXC files).
|
||||||
|
//
|
||||||
|
// See https://learn.microsoft.com/en-us/windows/win32/direct3dtools/fxc.
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/shaderprecomp"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if err := run(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func run() error {
|
||||||
|
if _, err := exec.LookPath("fxc.exe"); err != nil {
|
||||||
|
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)
|
||||||
|
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)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpdir, err := os.MkdirTemp("", "")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
|
srcs := shaderprecomp.AppendBuildinShaderSources(nil)
|
||||||
|
|
||||||
|
defaultSrcBytes, err := os.ReadFile(filepath.Join("..", "defaultshader.go"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defaultSrc, err := shaderprecomp.NewShaderSource(defaultSrcBytes)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
srcs = append(srcs, defaultSrc)
|
||||||
|
|
||||||
|
for _, src := range srcs {
|
||||||
|
// Compiling sources in parallel causes a mixed error message on the console.
|
||||||
|
if err := compile(src, 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")
|
||||||
|
vsf, err := os.Create(vsHLSLFilePath)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
defer vsf.Close()
|
||||||
|
|
||||||
|
psHLSLFilePath := filepath.Join(tmpdir, id+"_ps.hlsl")
|
||||||
|
psf, err := os.Create(psHLSLFilePath)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
defer psf.Close()
|
||||||
|
|
||||||
|
if err := shaderprecomp.CompileToHLSL(vsf, psf, source); err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return vsHLSLFilePath, psHLSLFilePath, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func compile(source *shaderprecomp.ShaderSource, 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)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
id := source.ID().String()
|
||||||
|
|
||||||
|
vsFXCFilePath := id + "_vs.fxc"
|
||||||
|
cmd := exec.Command("fxc.exe", "/nologo", "/O3", "/T", shaderprecomp.HLSLVertexShaderProfile, "/E", shaderprecomp.HLSLVertexShaderEntryPoint, "/Fo", vsFXCFilePath, vsHLSLFilePath)
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
psFXCFilePath := id + "_ps.fxc"
|
||||||
|
cmd = exec.Command("fxc.exe", "/nologo", "/O3", "/T", shaderprecomp.HLSLPixelShaderProfile, "/E", shaderprecomp.HLSLPixelShaderEntryPoint, "/Fo", psFXCFilePath, psHLSLFilePath)
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
17
examples/shaderprecomp/fxc/generate.go
Normal file
17
examples/shaderprecomp/fxc/generate.go
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2024 The Ebitengine Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
//go:generate go run gen.go
|
||||||
|
|
||||||
|
package fxc
|
@ -67,6 +67,7 @@ func main() {
|
|||||||
if err := registerPrecompiledShaders(); err != nil {
|
if err := registerPrecompiledShaders(); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
ebiten.SetWindowTitle("Ebitengine Example (Shader Precompilation)")
|
||||||
if err := ebiten.RunGame(&Game{}); err != nil {
|
if err := ebiten.RunGame(&Game{}); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
//go:build !darwin
|
//go:build !darwin && !windows
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
65
examples/shaderprecomp/register_windows.go
Normal file
65
examples/shaderprecomp/register_windows.go
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
// Copyright 2024 The Ebitengine Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"embed"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io/fs"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/hajimehoshi/ebiten/v2/shaderprecomp"
|
||||||
|
)
|
||||||
|
|
||||||
|
// https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/
|
||||||
|
|
||||||
|
//go:embed fxc/*.fxc
|
||||||
|
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)
|
||||||
|
|
||||||
|
for _, src := range srcs {
|
||||||
|
vsname := src.ID().String() + "_vs.fxc"
|
||||||
|
vs, err := fxcs.ReadFile("fxc/" + vsname)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, fs.ErrNotExist) {
|
||||||
|
fmt.Fprintf(os.Stderr, "precompiled HLSL library %s was not found. Run 'go generate' for 'fxc' directory to generate them.\n", vsname)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
psname := src.ID().String() + "_ps.fxc"
|
||||||
|
ps, err := fxcs.ReadFile("fxc/" + psname)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, fs.ErrNotExist) {
|
||||||
|
fmt.Fprintf(os.Stderr, "precompiled HLSL library %s was not found. Run 'go generate' for 'fxc' directory to generate them.\n", psname)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
shaderprecomp.RegisterFXCs(src, vs, ps)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
@ -72,6 +72,7 @@ const (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
procD3DCompile *windows.LazyProc
|
procD3DCompile *windows.LazyProc
|
||||||
|
procD3DCreateBlob *windows.LazyProc
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -93,6 +94,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
procD3DCompile = d3dcompiler.NewProc("D3DCompile")
|
procD3DCompile = d3dcompiler.NewProc("D3DCompile")
|
||||||
|
procD3DCreateBlob = d3dcompiler.NewProc("D3DCreateBlob")
|
||||||
}
|
}
|
||||||
|
|
||||||
func isD3DCompilerDLLAvailable() bool {
|
func isD3DCompilerDLLAvailable() bool {
|
||||||
@ -135,6 +137,19 @@ func _D3DCompile(srcData []byte, sourceName string, pDefines []_D3D_SHADER_MACRO
|
|||||||
return code, nil
|
return code, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func _D3DCreateBlob(size uint) (*_ID3DBlob, error) {
|
||||||
|
if !isD3DCompilerDLLAvailable() {
|
||||||
|
return nil, fmt.Errorf("directx: d3dcompiler_*.dll is missing in this environment")
|
||||||
|
}
|
||||||
|
|
||||||
|
var blob *_ID3DBlob
|
||||||
|
r, _, _ := procD3DCreateBlob.Call(uintptr(size), uintptr(unsafe.Pointer(&blob)))
|
||||||
|
if uint32(r) != uint32(windows.S_OK) {
|
||||||
|
return nil, fmt.Errorf("directx: D3DCreateBlob failed: %w", handleError(windows.Handle(uint32(r))))
|
||||||
|
}
|
||||||
|
return blob, nil
|
||||||
|
}
|
||||||
|
|
||||||
type _D3D_SHADER_MACRO struct {
|
type _D3D_SHADER_MACRO struct {
|
||||||
Name *byte
|
Name *byte
|
||||||
Definition *byte
|
Definition *byte
|
||||||
|
@ -16,6 +16,8 @@ package directx
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
|
|
||||||
@ -24,12 +26,57 @@ import (
|
|||||||
"github.com/hajimehoshi/ebiten/v2/internal/shaderir/hlsl"
|
"github.com/hajimehoshi/ebiten/v2/internal/shaderir/hlsl"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
VertexShaderProfile = "vs_4_0"
|
||||||
|
PixelShaderProfile = "ps_4_0"
|
||||||
|
|
||||||
|
VertexShaderEntryPoint = "VSMain"
|
||||||
|
PixelShaderEntryPoint = "PSMain"
|
||||||
|
)
|
||||||
|
|
||||||
|
type fxcPair struct {
|
||||||
|
vertex []byte
|
||||||
|
pixel []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
type precompiledFXCs struct {
|
||||||
|
binaries map[shaderir.SourceHash]fxcPair
|
||||||
|
m sync.Mutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *precompiledFXCs) put(hash shaderir.SourceHash, vertex, pixel []byte) {
|
||||||
|
c.m.Lock()
|
||||||
|
defer c.m.Unlock()
|
||||||
|
|
||||||
|
if c.binaries == nil {
|
||||||
|
c.binaries = map[shaderir.SourceHash]fxcPair{}
|
||||||
|
}
|
||||||
|
if _, ok := c.binaries[hash]; ok {
|
||||||
|
panic(fmt.Sprintf("directx: the precompiled library for the hash %s is already registered", hash.String()))
|
||||||
|
}
|
||||||
|
c.binaries[hash] = fxcPair{
|
||||||
|
vertex: vertex,
|
||||||
|
pixel: pixel,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *precompiledFXCs) get(hash shaderir.SourceHash) ([]byte, []byte) {
|
||||||
|
c.m.Lock()
|
||||||
|
defer c.m.Unlock()
|
||||||
|
|
||||||
|
f := c.binaries[hash]
|
||||||
|
return f.vertex, f.pixel
|
||||||
|
}
|
||||||
|
|
||||||
|
var thePrecompiledFXCs precompiledFXCs
|
||||||
|
|
||||||
|
func RegisterPrecompiledFXCs(hash shaderir.SourceHash, vertex, pixel []byte) {
|
||||||
|
thePrecompiledFXCs.put(hash, vertex, pixel)
|
||||||
|
}
|
||||||
|
|
||||||
var vertexShaderCache = map[string]*_ID3DBlob{}
|
var vertexShaderCache = map[string]*_ID3DBlob{}
|
||||||
|
|
||||||
func compileShader(program *shaderir.Program) (vsh, psh *_ID3DBlob, ferr error) {
|
func compileShader(program *shaderir.Program) (vsh, psh *_ID3DBlob, ferr error) {
|
||||||
vs, ps := hlsl.Compile(program)
|
|
||||||
var flag uint32 = uint32(_D3DCOMPILE_OPTIMIZATION_LEVEL3)
|
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if ferr == nil {
|
if ferr == nil {
|
||||||
return
|
return
|
||||||
@ -42,6 +89,22 @@ func compileShader(program *shaderir.Program) (vsh, psh *_ID3DBlob, ferr error)
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
if vshBin, pshBin := thePrecompiledFXCs.get(program.SourceHash); vshBin != nil && pshBin != nil {
|
||||||
|
var err error
|
||||||
|
if vsh, err = _D3DCreateBlob(uint(len(vshBin))); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if psh, err = _D3DCreateBlob(uint(len(pshBin))); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
copy(unsafe.Slice((*byte)(vsh.GetBufferPointer()), vsh.GetBufferSize()), vshBin)
|
||||||
|
copy(unsafe.Slice((*byte)(psh.GetBufferPointer()), psh.GetBufferSize()), pshBin)
|
||||||
|
return vsh, psh, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
vs, ps := hlsl.Compile(program)
|
||||||
|
var flag uint32 = uint32(_D3DCOMPILE_OPTIMIZATION_LEVEL3)
|
||||||
|
|
||||||
var wg errgroup.Group
|
var wg errgroup.Group
|
||||||
|
|
||||||
// Vertex shaders are likely the same. If so, reuse the same _ID3DBlob.
|
// Vertex shaders are likely the same. If so, reuse the same _ID3DBlob.
|
||||||
@ -58,7 +121,7 @@ func compileShader(program *shaderir.Program) (vsh, psh *_ID3DBlob, ferr error)
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
wg.Go(func() error {
|
wg.Go(func() error {
|
||||||
v, err := _D3DCompile([]byte(vs), "shader", nil, nil, "VSMain", "vs_4_0", flag, 0)
|
v, err := _D3DCompile([]byte(vs), "shader", nil, nil, VertexShaderEntryPoint, VertexShaderProfile, flag, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("directx: D3DCompile for VSMain failed, original source: %s, %w", vs, err)
|
return fmt.Errorf("directx: D3DCompile for VSMain failed, original source: %s, %w", vs, err)
|
||||||
}
|
}
|
||||||
@ -67,7 +130,7 @@ func compileShader(program *shaderir.Program) (vsh, psh *_ID3DBlob, ferr error)
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
wg.Go(func() error {
|
wg.Go(func() error {
|
||||||
p, err := _D3DCompile([]byte(ps), "shader", nil, nil, "PSMain", "ps_4_0", flag, 0)
|
p, err := _D3DCompile([]byte(ps), "shader", nil, nil, PixelShaderEntryPoint, PixelShaderProfile, flag, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("directx: D3DCompile for PSMain failed, original source: %s, %w", ps, err)
|
return fmt.Errorf("directx: D3DCompile for PSMain failed, original source: %s, %w", ps, err)
|
||||||
}
|
}
|
||||||
|
65
shaderprecomp/shaderprecomp_windows.go
Normal file
65
shaderprecomp/shaderprecomp_windows.go
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
// Copyright 2024 The Ebitengine Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package shaderprecomp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"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"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// HLSLVertexShaderProfile is the target profile for vertex shaders.
|
||||||
|
HLSLVertexShaderProfile = directx.VertexShaderProfile
|
||||||
|
|
||||||
|
// HLSLPixelShaderProfile is the target profile for pixel shaders.
|
||||||
|
HLSLPixelShaderProfile = directx.PixelShaderProfile
|
||||||
|
|
||||||
|
// HLSLVertexShaderEntryPoint is the entry point name for vertex shaders.
|
||||||
|
HLSLVertexShaderEntryPoint = directx.VertexShaderEntryPoint
|
||||||
|
|
||||||
|
// HLSLPixelShaderEntryPoint is the entry point name for pixel shaders.
|
||||||
|
HLSLPixelShaderEntryPoint = directx.PixelShaderEntryPoint
|
||||||
|
)
|
||||||
|
|
||||||
|
// CompileToHLSL compiles the shader source to High-Level Shader Language to writers.
|
||||||
|
//
|
||||||
|
// CompileToHLSL is concurrent-safe.
|
||||||
|
func CompileToHLSL(vertexWriter, pixelWriter io.Writer, source *ShaderSource) error {
|
||||||
|
ir, err := graphics.CompileShader(source.source)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
vs, ps := hlsl.Compile(ir)
|
||||||
|
if _, err = vertexWriter.Write([]byte(vs)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err = pixelWriter.Write([]byte(ps)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterFXCs registers a precompiled HLSL (FXC) for a shader source.
|
||||||
|
// vertexFXC and pixelFXC must be the content of .fxc files generated by `fxc` command.
|
||||||
|
// For more details, see https://learn.microsoft.com/en-us/windows/win32/direct3dtools/dx-graphics-tools-fxc-using.
|
||||||
|
//
|
||||||
|
// RegisterFXCs is concurrent-safe.
|
||||||
|
func RegisterFXCs(source *ShaderSource, vertexFXC, pixelFXC []byte) {
|
||||||
|
directx.RegisterPrecompiledFXCs(shaderir.SourceHash(source.ID()), vertexFXC, pixelFXC)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user