Compare commits

..

No commits in common. "230619a03681e06ca9c3177f77d585ce1d889adb" and "e7bb66bb2f13ae302e8fd14409faa0b0c749e367" have entirely different histories.

11 changed files with 52 additions and 150 deletions

1
doc.go
View File

@ -81,7 +81,6 @@
// //
// "debug": Use a debug layer. // "debug": Use a debug layer.
// "warp": Use WARP (i.e. software rendering). // "warp": Use WARP (i.e. software rendering).
// "tearing": Allow tearing when vsync is off.
// "version=VERSION": Specify a DirectX version (e.g. 11). // "version=VERSION": Specify a DirectX version (e.g. 11).
// "featurelevel=FEATURE_LEVEL": Specify a feature level (e.g. 11_0). This is for DirectX 12. // "featurelevel=FEATURE_LEVEL": Specify a feature level (e.g. 11_0). This is for DirectX 12.
// //

View File

@ -14,19 +14,14 @@
//go:build ignore //go:build ignore
// Specify the 'pixel' mode.
//kage:unit pixels //kage:unit pixels
package main package main
// Uniform variables.
var Time float var Time float
var Cursor vec2 var Cursor vec2
// Fragment is the entry point of the fragment shader.
// Fragment returns the color value for the current position.
func Fragment(dstPos vec4, srcPos vec2, color vec4) vec4 { func Fragment(dstPos vec4, srcPos vec2, color vec4) vec4 {
// You can define variables with a short variable declaration like Go.
pos := dstPos.xy - imageDstOrigin() pos := dstPos.xy - imageDstOrigin()
lightpos := vec3(Cursor, 50) lightpos := vec3(Cursor, 50)
@ -34,8 +29,5 @@ func Fragment(dstPos vec4, srcPos vec2, color vec4) vec4 {
normal := normalize(imageSrc1UnsafeAt(srcPos) - 0.5) normal := normalize(imageSrc1UnsafeAt(srcPos) - 0.5)
const ambient = 0.25 const ambient = 0.25
diffuse := 0.75 * max(0.0, dot(normal.xyz, lightdir)) diffuse := 0.75 * max(0.0, dot(normal.xyz, lightdir))
// You can treat multiple source images by
// imageSrc[N]At or imageSrc[N]UnsafeAt.
return imageSrc0UnsafeAt(srcPos) * (ambient + diffuse) return imageSrc0UnsafeAt(srcPos) * (ambient + diffuse)
} }

View File

@ -140,16 +140,12 @@ func drawEbitenText(screen *ebiten.Image, x, y int, aa bool, line bool) {
op := &ebiten.DrawTrianglesOptions{} op := &ebiten.DrawTrianglesOptions{}
op.AntiAlias = aa op.AntiAlias = aa
if !line {
// For strokes (AppendVerticesAndIndicesForStroke), FillAll and NonZero work. // ebiten.EvenOdd is also fine here.
// // NonZero and EvenOdd differ when rendering a complex polygons with self-intersections and/or holes.
// For filling (AppendVerticesAndIndicesForFilling), NonZero and EvenOdd work. // See https://en.wikipedia.org/wiki/Nonzero-rule and https://en.wikipedia.org/wiki/Even%E2%80%93odd_rule .
// NonZero and EvenOdd differ when rendering a complex polygons with self-intersections and/or holes. op.FillRule = ebiten.NonZero
// See https://en.wikipedia.org/wiki/Nonzero-rule and https://en.wikipedia.org/wiki/Even%E2%80%93odd_rule . }
//
// For simplicity, this example always uses NonZero, whichever strokes or filling is done.
op.FillRule = ebiten.NonZero
screen.DrawTriangles(vs, is, whiteSubImage, op) screen.DrawTriangles(vs, is, whiteSubImage, op)
} }
@ -203,7 +199,9 @@ func drawEbitenLogo(screen *ebiten.Image, x, y int, aa bool, line bool) {
op := &ebiten.DrawTrianglesOptions{} op := &ebiten.DrawTrianglesOptions{}
op.AntiAlias = aa op.AntiAlias = aa
op.FillRule = ebiten.NonZero if !line {
op.FillRule = ebiten.NonZero
}
screen.DrawTriangles(vs, is, whiteSubImage, op) screen.DrawTriangles(vs, is, whiteSubImage, op)
} }
@ -245,7 +243,9 @@ func drawArc(screen *ebiten.Image, count int, aa bool, line bool) {
op := &ebiten.DrawTrianglesOptions{} op := &ebiten.DrawTrianglesOptions{}
op.AntiAlias = aa op.AntiAlias = aa
op.FillRule = ebiten.NonZero if !line {
op.FillRule = ebiten.NonZero
}
screen.DrawTriangles(vs, is, whiteSubImage, op) screen.DrawTriangles(vs, is, whiteSubImage, op)
} }
@ -300,7 +300,9 @@ func drawWave(screen *ebiten.Image, counter int, aa bool, line bool) {
op := &ebiten.DrawTrianglesOptions{} op := &ebiten.DrawTrianglesOptions{}
op.AntiAlias = aa op.AntiAlias = aa
op.FillRule = ebiten.NonZero if !line {
op.FillRule = ebiten.NonZero
}
screen.DrawTriangles(vs, is, whiteSubImage, op) screen.DrawTriangles(vs, is, whiteSubImage, op)
} }

View File

@ -153,7 +153,7 @@ type graphics11 struct {
newScreenHeight int newScreenHeight int
} }
func newGraphics11(useWARP bool, useDebugLayer bool, allowTearing bool) (gr11 *graphics11, ferr error) { func newGraphics11(useWARP bool, useDebugLayer bool) (gr11 *graphics11, ferr error) {
g := &graphics11{ g := &graphics11{
vsyncEnabled: true, vsyncEnabled: true,
} }
@ -207,7 +207,7 @@ func newGraphics11(useWARP bool, useDebugLayer bool, allowTearing bool) (gr11 *g
} }
dxgiFactory := (*_IDXGIFactory)(df) dxgiFactory := (*_IDXGIFactory)(df)
gi, err := newGraphicsInfra(dxgiFactory, allowTearing) gi, err := newGraphicsInfra(dxgiFactory)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -106,7 +106,7 @@ type graphics12 struct {
pipelineStates pipelineStates
} }
func newGraphics12(useWARP bool, useDebugLayer bool, allowTearing bool, featureLevel _D3D_FEATURE_LEVEL) (*graphics12, error) { func newGraphics12(useWARP bool, useDebugLayer bool, featureLevel _D3D_FEATURE_LEVEL) (*graphics12, error) {
g := &graphics12{} g := &graphics12{}
// Initialize not only a device but also other members like a fence. // Initialize not only a device but also other members like a fence.
@ -116,7 +116,7 @@ func newGraphics12(useWARP bool, useDebugLayer bool, allowTearing bool, featureL
return nil, err return nil, err
} }
} else { } else {
if err := g.initializeDesktop(useWARP, useDebugLayer, allowTearing, featureLevel); err != nil { if err := g.initializeDesktop(useWARP, useDebugLayer, featureLevel); err != nil {
return nil, err return nil, err
} }
} }
@ -124,7 +124,7 @@ func newGraphics12(useWARP bool, useDebugLayer bool, allowTearing bool, featureL
return g, nil return g, nil
} }
func (g *graphics12) initializeDesktop(useWARP bool, useDebugLayer bool, allowTearing bool, featureLevel _D3D_FEATURE_LEVEL) (ferr error) { func (g *graphics12) initializeDesktop(useWARP bool, useDebugLayer bool, featureLevel _D3D_FEATURE_LEVEL) (ferr error) {
if err := d3d12.Load(); err != nil { if err := d3d12.Load(); err != nil {
return err return err
} }
@ -152,7 +152,7 @@ func (g *graphics12) initializeDesktop(useWARP bool, useDebugLayer bool, allowTe
if err != nil { if err != nil {
return err return err
} }
gi, err := newGraphicsInfra(f, allowTearing) gi, err := newGraphicsInfra(f)
if err != nil { if err != nil {
return err return err
} }

View File

@ -81,7 +81,6 @@ func NewGraphics() (graphicsdriver.Graphics, error) {
var useWARP bool var useWARP bool
var useDebugLayer bool var useDebugLayer bool
var allowTearing bool
version := 11 version := 11
// Specify the feature level 11 by default. // Specify the feature level 11 by default.
@ -109,8 +108,6 @@ func NewGraphics() (graphicsdriver.Graphics, error) {
useWARP = true useWARP = true
case t == "debug": case t == "debug":
useDebugLayer = true useDebugLayer = true
case t == "tearing":
allowTearing = true
case strings.HasPrefix(t, "version="): case strings.HasPrefix(t, "version="):
v, err := strconv.Atoi(t[len("version="):]) v, err := strconv.Atoi(t[len("version="):])
if err != nil { if err != nil {
@ -133,13 +130,13 @@ func NewGraphics() (graphicsdriver.Graphics, error) {
switch version { switch version {
case 11: case 11:
g, err := newGraphics11(useWARP, useDebugLayer, allowTearing) g, err := newGraphics11(useWARP, useDebugLayer)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return g, nil return g, nil
case 12: case 12:
g, err := newGraphics12(useWARP, useDebugLayer, allowTearing, featureLevel) g, err := newGraphics12(useWARP, useDebugLayer, featureLevel)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -166,21 +163,19 @@ type graphicsInfra struct {
} }
// newGraphicsInfra takes the ownership of the given factory. // newGraphicsInfra takes the ownership of the given factory.
func newGraphicsInfra(factory *_IDXGIFactory, allowTearing bool) (*graphicsInfra, error) { func newGraphicsInfra(factory *_IDXGIFactory) (*graphicsInfra, error) {
g := &graphicsInfra{ g := &graphicsInfra{
factory: factory, factory: factory,
} }
runtime.SetFinalizer(g, (*graphicsInfra).release) runtime.SetFinalizer(g, (*graphicsInfra).release)
if allowTearing { if f, err := g.factory.QueryInterface(&_IID_IDXGIFactory5); err == nil && f != nil {
if f, err := g.factory.QueryInterface(&_IID_IDXGIFactory5); err == nil && f != nil { factory := (*_IDXGIFactory5)(f)
factory := (*_IDXGIFactory5)(f) defer factory.Release()
defer factory.Release()
var allowTearing int32 var allowTearing int32
if err := factory.CheckFeatureSupport(_DXGI_FEATURE_PRESENT_ALLOW_TEARING, unsafe.Pointer(&allowTearing), uint32(unsafe.Sizeof(allowTearing))); err == nil && allowTearing != 0 { if err := factory.CheckFeatureSupport(_DXGI_FEATURE_PRESENT_ALLOW_TEARING, unsafe.Pointer(&allowTearing), uint32(unsafe.Sizeof(allowTearing))); err == nil && allowTearing != 0 {
g.allowTearing = true g.allowTearing = true
}
} }
} }

View File

@ -492,8 +492,8 @@ func (cs *compileState) assign(block *block, fname string, pos token.Pos, lhs, r
var rhsTypes []shaderir.Type var rhsTypes []shaderir.Type
allblank := true allblank := true
if len(lhs) == len(rhs) { for i, e := range lhs {
for i, e := range lhs { if len(lhs) == len(rhs) {
// Prase RHS first for the order of the statements. // Prase RHS first for the order of the statements.
r, rts, ss, ok := cs.parseExpr(block, fname, rhs[i], true) r, rts, ss, ok := cs.parseExpr(block, fname, rhs[i], true)
if !ok { if !ok {
@ -582,12 +582,6 @@ func (cs *compileState) assign(block *block, fname string, pos token.Pos, lhs, r
cs.addError(pos, fmt.Sprintf("cannot use type %s as type %s in variable declaration", rts[i].String(), lts[i].String())) cs.addError(pos, fmt.Sprintf("cannot use type %s as type %s in variable declaration", rts[i].String(), lts[i].String()))
return nil, false return nil, false
} }
switch lts[0].Main {
case shaderir.Int:
r[i].Const = gconstant.ToInt(r[i].Const)
case shaderir.Float:
r[i].Const = gconstant.ToFloat(r[i].Const)
}
} }
if len(lhs) == 1 { if len(lhs) == 1 {
@ -627,21 +621,20 @@ func (cs *compileState) assign(block *block, fname string, pos token.Pos, lhs, r
}, },
}) })
} }
} } else {
} else { if i == 0 {
var ss []shaderir.Stmt var ss []shaderir.Stmt
var ok bool var ok bool
rhsExprs, rhsTypes, ss, ok = cs.parseExpr(block, fname, rhs[0], true) rhsExprs, rhsTypes, ss, ok = cs.parseExpr(block, fname, rhs[0], true)
if !ok { if !ok {
return nil, false return nil, false
} }
if len(lhs) != len(rhsExprs) { if len(rhsExprs) != len(lhs) {
cs.addError(pos, fmt.Sprintf("assignment mismatch: %d variables but %d", len(lhs), len(rhsExprs))) cs.addError(pos, "single-value context and multiple-value context cannot be mixed")
return nil, false }
} stmts = append(stmts, ss...)
stmts = append(stmts, ss...) }
for i, e := range lhs {
if define { if define {
if _, ok := e.(*ast.Ident); !ok { if _, ok := e.(*ast.Ident); !ok {
cs.addError(pos, "non-name on the left side of :=") cs.addError(pos, "non-name on the left side of :=")

View File

@ -4103,48 +4103,6 @@ func Bar() {
`)); err != nil { `)); err != nil {
t.Error(err) t.Error(err)
} }
if _, err := compileToIR([]byte(`package main
func Foo() {
a, b := 0
_, _ = a, b
}
`)); err == nil {
t.Error("compileToIR must return an error but did not")
}
if _, err := compileToIR([]byte(`package main
func Foo() {
a, b, c := 0, 0
_, _ = a, b, c
}
`)); err == nil {
t.Error("compileToIR must return an error but did not")
}
if _, err := compileToIR([]byte(`package main
func Foo() {
var a, b int
a, b = 0
_, _ = a, b
}
`)); err == nil {
t.Error("compileToIR must return an error but did not")
}
if _, err := compileToIR([]byte(`package main
func Foo() {
var a, b, c int
a, b, c = 0, 0
_, _ = a, b, c
}
`)); err == nil {
t.Error("compileToIR must return an error but did not")
}
} }
func TestSyntaxBitwiseOperator(t *testing.T) { func TestSyntaxBitwiseOperator(t *testing.T) {

View File

@ -5,7 +5,7 @@ void F2(in bool l0, out float l1, out vec2 l2);
float F0(void) { float F0(void) {
float l0 = float(0); float l0 = float(0);
{ {
l0 = 0.0; l0 = 0;
} }
return l0; return l0;
} }
@ -14,9 +14,9 @@ void F1(out float l0, out vec2 l1) {
float l2 = float(0); float l2 = float(0);
vec2 l3 = vec2(0); vec2 l3 = vec2(0);
{ {
float l4 = float(0); int l4 = 0;
vec2 l5 = vec2(0); vec2 l5 = vec2(0);
l4 = 0.0; l4 = 0;
l2 = l4; l2 = l4;
l5 = vec2(0.0); l5 = vec2(0.0);
l3 = l5; l3 = l5;
@ -30,9 +30,9 @@ void F2(in bool l0, out float l1, out vec2 l2) {
float l3 = float(0); float l3 = float(0);
vec2 l4 = vec2(0); vec2 l4 = vec2(0);
{ {
float l5 = float(0); int l5 = 0;
vec2 l6 = vec2(0); vec2 l6 = vec2(0);
l5 = 0.0; l5 = 0;
l3 = l5; l3 = l5;
l6 = vec2(0.0); l6 = vec2(0.0);
l4 = l6; l4 = l6;

View File

@ -2559,39 +2559,3 @@ func Fragment(dstPos vec4, srcPos vec2, color vec4) vec4 {
} }
} }
} }
// Issue #2934
func TestShaderAssignConst(t *testing.T) {
const w, h = 16, 16
dst := ebiten.NewImage(w, h)
s, err := ebiten.NewShader([]byte(`//kage:unit pixels
package main
func Fragment(dstPos vec4, srcPos vec2, color vec4) vec4 {
a := 0.0
a = 1
b, c := 0.0, 0.0
b, c = 1, 1
d := 0.0
d += 1
return vec4(a, b, c, d)
}
`))
if err != nil {
t.Fatal(err)
}
dst.DrawRectShader(w, h, s, nil)
for j := 0; j < h; j++ {
for i := 0; i < w; i++ {
got := dst.At(i, j).(color.RGBA)
want := color.RGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff}
if !sameColors(got, want, 2) {
t.Errorf("dst.At(%d, %d): got: %v, want: %v", i, j, got, want)
}
}
}
}

View File

@ -480,7 +480,7 @@ type StrokeOptions struct {
// The returned vertice's SrcX and SrcY are 0, and ColorR, ColorG, ColorB, and ColorA are 1. // The returned vertice's SrcX and SrcY are 0, and ColorR, ColorG, ColorB, and ColorA are 1.
// //
// The returned values are intended to be passed to DrawTriangles or DrawTrianglesShader with a solid (non-transparent) color // The returned values are intended to be passed to DrawTriangles or DrawTrianglesShader with a solid (non-transparent) color
// with FillAll or NonZero fill rule, not EvenOdd fill rule. // with the FillAll fill rule (not NonZero or EvenOdd fill rule).
func (p *Path) AppendVerticesAndIndicesForStroke(vertices []ebiten.Vertex, indices []uint16, op *StrokeOptions) ([]ebiten.Vertex, []uint16) { func (p *Path) AppendVerticesAndIndicesForStroke(vertices []ebiten.Vertex, indices []uint16, op *StrokeOptions) ([]ebiten.Vertex, []uint16) {
if op == nil { if op == nil {
return vertices, indices return vertices, indices
@ -536,8 +536,7 @@ func (p *Path) AppendVerticesAndIndicesForStroke(vertices []ebiten.Vertex, indic
ColorA: 1, ColorA: 1,
}) })
} }
// All the triangles are rendered in clockwise order to enable NonZero filling rule (#2833). indices = append(indices, idx, idx+1, idx+2, idx+1, idx+2, idx+3)
indices = append(indices, idx, idx+1, idx+2, idx+1, idx+3, idx+2)
// Add line joints. // Add line joints.
var nextRect [4]point var nextRect [4]point