~eliasnaur/gio

61529c2cb6f424cf8705b016f3954a874ac0a5c6 — Elias Naur 29 days ago acfe91e
gpu: fix clip intersection with the D3D backend

Signed-off-by: Elias Naur <mail@eliasnaur.com>
M app/headless/headless_test.go => app/headless/headless_test.go +59 -0
@@ 9,6 9,7 @@ import (

	"gioui.org/f32"
	"gioui.org/op"
	"gioui.org/op/clip"
	"gioui.org/op/paint"
)



@@ 39,6 40,64 @@ func TestHeadless(t *testing.T) {
	}
}

func TestClipping(t *testing.T) {
	w, release := newTestWindow(t)
	defer release()

	sz := w.size
	col := color.RGBA{A: 0xff, R: 0xca, G: 0xfe}
	col2 := color.RGBA{A: 0xff, R: 0x00, G: 0xfe}
	var ops op.Ops
	pop := paint.PaintOp{Rect: f32.Rectangle{Max: f32.Point{
		X: float32(sz.X),
		Y: float32(sz.Y),
	}}}
	paint.ColorOp{Color: col}.Add(&ops)
	clip.Rect{
		Rect: f32.Rectangle{
			Min: f32.Point{X: 50, Y: 50},
			Max: f32.Point{X: 250, Y: 250},
		},
		SE: 75,
	}.Op(&ops).Add(&ops)
	pop.Add(&ops)
	paint.ColorOp{Color: col2}.Add(&ops)
	clip.Rect{
		Rect: f32.Rectangle{
			Min: f32.Point{X: 100, Y: 100},
			Max: f32.Point{X: 350, Y: 350},
		},
		NW: 75,
	}.Op(&ops).Add(&ops)
	pop.Add(&ops)
	w.Frame(&ops)

	img, err := w.Screenshot()
	if err != nil {
		t.Fatal(err)
	}
	if *dumpImages {
		if err := saveImage("clip.png", img); err != nil {
			t.Fatal(err)
		}
	}
	bg := color.RGBA{A: 0xff, R: 0xff, G: 0xff, B: 0xff}
	tests := []struct {
		x, y  int
		color color.RGBA
	}{
		{120, 120, col},
		{130, 130, col2},
		{210, 210, col2},
		{230, 230, bg},
	}
	for _, test := range tests {
		if got := img.RGBAAt(test.x, test.y); got != test.color {
			t.Errorf("(%d,%d): got color %v, expected %v", test.x, test.y, got, test.color)
		}
	}
}

func newTestWindow(t *testing.T) (*Window, func()) {
	t.Helper()
	sz := image.Point{X: 800, Y: 600}

M gpu/gpu.go => gpu/gpu.go +7 -1
@@ 538,15 538,21 @@ func (r *renderer) intersectPath(p *pathOp, clip image.Rectangle) {
	if !p.path {
		return
	}
	o := p.place.Pos.Add(clip.Min).Sub(p.clip.Min)
	uv := image.Rectangle{
		Min: p.place.Pos,
		Max: p.place.Pos.Add(p.clip.Size()),
	}
	o := clip.Min.Sub(p.clip.Min)
	sub := image.Rectangle{
		Min: o,
		Max: o.Add(clip.Size()),
	}
	fbo := r.pather.stenciler.cover(p.place.Idx)
	r.ctx.BindTexture(0, fbo.tex)
	coverScale, coverOff := texSpaceTransform(toRectF(uv), fbo.size)
	subScale, subOff := texSpaceTransform(toRectF(sub), p.clip.Size())
	r.pather.stenciler.iprog.uniforms.vert.uvTransform = [4]float32{coverScale.X, coverScale.Y, coverOff.X, coverOff.Y}
	r.pather.stenciler.iprog.uniforms.vert.subUVTransform = [4]float32{subScale.X, subScale.Y, subOff.X, subOff.Y}
	r.pather.stenciler.iprog.prog.UploadUniforms()
	r.ctx.DrawArrays(backend.DrawModeTriangleStrip, 0, 4)
}

M gpu/path.go => gpu/path.go +2 -1
@@ 83,7 83,8 @@ type stencilUniforms struct {

type intersectUniforms struct {
	vert struct {
		uvTransform [4]float32
		uvTransform    [4]float32
		subUVTransform [4]float32
	}
}


M gpu/shaders.go => gpu/shaders.go +49 -13
@@ 394,24 394,25 @@ var (
		Inputs: []backend.InputLocation{{Name: "pos", Location: 0, Semantic: "POSITION", SemanticIndex: 0, Type: 0x0, Size: 2}, {Name: "uv", Location: 1, Semantic: "NORMAL", SemanticIndex: 0, Type: 0x0, Size: 2}},
		Uniforms: backend.UniformsReflection{
			Blocks:    []backend.UniformBlock{{Name: "Block", Binding: 0}},
			Locations: []backend.UniformLocation{{Name: "_40.uvTransform", Type: 0x0, Size: 4, Offset: 0}},
			Size:      16,
			Locations: []backend.UniformLocation{{Name: "_101.uvTransform", Type: 0x0, Size: 4, Offset: 0}, {Name: "_101.subUVTransform", Type: 0x0, Size: 4, Offset: 16}},
			Size:      32,
		},
		GLSL100ES: "\nstruct Block\n{\n    vec4 uvTransform;\n};\n\nuniform Block _40;\n\nattribute vec2 pos;\nvarying vec2 vUV;\nattribute vec2 uv;\n\nvoid main()\n{\n    vec2 p = pos;\n    p.y = -p.y;\n    gl_Position = vec4(p, 0.0, 1.0);\n    vUV = (uv * _40.uvTransform.xy) + _40.uvTransform.zw;\n}\n\n",
		GLSL300ES: "#version 300 es\n\nlayout(std140) uniform Block\n{\n    vec4 uvTransform;\n} _40;\n\nlayout(location = 0) in vec2 pos;\nout vec2 vUV;\nlayout(location = 1) in vec2 uv;\n\nvoid main()\n{\n    vec2 p = pos;\n    p.y = -p.y;\n    gl_Position = vec4(p, 0.0, 1.0);\n    vUV = (uv * _40.uvTransform.xy) + _40.uvTransform.zw;\n}\n\n",
		GLSL130:   "#version 130\n\nstruct Block\n{\n    vec4 uvTransform;\n};\n\nuniform Block _40;\n\nin vec2 pos;\nout vec2 vUV;\nin vec2 uv;\n\nvoid main()\n{\n    vec2 p = pos;\n    p.y = -p.y;\n    gl_Position = vec4(p, 0.0, 1.0);\n    vUV = (uv * _40.uvTransform.xy) + _40.uvTransform.zw;\n}\n\n",
		GLSL150:   "#version 150\n\nstruct Block\n{\n    vec4 uvTransform;\n};\n\nuniform Block _40;\n\nin vec2 pos;\nout vec2 vUV;\nin vec2 uv;\n\nvoid main()\n{\n    vec2 p = pos;\n    p.y = -p.y;\n    gl_Position = vec4(p, 0.0, 1.0);\n    vUV = (uv * _40.uvTransform.xy) + _40.uvTransform.zw;\n}\n\n",
		GLSL100ES: "\nstruct Block\n{\n    vec4 uvTransform;\n    vec4 subUVTransform;\n};\n\nuniform Block _101;\n\nattribute vec2 pos;\nattribute vec2 uv;\nvarying vec2 vUV;\n\nvec3[2] fboTransform()\n{\n    vec3 t[2];\n    t[0] = vec3(1.0, 0.0, 0.0);\n    t[1] = vec3(0.0, -1.0, 0.0);\n    return t;\n}\n\nvec3 transform3x2(vec3 t[2], vec3 v)\n{\n    return vec3(dot(t[0], v), dot(t[1], v), dot(vec3(0.0, 0.0, 1.0), v));\n}\n\nvec3[2] fboTextureTransform()\n{\n    vec3 t[2];\n    t[0] = vec3(1.0, 0.0, 0.0);\n    t[1] = vec3(0.0, 1.0, 0.0);\n    return t;\n}\n\nvoid main()\n{\n    vec3 fboTrans[2] = fboTransform();\n    vec3 param[2] = fboTrans;\n    vec3 param_1 = vec3(pos, 1.0);\n    vec3 p = transform3x2(param, param_1);\n    gl_Position = vec4(p, 1.0);\n    vec3 fboTexTrans[2] = fboTextureTransform();\n    vec3 param_2[2] = fboTexTrans;\n    vec3 param_3 = vec3(uv, 1.0);\n    vec3 uv3 = transform3x2(param_2, param_3);\n    vUV = (uv3.xy * _101.subUVTransform.xy) + _101.subUVTransform.zw;\n    vec3 param_4[2] = fboTexTrans;\n    vec3 param_5 = vec3(vUV, 1.0);\n    vUV = transform3x2(param_4, param_5).xy;\n    vUV = (vUV * _101.uvTransform.xy) + _101.uvTransform.zw;\n}\n\n",
		GLSL300ES: "#version 300 es\n\nlayout(std140) uniform Block\n{\n    vec4 uvTransform;\n    vec4 subUVTransform;\n} _101;\n\nlayout(location = 0) in vec2 pos;\nlayout(location = 1) in vec2 uv;\nout vec2 vUV;\n\nvec3[2] fboTransform()\n{\n    vec3 t[2];\n    t[0] = vec3(1.0, 0.0, 0.0);\n    t[1] = vec3(0.0, -1.0, 0.0);\n    return t;\n}\n\nvec3 transform3x2(vec3 t[2], vec3 v)\n{\n    return vec3(dot(t[0], v), dot(t[1], v), dot(vec3(0.0, 0.0, 1.0), v));\n}\n\nvec3[2] fboTextureTransform()\n{\n    vec3 t[2];\n    t[0] = vec3(1.0, 0.0, 0.0);\n    t[1] = vec3(0.0, 1.0, 0.0);\n    return t;\n}\n\nvoid main()\n{\n    vec3 fboTrans[2] = fboTransform();\n    vec3 param[2] = fboTrans;\n    vec3 param_1 = vec3(pos, 1.0);\n    vec3 p = transform3x2(param, param_1);\n    gl_Position = vec4(p, 1.0);\n    vec3 fboTexTrans[2] = fboTextureTransform();\n    vec3 param_2[2] = fboTexTrans;\n    vec3 param_3 = vec3(uv, 1.0);\n    vec3 uv3 = transform3x2(param_2, param_3);\n    vUV = (uv3.xy * _101.subUVTransform.xy) + _101.subUVTransform.zw;\n    vec3 param_4[2] = fboTexTrans;\n    vec3 param_5 = vec3(vUV, 1.0);\n    vUV = transform3x2(param_4, param_5).xy;\n    vUV = (vUV * _101.uvTransform.xy) + _101.uvTransform.zw;\n}\n\n",
		GLSL130:   "#version 130\n\nstruct Block\n{\n    vec4 uvTransform;\n    vec4 subUVTransform;\n};\n\nuniform Block _101;\n\nin vec2 pos;\nin vec2 uv;\nout vec2 vUV;\n\nvec3[2] fboTransform()\n{\n    vec3 t[2];\n    t[0] = vec3(1.0, 0.0, 0.0);\n    t[1] = vec3(0.0, -1.0, 0.0);\n    return t;\n}\n\nvec3 transform3x2(vec3 t[2], vec3 v)\n{\n    return vec3(dot(t[0], v), dot(t[1], v), dot(vec3(0.0, 0.0, 1.0), v));\n}\n\nvec3[2] fboTextureTransform()\n{\n    vec3 t[2];\n    t[0] = vec3(1.0, 0.0, 0.0);\n    t[1] = vec3(0.0, 1.0, 0.0);\n    return t;\n}\n\nvoid main()\n{\n    vec3 fboTrans[2] = fboTransform();\n    vec3 param[2] = fboTrans;\n    vec3 param_1 = vec3(pos, 1.0);\n    vec3 p = transform3x2(param, param_1);\n    gl_Position = vec4(p, 1.0);\n    vec3 fboTexTrans[2] = fboTextureTransform();\n    vec3 param_2[2] = fboTexTrans;\n    vec3 param_3 = vec3(uv, 1.0);\n    vec3 uv3 = transform3x2(param_2, param_3);\n    vUV = (uv3.xy * _101.subUVTransform.xy) + _101.subUVTransform.zw;\n    vec3 param_4[2] = fboTexTrans;\n    vec3 param_5 = vec3(vUV, 1.0);\n    vUV = transform3x2(param_4, param_5).xy;\n    vUV = (vUV * _101.uvTransform.xy) + _101.uvTransform.zw;\n}\n\n",
		GLSL150:   "#version 150\n\nstruct Block\n{\n    vec4 uvTransform;\n    vec4 subUVTransform;\n};\n\nuniform Block _101;\n\nin vec2 pos;\nin vec2 uv;\nout vec2 vUV;\n\nvec3[2] fboTransform()\n{\n    vec3 t[2];\n    t[0] = vec3(1.0, 0.0, 0.0);\n    t[1] = vec3(0.0, -1.0, 0.0);\n    return t;\n}\n\nvec3 transform3x2(vec3 t[2], vec3 v)\n{\n    return vec3(dot(t[0], v), dot(t[1], v), dot(vec3(0.0, 0.0, 1.0), v));\n}\n\nvec3[2] fboTextureTransform()\n{\n    vec3 t[2];\n    t[0] = vec3(1.0, 0.0, 0.0);\n    t[1] = vec3(0.0, 1.0, 0.0);\n    return t;\n}\n\nvoid main()\n{\n    vec3 fboTrans[2] = fboTransform();\n    vec3 param[2] = fboTrans;\n    vec3 param_1 = vec3(pos, 1.0);\n    vec3 p = transform3x2(param, param_1);\n    gl_Position = vec4(p, 1.0);\n    vec3 fboTexTrans[2] = fboTextureTransform();\n    vec3 param_2[2] = fboTexTrans;\n    vec3 param_3 = vec3(uv, 1.0);\n    vec3 uv3 = transform3x2(param_2, param_3);\n    vUV = (uv3.xy * _101.subUVTransform.xy) + _101.subUVTransform.zw;\n    vec3 param_4[2] = fboTexTrans;\n    vec3 param_5 = vec3(vUV, 1.0);\n    vUV = transform3x2(param_4, param_5).xy;\n    vUV = (vUV * _101.uvTransform.xy) + _101.uvTransform.zw;\n}\n\n",
		/*
		   cbuffer Block : register(b0)
		   {
		       float4 _40_uvTransform : packoffset(c0);
		       float4 _101_uvTransform : packoffset(c0);
		       float4 _101_subUVTransform : packoffset(c1);
		   };


		   static float4 gl_Position;
		   static float2 pos;
		   static float2 vUV;
		   static float2 uv;
		   static float2 vUV;

		   struct SPIRV_Cross_Input
		   {


@@ 425,12 426,47 @@ var (
		       float4 gl_Position : SV_Position;
		   };

		   void fboTransform(out float3 SPIRV_Cross_return_value[2])
		   {
		       float3 t[2];
		       t[0] = float3(1.0f, 0.0f, 0.0f);
		       t[1] = float3(0.0f, 1.0f, 0.0f);
		       SPIRV_Cross_return_value = t;
		   }

		   float3 transform3x2(float3 t[2], float3 v)
		   {
		       return float3(dot(t[0], v), dot(t[1], v), dot(float3(0.0f, 0.0f, 1.0f), v));
		   }

		   void fboTextureTransform(out float3 SPIRV_Cross_return_value[2])
		   {
		       float3 t[2];
		       t[0] = float3(1.0f, 0.0f, 0.0f);
		       t[1] = float3(0.0f, -1.0f, 1.0f);
		       SPIRV_Cross_return_value = t;
		   }

		   void vert_main()
		   {
		       float2 p = pos;
		       p.y = -p.y;
		       gl_Position = float4(p, 0.0f, 1.0f);
		       vUV = (uv * _40_uvTransform.xy) + _40_uvTransform.zw;
		       float3 _59[2];
		       fboTransform(_59);
		       float3 fboTrans[2] = _59;
		       float3 param[2] = fboTrans;
		       float3 param_1 = float3(pos, 1.0f);
		       float3 p = transform3x2(param, param_1);
		       gl_Position = float4(p, 1.0f);
		       float3 _84[2];
		       fboTextureTransform(_84);
		       float3 fboTexTrans[2] = _84;
		       float3 param_2[2] = fboTexTrans;
		       float3 param_3 = float3(uv, 1.0f);
		       float3 uv3 = transform3x2(param_2, param_3);
		       vUV = (uv3.xy * _101_subUVTransform.xy) + _101_subUVTransform.zw;
		       float3 param_4[2] = fboTexTrans;
		       float3 param_5 = float3(vUV, 1.0f);
		       vUV = transform3x2(param_4, param_5).xy;
		       vUV = (vUV * _101_uvTransform.xy) + _101_uvTransform.zw;
		   }

		   SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)


@@ 445,7 481,7 @@ var (
		   }

		*/
		HLSL: []byte{0x44, 0x58, 0x42, 0x43, 0x9d, 0xb4, 0xe5, 0x39, 0x85, 0xb0, 0xbe, 0xe4, 0xf4, 0xfb, 0x5f, 0x51, 0x32, 0x0, 0x34, 0x3, 0x1, 0x0, 0x0, 0x0, 0xa0, 0x3, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x38, 0x0, 0x0, 0x0, 0xec, 0x0, 0x0, 0x0, 0xb8, 0x1, 0x0, 0x0, 0x34, 0x2, 0x0, 0x0, 0xf8, 0x2, 0x0, 0x0, 0x48, 0x3, 0x0, 0x0, 0x41, 0x6f, 0x6e, 0x39, 0xac, 0x0, 0x0, 0x0, 0xac, 0x0, 0x0, 0x0, 0x0, 0x2, 0xfe, 0xff, 0x78, 0x0, 0x0, 0x0, 0x34, 0x0, 0x0, 0x0, 0x1, 0x0, 0x24, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x24, 0x0, 0x1, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xfe, 0xff, 0x51, 0x0, 0x0, 0x5, 0x2, 0x0, 0xf, 0xa0, 0x0, 0x0, 0x80, 0x3f, 0x0, 0x0, 0x80, 0xbf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0x0, 0x0, 0x2, 0x5, 0x0, 0x0, 0x80, 0x0, 0x0, 0xf, 0x90, 0x1f, 0x0, 0x0, 0x2, 0x5, 0x0, 0x1, 0x80, 0x1, 0x0, 0xf, 0x90, 0x4, 0x0, 0x0, 0x4, 0x0, 0x0, 0x3, 0xe0, 0x1, 0x0, 0xe4, 0x90, 0x1, 0x0, 0xe4, 0xa0, 0x1, 0x0, 0xee, 0xa0, 0x1, 0x0, 0x0, 0x2, 0x0, 0x0, 0x3, 0x80, 0x2, 0x0, 0xe4, 0xa0, 0x4, 0x0, 0x0, 0x4, 0x0, 0x0, 0x3, 0xc0, 0x0, 0x0, 0xe4, 0x90, 0x0, 0x0, 0xe4, 0x80, 0x0, 0x0, 0xe4, 0xa0, 0x1, 0x0, 0x0, 0x2, 0x0, 0x0, 0xc, 0xc0, 0x2, 0x0, 0x24, 0xa0, 0xff, 0xff, 0x0, 0x0, 0x53, 0x48, 0x44, 0x52, 0xc4, 0x0, 0x0, 0x0, 0x40, 0x0, 0x1, 0x0, 0x31, 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, 0x4, 0x46, 0x8e, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x5f, 0x0, 0x0, 0x3, 0x32, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5f, 0x0, 0x0, 0x3, 0x32, 0x10, 0x10, 0x0, 0x1, 0x0, 0x0, 0x0, 0x65, 0x0, 0x0, 0x3, 0x32, 0x20, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x67, 0x0, 0x0, 0x4, 0xf2, 0x20, 0x10, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x32, 0x0, 0x0, 0xb, 0x32, 0x20, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x46, 0x10, 0x10, 0x0, 0x1, 0x0, 0x0, 0x0, 0x46, 0x80, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe6, 0x8a, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x38, 0x0, 0x0, 0xa, 0x32, 0x20, 0x10, 0x0, 0x1, 0x0, 0x0, 0x0, 0x46, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x40, 0x0, 0x0, 0x0, 0x0, 0x80, 0x3f, 0x0, 0x0, 0x80, 0xbf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x36, 0x0, 0x0, 0x8, 0xc2, 0x20, 0x10, 0x0, 0x1, 0x0, 0x0, 0x0, 0x2, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x3f, 0x3e, 0x0, 0x0, 0x1, 0x53, 0x54, 0x41, 0x54, 0x74, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x52, 0x44, 0x45, 0x46, 0xbc, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x44, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x4, 0xfe, 0xff, 0x0, 0x1, 0x0, 0x0, 0x94, 0x0, 0x0, 0x0, 0x3c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x0, 0xab, 0xab, 0x3c, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x5c, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x74, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x84, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5f, 0x34, 0x30, 0x5f, 0x75, 0x76, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x0, 0x1, 0x0, 0x3, 0x0, 0x1, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x31, 0x30, 0x2e, 0x31, 0x0, 0x49, 0x53, 0x47, 0x4e, 0x48, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x38, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x3, 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x3, 0x3, 0x0, 0x0, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x0, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x0, 0x4f, 0x53, 0x47, 0x4e, 0x50, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x38, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xc, 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x0, 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x0, 0xab, 0xab, 0xab},
		HLSL: []byte{0x44, 0x58, 0x42, 0x43, 0x2f, 0x66, 0x1f, 0xc0, 0x62, 0xcd, 0x8c, 0xeb, 0xb0, 0x37, 0x5c, 0xba, 0xcb, 0xd2, 0xb1, 0x7d, 0x1, 0x0, 0x0, 0x0, 0xdc, 0x4, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x38, 0x0, 0x0, 0x0, 0x4c, 0x1, 0x0, 0x0, 0xc4, 0x2, 0x0, 0x0, 0x40, 0x3, 0x0, 0x0, 0x34, 0x4, 0x0, 0x0, 0x84, 0x4, 0x0, 0x0, 0x41, 0x6f, 0x6e, 0x39, 0xc, 0x1, 0x0, 0x0, 0xc, 0x1, 0x0, 0x0, 0x0, 0x2, 0xfe, 0xff, 0xd8, 0x0, 0x0, 0x0, 0x34, 0x0, 0x0, 0x0, 0x1, 0x0, 0x24, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x24, 0x0, 0x1, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xfe, 0xff, 0x51, 0x0, 0x0, 0x5, 0x3, 0x0, 0xf, 0xa0, 0x0, 0x0, 0x80, 0x3f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0xbf, 0x0, 0x0, 0x0, 0x0, 0x1f, 0x0, 0x0, 0x2, 0x5, 0x0, 0x0, 0x80, 0x0, 0x0, 0xf, 0x90, 0x1f, 0x0, 0x0, 0x2, 0x5, 0x0, 0x1, 0x80, 0x1, 0x0, 0xf, 0x90, 0x4, 0x0, 0x0, 0x4, 0x0, 0x0, 0x3, 0x80, 0x1, 0x0, 0x55, 0x90, 0x3, 0x0, 0xe4, 0xa0, 0x3, 0x0, 0xe1, 0xa0, 0x5, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x80, 0x0, 0x0, 0xe4, 0x80, 0x3, 0x0, 0xe2, 0xa0, 0x2, 0x0, 0x0, 0x3, 0x0, 0x0, 0x2, 0x80, 0x0, 0x0, 0x55, 0x80, 0x0, 0x0, 0x0, 0x80, 0x1, 0x0, 0x0, 0x2, 0x0, 0x0, 0x1, 0x80, 0x1, 0x0, 0x0, 0x90, 0x4, 0x0, 0x0, 0x4, 0x0, 0x0, 0x3, 0x80, 0x0, 0x0, 0xe4, 0x80, 0x2, 0x0, 0xe4, 0xa0, 0x2, 0x0, 0xee, 0xa0, 0x1, 0x0, 0x0, 0x2, 0x0, 0x0, 0x4, 0x80, 0x3, 0x0, 0x0, 0xa0, 0x8, 0x0, 0x0, 0x3, 0x0, 0x0, 0x8, 0x80, 0x3, 0x0, 0xc9, 0xa0, 0x0, 0x0, 0xe4, 0x80, 0x4, 0x0, 0x0, 0x4, 0x0, 0x0, 0x3, 0xe0, 0x0, 0x0, 0xec, 0x80, 0x1, 0x0, 0xe4, 0xa0, 0x1, 0x0, 0xee, 0xa0, 0x2, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0xc0, 0x0, 0x0, 0xe4, 0x90, 0x0, 0x0, 0xe4, 0xa0, 0x1, 0x0, 0x0, 0x2, 0x0, 0x0, 0xc, 0xc0, 0x3, 0x0, 0x0, 0xa0, 0xff, 0xff, 0x0, 0x0, 0x53, 0x48, 0x44, 0x52, 0x70, 0x1, 0x0, 0x0, 0x40, 0x0, 0x1, 0x0, 0x5c, 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, 0x4, 0x46, 0x8e, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x5f, 0x0, 0x0, 0x3, 0x32, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5f, 0x0, 0x0, 0x3, 0x32, 0x10, 0x10, 0x0, 0x1, 0x0, 0x0, 0x0, 0x65, 0x0, 0x0, 0x3, 0x32, 0x20, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x67, 0x0, 0x0, 0x4, 0xf2, 0x20, 0x10, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x68, 0x0, 0x0, 0x2, 0x1, 0x0, 0x0, 0x0, 0x36, 0x0, 0x0, 0x5, 0x22, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x40, 0x0, 0x0, 0x0, 0x0, 0x80, 0x3f, 0x36, 0x0, 0x0, 0x5, 0x52, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x56, 0x14, 0x10, 0x0, 0x1, 0x0, 0x0, 0x0, 0xf, 0x0, 0x0, 0xa, 0x82, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x40, 0x0, 0x0, 0x0, 0x0, 0x80, 0xbf, 0x0, 0x0, 0x80, 0x3f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x46, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x32, 0x0, 0x0, 0xb, 0x32, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe6, 0xa, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x46, 0x80, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0xe6, 0x8a, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x36, 0x0, 0x0, 0x5, 0x42, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x40, 0x0, 0x0, 0x0, 0x0, 0x80, 0x3f, 0xf, 0x0, 0x0, 0xa, 0x82, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x40, 0x0, 0x0, 0x0, 0x0, 0x80, 0xbf, 0x0, 0x0, 0x80, 0x3f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x96, 0x5, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x32, 0x0, 0x0, 0xb, 0x32, 0x20, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc6, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x46, 0x80, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe6, 0x8a, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x36, 0x0, 0x0, 0x5, 0x32, 0x20, 0x10, 0x0, 0x1, 0x0, 0x0, 0x0, 0x46, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x36, 0x0, 0x0, 0x8, 0xc2, 0x20, 0x10, 0x0, 0x1, 0x0, 0x0, 0x0, 0x2, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x3f, 0x0, 0x0, 0x80, 0x3f, 0x3e, 0x0, 0x0, 0x1, 0x53, 0x54, 0x41, 0x54, 0x74, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x52, 0x44, 0x45, 0x46, 0xec, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x44, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x4, 0xfe, 0xff, 0x0, 0x1, 0x0, 0x0, 0xc4, 0x0, 0x0, 0x0, 0x3c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x0, 0xab, 0xab, 0x3c, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x5c, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5f, 0x31, 0x30, 0x31, 0x5f, 0x75, 0x76, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x0, 0xab, 0xab, 0xab, 0x1, 0x0, 0x3, 0x0, 0x1, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5f, 0x31, 0x30, 0x31, 0x5f, 0x73, 0x75, 0x62, 0x55, 0x56, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x0, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x31, 0x30, 0x2e, 0x31, 0x0, 0x49, 0x53, 0x47, 0x4e, 0x48, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x38, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x3, 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x3, 0x3, 0x0, 0x0, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x0, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x0, 0x4f, 0x53, 0x47, 0x4e, 0x50, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x38, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xc, 0x0, 0x0, 0x41, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x0, 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x0, 0xab, 0xab, 0xab},
	}
	shader_stencil_frag = backend.ShaderSources{
		GLSL100ES: "precision mediump float;\nprecision highp int;\n\nvarying vec2 vTo;\nvarying vec2 vFrom;\nvarying vec2 vCtrl;\n\nvoid main()\n{\n    float dx = vTo.x - vFrom.x;\n    bool increasing = vTo.x >= vFrom.x;\n    bvec2 _35 = bvec2(increasing);\n    vec2 left = vec2(_35.x ? vFrom.x : vTo.x, _35.y ? vFrom.y : vTo.y);\n    bvec2 _41 = bvec2(increasing);\n    vec2 right = vec2(_41.x ? vTo.x : vFrom.x, _41.y ? vTo.y : vFrom.y);\n    vec2 extent = clamp(vec2(vFrom.x, vTo.x), vec2(-0.5), vec2(0.5));\n    float midx = mix(extent.x, extent.y, 0.5);\n    float x0 = midx - left.x;\n    vec2 p1 = vCtrl - left;\n    vec2 v = right - vCtrl;\n    float t = x0 / (p1.x + sqrt((p1.x * p1.x) + ((v.x - p1.x) * x0)));\n    float y = mix(mix(left.y, vCtrl.y, t), mix(vCtrl.y, right.y, t), t);\n    vec2 d_half = mix(p1, v, vec2(t));\n    float dy = d_half.y / d_half.x;\n    float width = extent.y - extent.x;\n    dy = abs(dy * width);\n    vec4 sides = vec4((dy * 0.5) + y, (dy * (-0.5)) + y, (0.5 - y) / dy, ((-0.5) - y) / dy);\n    sides = clamp(sides + vec4(0.5), vec4(0.0), vec4(1.0));\n    float area = 0.5 * ((((sides.z - (sides.z * sides.y)) + 1.0) - sides.x) + (sides.x * sides.w));\n    area *= width;\n    if (width == 0.0)\n    {\n        area = 0.0;\n    }\n    gl_FragData[0].x = area;\n}\n\n",

M gpu/shaders/common.inc => gpu/shaders/common.inc +17 -0
@@ 17,6 17,23 @@ vec3[2] fboTextureTransform() {
	return t;
}

// fboTransform returns a transformation
// that cancels the implied transformation between
// the clip space and the framebuffer.
// Only two rows are returned. The last is implied
// to be [0, 0, 1].
vec3[2] fboTransform() {
	vec3[2] t;
#ifdef HLSL
	t[0] = vec3(1.0, 0.0, 0.0);
	t[1] = vec3(0.0, 1.0, 0.0);
#else
	t[0] = vec3(1.0, 0.0, 0.0);
	t[1] = vec3(0.0, -1.0, 0.0);
#endif
	return t;
}

// toClipSpace converts an OpenGL gl_Position value to a
// native GPU position.
vec4 toClipSpace(vec4 pos) {

M gpu/shaders/intersect.vert => gpu/shaders/intersect.vert +11 -4
@@ 4,18 4,25 @@

precision highp float;

#include <common.inc>

layout(location = 0) in vec2 pos;
layout(location = 1) in vec2 uv;

layout(binding = 0) uniform Block {
	vec4 uvTransform;
	vec4 subUVTransform;
};

layout(location = 0) out vec2 vUV;

void main() {
  vec2 p = pos;
  p.y = -p.y;
  gl_Position = vec4(p, 0, 1);
  vUV = uv*uvTransform.xy + uvTransform.zw;
  vec3[2] fboTrans = fboTransform();
  vec3 p = transform3x2(fboTrans, vec3(pos, 1.0));
  gl_Position = vec4(p, 1);
  vec3[2] fboTexTrans = fboTextureTransform();
  vec3 uv3 = transform3x2(fboTexTrans, vec3(uv, 1.0));
  vUV = uv3.xy*subUVTransform.xy + subUVTransform.zw;
  vUV = transform3x2(fboTexTrans, vec3(vUV, 1.0)).xy;
  vUV = vUV*uvTransform.xy + uvTransform.zw;
}