internal/cmd/convertshaders: replace fxc.exe with D3DCompile

D3DCompile successfully compiles shaders fxc.exe doesn't. As a bonus
the DirectX SDK is no longer required (it includes fxc.exe).

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2020-02-28 15:10:17 +01:00
parent a448825d48
commit 1d3a9fb2d6
5 changed files with 128 additions and 104 deletions
-77
View File
@@ -9,8 +9,6 @@ import (
"syscall"
gunsafe "gioui.org/internal/unsafe"
"golang.org/x/sys/windows"
)
@@ -360,14 +358,6 @@ type _ID3D11InputLayout struct {
}
}
type _ID3DBlob struct {
vtbl *struct {
_IUnknownVTbl
GetBufferPointer uintptr
GetBufferSize uintptr
}
}
type _D3D11_DEPTH_STENCIL_DESC struct {
DepthEnable uint32
DepthWriteMask uint32
@@ -560,10 +550,6 @@ var (
__D3D11CreateDevice = d3d11.NewProc("D3D11CreateDevice")
__D3D11CreateDeviceAndSwapChain = d3d11.NewProc("D3D11CreateDeviceAndSwapChain")
d3dcompiler_47 = windows.NewLazySystemDLL("d3dcompiler_47.dll")
__D3DCompile = d3dcompiler_47.NewProc("D3DCompile")
)
const (
@@ -699,41 +685,6 @@ func _D3D11CreateDeviceAndSwapChain(driverType uint32, flags uint32, swapDesc *_
return dev, ctx, swchain, featLvl, nil
}
func _D3DCompile(src []byte, entryPoint, target string) ([]byte, error) {
var (
code *_ID3DBlob
errors *_ID3DBlob
)
entryPoint0 := []byte(entryPoint + "\x00")
target0 := []byte(target + "\x00")
r, _, _ := __D3DCompile.Call(
uintptr(unsafe.Pointer(&src[0])),
uintptr(len(src)),
0, // pSourceName
0, // pDefines
0, // pInclude
uintptr(unsafe.Pointer(&entryPoint0[0])),
uintptr(unsafe.Pointer(&target0[0])),
0, // Flags1
0, // Flags2
uintptr(unsafe.Pointer(&code)),
uintptr(unsafe.Pointer(&errors)),
)
var compileErr string
if errors != nil {
compileErr = string(errors.data())
_IUnknownRelease(unsafe.Pointer(errors), errors.vtbl.Release)
}
if r != 0 {
return nil, fmt.Errorf("D3D11Compile: %#x: %s", r, compileErr)
}
bytecode := code.data()
cp := make([]byte, len(bytecode))
copy(cp, bytecode)
_IUnknownRelease(unsafe.Pointer(code), code.vtbl.Release)
return cp, nil
}
func (d *_ID3D11Device) CreateBuffer(desc *_D3D11_BUFFER_DESC, data []byte) (*_ID3D11Buffer, error) {
var dataDesc *_D3D11_SUBRESOURCE_DATA
if len(data) > 0 {
@@ -1281,34 +1232,6 @@ func (c *_ID3D11DeviceContext) OMSetDepthStencilState(state *_ID3D11DepthStencil
)
}
func (b *_ID3DBlob) GetBufferPointer() uintptr {
ptr, _, _ := syscall.Syscall(
b.vtbl.GetBufferPointer,
1,
uintptr(unsafe.Pointer(b)),
0,
0,
)
return ptr
}
func (b *_ID3DBlob) GetBufferSize() uintptr {
sz, _, _ := syscall.Syscall(
b.vtbl.GetBufferSize,
1,
uintptr(unsafe.Pointer(b)),
0,
0,
)
return sz
}
func (b *_ID3DBlob) data() []byte {
data := gunsafe.SliceOf(b.GetBufferPointer())
n := int(b.GetBufferSize())
return data[:n:n]
}
func (d *_IDXGIObject) GetParent(guid *_GUID) (*_IDXGIObject, error) {
var parent *_IDXGIObject
r, _, _ := syscall.Syscall(
+9
View File
@@ -0,0 +1,9 @@
// SPDX-License-Identifier: Unlicense OR MIT
// +build !windows
package main
func compileHLSL(src, entry, profile string) ([]byte, error) {
return nil, nil
}
@@ -0,0 +1,9 @@
// SPDX-License-Identifier: Unlicense OR MIT
package main
import "gioui.org/internal/d3dcompile"
func compileHLSL(src, entry, profile string) ([]byte, error) {
return d3dcompile.D3DCompile([]byte(src), entry, profile)
}
+3 -27
View File
@@ -55,8 +55,6 @@ func generate() error {
if err != nil {
return err
}
fxc, err := exec.LookPath("fxc")
fxcFound := err == nil
shaders, err := filepath.Glob(filepath.Join(absShadersDir, "*"))
if err != nil {
return err
@@ -117,11 +115,9 @@ func generate() error {
return fmt.Errorf("unrecognized shader type %s", shader)
}
var hlslc []byte
if fxcFound {
hlslc, err = compileHLSL(tmp, fxc, hlsl, "main", hlslProf+"_4_0")
if err != nil {
return err
}
hlslc, err = compileHLSL(hlsl, "main", hlslProf+"_4_0")
if err != nil {
return err
}
// OpenGL 3.2 Core only accepts GLSL version 1.50, but is
// otherwise compatible with version 1.30.
@@ -310,26 +306,6 @@ func parseDataType(t string) (backend.DataType, int, error) {
}
}
func compileHLSL(tmp, fxc, src, entry, profile string) ([]byte, error) {
tmpfile := filepath.Join(tmp, "shader.hlsl")
if err := ioutil.WriteFile(tmpfile, []byte(src), 0644); err != nil {
return nil, err
}
outFile := filepath.Join(tmp, "shader.bin")
cmd := exec.Command(fxc,
"/T", profile,
"/E", entry,
"/nologo",
"/Fo", outFile,
tmpfile,
)
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
return nil, err
}
return ioutil.ReadFile(outFile)
}
func convertShader(tmp, glslcc, path, lang, profile string, args *shaderArgs, flattenUBOs bool) (string, []byte, error) {
shaderTmpl, err := template.ParseFiles(path)
if err != nil {
+107
View File
@@ -0,0 +1,107 @@
// SPDX-License-Identifier: Unlicense OR MIT
package d3dcompile
import (
"fmt"
"unsafe"
"syscall"
gunsafe "gioui.org/internal/unsafe"
"golang.org/x/sys/windows"
)
var (
d3dcompiler_47 = windows.NewLazySystemDLL("d3dcompiler_47.dll")
__D3DCompile = d3dcompiler_47.NewProc("D3DCompile")
)
type _IUnknownVTbl struct {
QueryInterface uintptr
AddRef uintptr
Release uintptr
}
type _ID3DBlob struct {
vtbl *struct {
_IUnknownVTbl
GetBufferPointer uintptr
GetBufferSize uintptr
}
}
func D3DCompile(src []byte, entryPoint, target string) ([]byte, error) {
var (
code *_ID3DBlob
errors *_ID3DBlob
)
entryPoint0 := []byte(entryPoint + "\x00")
target0 := []byte(target + "\x00")
r, _, _ := __D3DCompile.Call(
uintptr(unsafe.Pointer(&src[0])),
uintptr(len(src)),
0, // pSourceName
0, // pDefines
0, // pInclude
uintptr(unsafe.Pointer(&entryPoint0[0])),
uintptr(unsafe.Pointer(&target0[0])),
0, // Flags1
0, // Flags2
uintptr(unsafe.Pointer(&code)),
uintptr(unsafe.Pointer(&errors)),
)
var compileErr string
if errors != nil {
compileErr = string(errors.data())
_IUnknownRelease(unsafe.Pointer(errors), errors.vtbl.Release)
}
if r != 0 {
return nil, fmt.Errorf("D3D11Compile: %#x: %s", r, compileErr)
}
bytecode := code.data()
cp := make([]byte, len(bytecode))
copy(cp, bytecode)
_IUnknownRelease(unsafe.Pointer(code), code.vtbl.Release)
return cp, nil
}
func (b *_ID3DBlob) GetBufferPointer() uintptr {
ptr, _, _ := syscall.Syscall(
b.vtbl.GetBufferPointer,
1,
uintptr(unsafe.Pointer(b)),
0,
0,
)
return ptr
}
func (b *_ID3DBlob) GetBufferSize() uintptr {
sz, _, _ := syscall.Syscall(
b.vtbl.GetBufferSize,
1,
uintptr(unsafe.Pointer(b)),
0,
0,
)
return sz
}
func (b *_ID3DBlob) data() []byte {
data := gunsafe.SliceOf(b.GetBufferPointer())
n := int(b.GetBufferSize())
return data[:n:n]
}
func _IUnknownRelease(obj unsafe.Pointer, releaseMethod uintptr) {
syscall.Syscall(
releaseMethod,
1,
uintptr(obj),
0,
0,
)
}