├── test ├── empty.t ├── foo.txt ├── abort.t ├── really-simple.t ├── error-return-int-from-main.t ├── hello.t ├── error-allocate-unsized-array.t ├── error-dereference.t ├── error-raw-ptr-must-be-initialized.t ├── include │ ├── include-fiveclass.t │ ├── syntax-error.t │ ├── small.jpg │ ├── fiveclass.t │ ├── test.t │ └── string.t ├── error-include-not-found.t ├── error-missing-parent-class.t ├── error-widen-null-to-raw-ptr.t ├── abort-on-strong-null-deref.t ├── abort-out-of-bounds-array.t ├── error-hex-literal-too-large.t ├── error-uint-literal-too-large.t ├── abort-out-of-bounds-vector.t ├── error-forward-var.t ├── error-stack-allocate-unsized-array.t ├── error-store-to-length.t ├── abort-out-of-bounds-matrix.t ├── duplicate-method.t ├── error-unknown-param-type.t ├── abort-out-of-bounds-heap-array.t ├── duplicate-var.t ├── error-syntax-error-in-included-file.t ├── hello-split.t ├── error-duplicate-enum.t ├── error-int-literal-too-large.t ├── abort-on-slice-fail1.t ├── abort-on-slice-fail2.t ├── error-constructor-not-found.t ├── error-unknown-return-type.t ├── error-missing-field.t ├── error-raw-ptr-cast-to-smart.t ├── unary-minus.t ├── byte.t ├── error-missing-method.t ├── error-new-with-missing-constructor.t ├── short.t ├── ubyte.t ├── binop-widen.t ├── cast-int-to-float.t ├── error-missing-class.t ├── abort-on-assert-failure.t ├── error-cast-weak-ptr-to-strong.t ├── error-expectation-failed.t ├── error-unsized-array-not-last-in-class.t ├── implicit-return.t ├── include.t ├── unspecified-template-destructor.t ├── abort-on-slice-fail3.t ├── array-constant.t ├── addable-qualifiers.t ├── array-length-dynamic.t ├── bitwise.t ├── include-syntax-error-after-included-file.t ├── error-implicit-void-return.t ├── error-non-static-method-called-statically.t ├── error-raw-ptr-array-cast-to-smart.t ├── error-array-size-non-integer.t ├── cast-uint-to-float.t ├── inline-file.t ├── type-inference-in-template.t ├── do-test.t ├── error-missing-this-qualifier.t ├── vector-store-by-index.t ├── error-allocate-class-with-unsized-array-without-length.t ├── indexed-bracketed-expr.t ├── ushort.t ├── array-assign.t ├── byte-vector.t ├── error-invalid-forward-decl.t ├── error-non-removable-qualifiers.t ├── field-shadows-global.t ├── include-twice.t ├── ubyte-vector.t ├── double.t ├── short-vector.t ├── fabs.t ├── store-null.t ├── array-length-static.t ├── error-missing-sampleable-qualifier.t ├── error-wrong-named-param.t ├── scope-test.t ├── error-named-param-missing-one.t ├── recursive-template-instantiation.t ├── cast-static-array-to-dynamic.t ├── include-twice-by-different-paths.t ├── list-init-array.t ├── simple.t ├── field-default-value.t ├── if-stmt.t ├── matrix.t ├── allocate-in-class-initializer.t ├── buffer-freed-with-mapped-data.t ├── abort-on-weak-null-deref.t ├── static-method.t ├── ushort-vector.t ├── recursive-type.t ├── bool-constants.t ├── control-flow.t ├── error-field-access-from-static-method.t ├── for-stmt.t ├── uint.t ├── list-init-class.t ├── array-class.t ├── decl-test.t ├── later-class-field.t ├── named-param.t ├── constructor.t ├── error-widen-weak-ptr-short-to-weak-ptr-int.t ├── static-method-with-args.t ├── buffer-double-map.t ├── early-return-int.t ├── list-init-vector-arg.t ├── early-return-bool.t ├── error-partial-template.t ├── local-var-do.t ├── loop.t ├── named-param-default-value.t ├── test.t ├── constructor-with-default-arg.t ├── list-init-class-arg.t ├── list-init-default-class-arg.t ├── local-var-while.t ├── new.t ├── cast-int-vector-to-float-vector.t ├── enum-default-value.t ├── forward-field.t ├── templated-class-with-auto-formal-arg.t ├── aggregate-return.t ├── error-allocate-raw-ptr.t ├── inc-dec-float.t ├── inc-dec-byte.t ├── inc-dec-short.t ├── vector-constructors.t ├── vector-initializer.t ├── allocate-unsized-class.t ├── list-init-inherited-field.t ├── cast-uint-vector-to-float-vector.t ├── file-location.t ├── list-default-init-aggregated-class.t ├── vector-scalar-mul-div.t ├── error-invalid-return-value.t ├── widen-weak-ptr-to-raw-ptr.t ├── class-initializer.t ├── method.t ├── templated-class-on-primitive-type.t ├── field-store.t ├── override.t ├── stack-method-call.t ├── error-return-raw-ptr.t ├── error-shader-validation.t ├── inherited-field.t ├── templated-class-initializer.t ├── arrays.t ├── constructor-calls-initializer.t ├── constructor-with-explicit-initializer.t ├── worst-cast-ever.t ├── error-workgroup-size.t ├── vector-array-access.t ├── class-constructor-calls-constructor.t ├── string-conversions.t ├── templated-derived-class.t ├── list-init-aggregated-class.t ├── error-stack-allocate-raw-ptr-aggregate.t ├── field-access.t ├── list-init-padded-class.t ├── vector-binop.t ├── error-listexpr-mismatch.t ├── vector-constructors3.t ├── array-float.t ├── complex-method.t ├── file-location-default-arg.t ├── overload.t ├── templated-class.t ├── chained-method-call.t ├── enum.t ├── method-chained.t ├── templated-derived-class-with-shader.t ├── increment-with-side-effects.t ├── chained-array-access.t ├── post-increment-with-side-effects.t ├── list-init-array-arg.t ├── null-ptr.t ├── templated-vector.t ├── destructor.t ├── error-index-buffer-get.t ├── raw-ptr.t ├── list-init-vector.t ├── spirv-call-graph.t ├── templated-on-class-and-primitive-type.t ├── list-init-matrix.t ├── templated-matrix.t ├── matrix-constructor.t ├── error-texture-from-buffer-incorrect-format.t ├── dereference.t ├── array-float4.t ├── destructor-set-null.t ├── error-validate-bind-group.t ├── templated-class-with-auto-field.t ├── matrix-array-access.t ├── error-non-addable-qualifiers.t ├── spirv-if-stmt.t ├── error-swizzle.t ├── error-assign-padded-array.t ├── error-invalid-class-casts.t ├── class-constructor.t ├── mutual-recursion.t ├── vector-constructors4.t ├── matrix-initializer.t ├── slice.t ├── test.sh ├── image.t ├── array-initialization.t ├── BUILD.gn ├── unfold-vector.t ├── indexed-method-return.t ├── spirv-uint.t ├── compute-simple.t ├── spirv-insert-element.t ├── swizzle-store.t ├── compute-empty-class.t ├── removable-qualifiers.t ├── compute-vector-cast.t ├── compute-swizzle.t ├── interactive │ ├── two-windows.t │ ├── triangle-with-inherited-vertex-shader.t │ ├── shader-method-call.t │ ├── triangle-with-vertex-helper.t │ ├── triangle-vertex-input-parameter.t │ ├── gouraud-separate-vertex-buffers.t │ ├── gouraud-separate-vertex-buffers-parent-class.t │ ├── uniform-with-padded-array.t │ ├── index-buffer.t │ ├── index-buffer-short.t │ ├── uniform-with-padded-class.t │ ├── uniform-triangle.t │ ├── blending.t │ ├── compute.t │ └── bind-group.t ├── constant-folding.t ├── test.py ├── error-validate.t ├── compute-pass-ptr-to-element.t ├── texture-size.t ├── compute-builtins.t ├── unfilterable.t └── error-validate-buffer.t ├── tools ├── toucan.keystore ├── git-sync-deps.bat ├── first-dir-entry.py ├── run.py ├── git-sync-deps ├── unixify.py ├── run-llvm-config ├── vswhere.py ├── fetch-win-flex-bison.py ├── make-ipa.py └── dragon-massager.py ├── bench ├── bench_mulf.t ├── bench_addf.t ├── bench_exp.t ├── bench_add4f.t ├── bench_muli.t ├── bench_mul4f.t ├── bench_mul4f_while.t ├── bench_mul3f.t ├── dynamic_array_float.t ├── dynamic_array_int.t ├── array_float4.t ├── bench_mat4f.t ├── array_float4_unroll.t ├── native1.cc ├── array_float_unrolled.t ├── array_float.cc ├── array_float_unrolled.cc └── array_vec4f.cc ├── third_party ├── build │ └── libjpeg-turbo │ │ ├── README.md │ │ └── LICENSE.md ├── android_native_app_glue │ ├── README │ ├── NOTICE │ └── BUILD.gn └── skia │ ├── LICENSE │ └── bin │ └── fetch-gn ├── AUTHORS ├── .clang-format ├── samples ├── include │ ├── cubic.t │ ├── cube-loader.t │ ├── tex-coord-utils.t │ ├── quaternion.t │ ├── event-handler.t │ └── cube.t ├── window.t ├── main.cc ├── triangle.t ├── android_main.cc └── gouraud.t ├── .gitignore ├── .gn ├── api ├── api_android.h ├── init_types.h ├── init_api.h └── api_internal.h ├── gn ├── rm.py ├── cp.py └── ar.py ├── BUILD.gn ├── emscripten └── BUILD.gn ├── .emscripten ├── utils └── hash_pair.h ├── ast ├── file_location.cc ├── BUILD.gn ├── file_location.h ├── constant_folder.h ├── api_validator.h ├── native_class.cc ├── type_replacement_pass.h ├── native_class.h └── symbol.h ├── parser ├── lexer.h ├── parser.h └── BUILD.gn ├── bindings ├── BUILD.gn └── gen_bindings.h ├── codegen └── BUILD.gn ├── CONTRIBUTING.md └── TODO /test/empty.t: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/foo.txt: -------------------------------------------------------------------------------- 1 | abc 2 | -------------------------------------------------------------------------------- /test/abort.t: -------------------------------------------------------------------------------- 1 | System.Abort(); 2 | -------------------------------------------------------------------------------- /test/really-simple.t: -------------------------------------------------------------------------------- 1 | return; 2 | -------------------------------------------------------------------------------- /test/error-return-int-from-main.t: -------------------------------------------------------------------------------- 1 | return 1; 2 | -------------------------------------------------------------------------------- /test/hello.t: -------------------------------------------------------------------------------- 1 | System.PrintLine("Hello, world."); 2 | -------------------------------------------------------------------------------- /test/error-allocate-unsized-array.t: -------------------------------------------------------------------------------- 1 | var a = new []int; 2 | -------------------------------------------------------------------------------- /test/error-dereference.t: -------------------------------------------------------------------------------- 1 | var f = 3.0; 2 | var r = f:; 3 | -------------------------------------------------------------------------------- /test/error-raw-ptr-must-be-initialized.t: -------------------------------------------------------------------------------- 1 | var a : ∫ 2 | -------------------------------------------------------------------------------- /test/include/include-fiveclass.t: -------------------------------------------------------------------------------- 1 | include "fiveclass.t" 2 | -------------------------------------------------------------------------------- /test/include/syntax-error.t: -------------------------------------------------------------------------------- 1 | 2 | bogus bogus bogus; 3 | -------------------------------------------------------------------------------- /test/error-include-not-found.t: -------------------------------------------------------------------------------- 1 | include "include/bogus.t" 2 | -------------------------------------------------------------------------------- /test/error-missing-parent-class.t: -------------------------------------------------------------------------------- 1 | class Foo : Bar { 2 | }; 3 | -------------------------------------------------------------------------------- /test/error-widen-null-to-raw-ptr.t: -------------------------------------------------------------------------------- 1 | var a : &int = null; 2 | -------------------------------------------------------------------------------- /test/abort-on-strong-null-deref.t: -------------------------------------------------------------------------------- 1 | var a : *int; 2 | var b = a:; 3 | -------------------------------------------------------------------------------- /test/abort-out-of-bounds-array.t: -------------------------------------------------------------------------------- 1 | var a : [1]int; 2 | a[1] = 42; 3 | -------------------------------------------------------------------------------- /test/error-hex-literal-too-large.t: -------------------------------------------------------------------------------- 1 | var a : uint = 0x100000000; 2 | -------------------------------------------------------------------------------- /test/error-uint-literal-too-large.t: -------------------------------------------------------------------------------- 1 | var a : uint = 5000000000u; 2 | -------------------------------------------------------------------------------- /test/abort-out-of-bounds-vector.t: -------------------------------------------------------------------------------- 1 | var a : float<3>; 2 | a[-1] = 42.0; 3 | -------------------------------------------------------------------------------- /test/error-forward-var.t: -------------------------------------------------------------------------------- 1 | var b : float = a; 2 | var a : float = 3.0; 3 | -------------------------------------------------------------------------------- /test/error-stack-allocate-unsized-array.t: -------------------------------------------------------------------------------- 1 | var invalidArray : []int; 2 | -------------------------------------------------------------------------------- /test/error-store-to-length.t: -------------------------------------------------------------------------------- 1 | var f = [5] new float; 2 | f.length = 0; 3 | -------------------------------------------------------------------------------- /test/abort-out-of-bounds-matrix.t: -------------------------------------------------------------------------------- 1 | var m : double<3,3>; 2 | m[3][2] = 1.0; 3 | -------------------------------------------------------------------------------- /test/duplicate-method.t: -------------------------------------------------------------------------------- 1 | class Foo { 2 | bar() {} 3 | bar() {} 4 | }; 5 | -------------------------------------------------------------------------------- /test/error-unknown-param-type.t: -------------------------------------------------------------------------------- 1 | class Foo { 2 | bar(b : Baz) {} 3 | }; 4 | -------------------------------------------------------------------------------- /test/abort-out-of-bounds-heap-array.t: -------------------------------------------------------------------------------- 1 | var a = [5] new ubyte; 2 | a[5] = 0ub; 3 | -------------------------------------------------------------------------------- /test/duplicate-var.t: -------------------------------------------------------------------------------- 1 | class Foo { 2 | var x : int; 3 | var x : int; 4 | }; 5 | -------------------------------------------------------------------------------- /test/error-syntax-error-in-included-file.t: -------------------------------------------------------------------------------- 1 | include "include/syntax-error.t" 2 | -------------------------------------------------------------------------------- /test/hello-split.t: -------------------------------------------------------------------------------- 1 | System.Print("Hello, "); 2 | System.PrintLine("world."); 3 | -------------------------------------------------------------------------------- /test/error-duplicate-enum.t: -------------------------------------------------------------------------------- 1 | enum E {} 2 | enum E {} 3 | class C {} 4 | enum C {} 5 | -------------------------------------------------------------------------------- /test/error-int-literal-too-large.t: -------------------------------------------------------------------------------- 1 | var a : int = 2147483648; 2 | var r = (float) a; 3 | -------------------------------------------------------------------------------- /test/abort-on-slice-fail1.t: -------------------------------------------------------------------------------- 1 | var array = [3]int{0, 1, 2}; 2 | var slice = &array[-1..]; 3 | -------------------------------------------------------------------------------- /test/abort-on-slice-fail2.t: -------------------------------------------------------------------------------- 1 | var array = [3]int{0, 1, 2}; 2 | var slice = &array[..4]; 3 | -------------------------------------------------------------------------------- /test/error-constructor-not-found.t: -------------------------------------------------------------------------------- 1 | var tex = new sampleable Texture2D(2, 2); 2 | -------------------------------------------------------------------------------- /test/error-unknown-return-type.t: -------------------------------------------------------------------------------- 1 | class Foo { 2 | bar() : Bar { return Bar{}; } 3 | }; 4 | -------------------------------------------------------------------------------- /test/include/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/toucan/HEAD/test/include/small.jpg -------------------------------------------------------------------------------- /tools/toucan.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/toucan/HEAD/tools/toucan.keystore -------------------------------------------------------------------------------- /test/error-missing-field.t: -------------------------------------------------------------------------------- 1 | class Foo { 2 | }; 3 | 4 | var foo = new Foo; 5 | var r = foo.zzz; 6 | -------------------------------------------------------------------------------- /test/error-raw-ptr-cast-to-smart.t: -------------------------------------------------------------------------------- 1 | var r = 42; 2 | var wp = (^int) &r; 3 | var sp = (*int) &r; 4 | -------------------------------------------------------------------------------- /test/unary-minus.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var i = 4; 4 | Test.Expect(-i == -4); 5 | -------------------------------------------------------------------------------- /test/byte.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var a : byte = -3b; 4 | Test.Expect((int) a == -3); 5 | -------------------------------------------------------------------------------- /test/error-missing-method.t: -------------------------------------------------------------------------------- 1 | class Foo { 2 | }; 3 | 4 | var foo = new Foo; 5 | var r = foo.zzz(); 6 | -------------------------------------------------------------------------------- /test/error-new-with-missing-constructor.t: -------------------------------------------------------------------------------- 1 | class C { 2 | C(); 3 | } 4 | 5 | var a = new C(42); 6 | -------------------------------------------------------------------------------- /test/include/fiveclass.t: -------------------------------------------------------------------------------- 1 | class C { 2 | static m() : float { 3 | return 5.0; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/short.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var s : short = 3s; 4 | Test.Expect((int) s == 3); 5 | -------------------------------------------------------------------------------- /test/ubyte.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var a : ubyte = 3ub; 4 | Test.Expect((int) a == 3); 5 | -------------------------------------------------------------------------------- /test/binop-widen.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var a = 3u + (uint) -1; 4 | Test.Expect(a == 2); 5 | -------------------------------------------------------------------------------- /test/cast-int-to-float.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var a = 3; 4 | Test.Expect((float) a == 3.0); 5 | -------------------------------------------------------------------------------- /test/error-missing-class.t: -------------------------------------------------------------------------------- 1 | class Foo { 2 | baz() { 3 | Blargh b = new Blargh(); 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /test/abort-on-assert-failure.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | Test.Assert(true); 4 | Test.Assert(false); 5 | -------------------------------------------------------------------------------- /test/error-cast-weak-ptr-to-strong.t: -------------------------------------------------------------------------------- 1 | var sp = new int(); 2 | var wp = (^int) sp; 3 | var newSP = (*int) wp; 4 | -------------------------------------------------------------------------------- /test/error-expectation-failed.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | Test.Expect(true); 4 | Test.Expect(false); 5 | -------------------------------------------------------------------------------- /test/error-unsized-array-not-last-in-class.t: -------------------------------------------------------------------------------- 1 | class C { 2 | var array : []int; 3 | var f : float; 4 | }; 5 | -------------------------------------------------------------------------------- /test/implicit-return.t: -------------------------------------------------------------------------------- 1 | class Foo { 2 | foo() { 3 | } 4 | }; 5 | 6 | var foo = new Foo; 7 | foo.foo(); 8 | -------------------------------------------------------------------------------- /test/include.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | include "include/fiveclass.t" 3 | 4 | Test.Expect(C.m() == 5.0); 5 | -------------------------------------------------------------------------------- /test/unspecified-template-destructor.t: -------------------------------------------------------------------------------- 1 | class Template { 2 | } 3 | 4 | var removed = new Template; 5 | -------------------------------------------------------------------------------- /test/abort-on-slice-fail3.t: -------------------------------------------------------------------------------- 1 | var array = [1]int{0}; 2 | var slice1 = &array[0..0]; 3 | var slice2 = &slice1[0..0]; 4 | -------------------------------------------------------------------------------- /test/array-constant.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var a = [4]int(4, 3, 2, 1); 4 | Test.Expect(a[1] == 3); 5 | -------------------------------------------------------------------------------- /test/addable-qualifiers.t: -------------------------------------------------------------------------------- 1 | var f : *float; 2 | 3 | var rf : *readonly float = f; 4 | var wf : *writeonly float = f; 5 | -------------------------------------------------------------------------------- /test/array-length-dynamic.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var f = [3] new float; 4 | Test.Expect(f.length == 3); 5 | -------------------------------------------------------------------------------- /test/bitwise.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var r : int = (((1 | 4) + (6 & 2)) ^ 15); 4 | Test.Expect(r == 8); 5 | -------------------------------------------------------------------------------- /test/include-syntax-error-after-included-file.t: -------------------------------------------------------------------------------- 1 | include "include/fiveclass.t" 2 | var a = 2; 3 | bogus bogus bogus; 4 | -------------------------------------------------------------------------------- /test/error-implicit-void-return.t: -------------------------------------------------------------------------------- 1 | class Foo { 2 | foo() : int { 3 | } 4 | }; 5 | 6 | var foo = new Foo; 7 | foo.foo(); 8 | -------------------------------------------------------------------------------- /test/error-non-static-method-called-statically.t: -------------------------------------------------------------------------------- 1 | class Foo { 2 | bar() : float { return 1.0; } 3 | }; 4 | 5 | Foo.bar(); 6 | -------------------------------------------------------------------------------- /test/error-raw-ptr-array-cast-to-smart.t: -------------------------------------------------------------------------------- 1 | var r = [3] int(1, 42, -1); 2 | var wp = (^[]int) &r; 3 | var sp = (*[]int) &r; 4 | -------------------------------------------------------------------------------- /test/error-array-size-non-integer.t: -------------------------------------------------------------------------------- 1 | var i = 5; 2 | var j = 6; 3 | var b : [i]int; 4 | var c : [i+j]int; 5 | var d : [3.0]int; 6 | -------------------------------------------------------------------------------- /test/cast-uint-to-float.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var a : uint = 3000000000u; 4 | Test.Expect((float) a == 3000000000.0); 5 | -------------------------------------------------------------------------------- /test/inline-file.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var t : ^[]ubyte = inline("test/foo.txt"); 4 | Test.Expect((int) t[0] == 97); 5 | -------------------------------------------------------------------------------- /test/type-inference-in-template.t: -------------------------------------------------------------------------------- 1 | class C { 2 | Func() { 3 | var i = new int; 4 | } 5 | } 6 | 7 | var c = new C; 8 | -------------------------------------------------------------------------------- /bench/bench_mulf.t: -------------------------------------------------------------------------------- 1 | float a = 1.3, b = 2.7; 2 | float c = 0.0; 3 | for(int i = 0; i < 10000000; ++i) { 4 | a += b; 5 | } 6 | return a; 7 | -------------------------------------------------------------------------------- /test/do-test.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var f = 1.0; 4 | do { 5 | f += 1.0; 6 | } while (f < 10.0); 7 | Test.Expect(f == 10.0); 8 | -------------------------------------------------------------------------------- /test/error-missing-this-qualifier.t: -------------------------------------------------------------------------------- 1 | class Foo { 2 | bar(i : int) uniform; 3 | }; 4 | 5 | var f : Foo; 6 | f.bar(i = 42); 7 | f.bar(42); 8 | -------------------------------------------------------------------------------- /test/vector-store-by-index.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var m : float<4>; 4 | m[1] = 432.0; 5 | 6 | Test.Expect(m[1] == 432.0); 7 | -------------------------------------------------------------------------------- /test/error-allocate-class-with-unsized-array-without-length.t: -------------------------------------------------------------------------------- 1 | class C { 2 | var f : float; 3 | var array : []int; 4 | }; 5 | var c = new C; 6 | -------------------------------------------------------------------------------- /test/indexed-bracketed-expr.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var foo : [10]float; 4 | foo[9] = 4321.0; 5 | Test.Expect(foo[9] == 4321.0); 6 | -------------------------------------------------------------------------------- /test/ushort.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var s : ushort = 65535us; 4 | Test.Expect((uint) s == 65535u); 5 | Test.Expect((int) s == -1); 6 | -------------------------------------------------------------------------------- /test/array-assign.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var a = [10] new float; 4 | a[9] = -4321.0; 5 | var b = a; 6 | Test.Expect(b[9] == -4321.0); 7 | -------------------------------------------------------------------------------- /test/byte-vector.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var a = byte<2>(-3b, -5b); 4 | Test.Expect((int) a.x == -3); 5 | Test.Expect((int) a.y == -5); 6 | -------------------------------------------------------------------------------- /test/error-invalid-forward-decl.t: -------------------------------------------------------------------------------- 1 | enum Foo { 2 | FOO, BAR 3 | } 4 | 5 | class Foo; 6 | class Bar; 7 | 8 | enum Bar { 9 | BAZ 10 | } 11 | -------------------------------------------------------------------------------- /test/error-non-removable-qualifiers.t: -------------------------------------------------------------------------------- 1 | var rf : readonly float; 2 | var wf : writeonly float; 3 | 4 | var f : &float = &rf; 5 | var g : &float = &wf; 6 | -------------------------------------------------------------------------------- /test/field-shadows-global.t: -------------------------------------------------------------------------------- 1 | var foo = 3; 2 | 3 | class C { 4 | main() : float { 5 | return foo; 6 | } 7 | var foo : float = 3.0; 8 | } 9 | -------------------------------------------------------------------------------- /test/include-twice.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | include "include/fiveclass.t" 3 | include "include/fiveclass.t" 4 | 5 | Test.Expect(C.m() == 5.0); 6 | -------------------------------------------------------------------------------- /test/ubyte-vector.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var a = ubyte<2>(5ub, 3ub); 4 | Test.Expect((int) a.x == 5); 5 | Test.Expect((int) a.y == 3); 6 | -------------------------------------------------------------------------------- /test/double.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var a = 2.0d; 4 | var b : double; 5 | var c : double; 6 | b = 3.0d; 7 | c = a * b; 8 | Test.Expect(c == 6.0d); 9 | -------------------------------------------------------------------------------- /test/short-vector.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var a = short<2>(-3s, 32767s); 4 | Test.Expect((int) a.x == -3); 5 | Test.Expect((int) a.y == 32767); 6 | -------------------------------------------------------------------------------- /test/fabs.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | Test.Expect(Math.fabs(-3.0) == 3.0); 4 | Test.Expect(Math.fabs(3.0) == 3.0); 5 | Test.Expect(Math.fabs(0.0) == 0.0); 6 | -------------------------------------------------------------------------------- /test/store-null.t: -------------------------------------------------------------------------------- 1 | class P {} 2 | class Q { 3 | Q(p : *P) { 4 | mP = p; 5 | } 6 | var mP : *P; 7 | } 8 | var p = new P; 9 | var q = new Q(null); 10 | -------------------------------------------------------------------------------- /bench/bench_addf.t: -------------------------------------------------------------------------------- 1 | int i; 2 | float a; 3 | float c; 4 | a = 0.0000001; 5 | c = 0.0; 6 | for(i = 0; i < 1000000000; ++i) { 7 | c += a; 8 | } 9 | return c; 10 | -------------------------------------------------------------------------------- /bench/bench_exp.t: -------------------------------------------------------------------------------- 1 | int i; 2 | float a; 3 | float c; 4 | a = 1.0000001; 5 | c = 1.0; 6 | for(i = 0; i < 100000000; ++i) { 7 | c = a * c; 8 | } 9 | return c; 10 | -------------------------------------------------------------------------------- /test/array-length-static.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var f : [5]float; 4 | Test.Expect(f.length == 5); 5 | 6 | var pf = &f; 7 | Test.Expect(pf.length == 5); 8 | -------------------------------------------------------------------------------- /test/error-missing-sampleable-qualifier.t: -------------------------------------------------------------------------------- 1 | var device = new Device(); 2 | var tex = new Texture2D(device, {2, 2}); 3 | var view = tex.CreateSampleableView(); 4 | -------------------------------------------------------------------------------- /test/error-wrong-named-param.t: -------------------------------------------------------------------------------- 1 | class Bar { 2 | static Foo(i : int, f : float) : float { 3 | return f - (float) i; 4 | } 5 | } 6 | 7 | Bar.Foo(b = 3.0, a = 1); 8 | -------------------------------------------------------------------------------- /test/scope-test.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var x = 3.0; 4 | var y : float; 5 | { 6 | var z = x * 2.0; 7 | y = z; 8 | } 9 | Test.Expect(y == 6.0); 10 | -------------------------------------------------------------------------------- /test/error-named-param-missing-one.t: -------------------------------------------------------------------------------- 1 | class Bar { 2 | static Foo(i : int, f : float) : float { 3 | return f - (float) i; 4 | } 5 | } 6 | 7 | var r = Bar.Foo(f = 3.0); 8 | -------------------------------------------------------------------------------- /test/recursive-template-instantiation.t: -------------------------------------------------------------------------------- 1 | class A {} 2 | 3 | class B : A {} 4 | 5 | class C { 6 | Set(value : U:T) {} 7 | } 8 | 9 | var c = C{}; 10 | -------------------------------------------------------------------------------- /test/cast-static-array-to-dynamic.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var a = [2]float(-2.0, 4.0); 4 | var b = &a; 5 | Test.Expect(b[0] == -2.0); 6 | Test.Expect(b[1] == 4.0); 7 | -------------------------------------------------------------------------------- /test/include-twice-by-different-paths.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | include "include/fiveclass.t" 3 | include "include/include-fiveclass.t" 4 | 5 | Test.Expect(C.m() == 5.0); 6 | -------------------------------------------------------------------------------- /test/list-init-array.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var a : [3]int; 4 | a = { 3, 2, 1 }; 5 | Test.Expect(a[0] == 3); 6 | Test.Expect(a[1] == 2); 7 | Test.Expect(a[2] == 1); 8 | -------------------------------------------------------------------------------- /test/simple.t: -------------------------------------------------------------------------------- 1 | include "include/string.t" 2 | 3 | var a = 2; 4 | var b : int; 5 | var c : int; 6 | b = 3; 7 | c = a * b; 8 | 9 | System.PrintLine(String.From(c).Get()); 10 | -------------------------------------------------------------------------------- /test/field-default-value.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Foo { 4 | var i : int; 5 | var f = 42.0; 6 | }; 7 | 8 | var foo : Foo; 9 | Test.Expect(foo.f == 42.0); 10 | -------------------------------------------------------------------------------- /test/if-stmt.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var f : float; 4 | var i = 3; 5 | if (i > 1) { 6 | f = 3.0; 7 | } else { 8 | f = 4.0; 9 | } 10 | Test.Expect(f == 3.0); 11 | -------------------------------------------------------------------------------- /test/matrix.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var m : float<4, 4>; 4 | m[3].w = 432.0; 5 | m[1][0] = 123.0; 6 | 7 | Test.Expect(m[3].w == 432.0); 8 | Test.Expect(m[1][0] == 123.0); 9 | -------------------------------------------------------------------------------- /test/allocate-in-class-initializer.t: -------------------------------------------------------------------------------- 1 | include "test.t" 2 | 3 | class C { 4 | var a : *int; 5 | } 6 | 7 | var c = C{ new int }; 8 | 9 | c.a: = 42; 10 | Test.Expect(c.a: == 42); 11 | -------------------------------------------------------------------------------- /test/buffer-freed-with-mapped-data.t: -------------------------------------------------------------------------------- 1 | var device = new Device(); 2 | var buffer = new hostwriteable Buffer(device); 3 | var data = buffer.MapWrite(); 4 | buffer = null; 5 | data: = 42; 6 | -------------------------------------------------------------------------------- /bench/bench_add4f.t: -------------------------------------------------------------------------------- 1 | float4 a; 2 | float4 b; 3 | a = float4(1.0, 2.0, 3.0, 4.0); 4 | b = float4(0.0, 0.0, 0.0, 0.0); 5 | for (int i = 0; i < 1000000000; ++i) { 6 | b += a; 7 | } 8 | return b.w; 9 | -------------------------------------------------------------------------------- /test/abort-on-weak-null-deref.t: -------------------------------------------------------------------------------- 1 | include "include/string.t" 2 | var pi = new int; 3 | var wpi : ^int = pi; 4 | pi = null; 5 | var result = wpi:; 6 | System.PrintLine(String.From(result).Get()); 7 | -------------------------------------------------------------------------------- /test/static-method.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Foo { 4 | static whee() : float { 5 | return -1234.0; 6 | } 7 | }; 8 | 9 | Test.Expect(Foo.whee() == -1234.0); 10 | -------------------------------------------------------------------------------- /test/ushort-vector.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var a = ushort<2>(5us, 65535us); 4 | Test.Expect((uint) a.x == 5); 5 | Test.Expect((uint) a.y == 65535); 6 | Test.Expect((int) a.y == -1); 7 | -------------------------------------------------------------------------------- /test/recursive-type.t: -------------------------------------------------------------------------------- 1 | class C { 2 | var c : ^C; 3 | } 4 | 5 | class E; 6 | 7 | class D { 8 | var e : ^E; 9 | } 10 | 11 | class E { 12 | var d : ^D; 13 | } 14 | 15 | var c = new C; 16 | -------------------------------------------------------------------------------- /test/bool-constants.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var a : bool = true; 4 | var b : bool = false; 5 | Test.Expect(a != b); 6 | Test.Expect(b != a); 7 | Test.Expect(a == a); 8 | Test.Expect(b == b); 9 | -------------------------------------------------------------------------------- /test/control-flow.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var i : int; 4 | var f : float; 5 | i = 1; 6 | if (i < 1) { 7 | f = -5.8; 8 | } else { 9 | f = 3.2; 10 | } 11 | Test.Expect(f == 3.2); 12 | -------------------------------------------------------------------------------- /test/error-field-access-from-static-method.t: -------------------------------------------------------------------------------- 1 | class Foo { 2 | static bar() : float { 3 | return baz; 4 | } 5 | var baz : float; 6 | }; 7 | 8 | var foo = new Foo; 9 | foo.baz = -321.0; 10 | -------------------------------------------------------------------------------- /test/for-stmt.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var a = 1.0001; 4 | var b = 2.7; 5 | var c = 2.7; 6 | for(var i = 0; i < 1000; i = i + 1) { 7 | c = a * b; 8 | } 9 | Test.Expect(b == 2.7); 10 | -------------------------------------------------------------------------------- /test/uint.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var a : uint = 3; 4 | var b : uint = 3000000000u; 5 | Test.Expect(a < b); 6 | var c : int = 3; 7 | var d : int = (int) 3000000000u; 8 | Test.Expect(c > d); 9 | -------------------------------------------------------------------------------- /test/list-init-class.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class C { 4 | var i : int; 5 | var a = 42.0; 6 | }; 7 | 8 | var c = C{ 3, 5.0 }; 9 | Test.Expect(c.i == 3); 10 | Test.Expect(c.a == 5.0); 11 | -------------------------------------------------------------------------------- /test/array-class.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Foo { 4 | var x : int; 5 | var y : float; 6 | }; 7 | 8 | var foo = [100] new Foo; 9 | foo[23].y = 5.0; 10 | Test.Expect(foo[23].y == 5.0); 11 | -------------------------------------------------------------------------------- /test/decl-test.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var a : float; 4 | a = 3.0; 5 | var b : int; 6 | { 7 | var a : int; 8 | var aa : [3]int; 9 | var bb : [3]int; 10 | } 11 | Test.Expect(a == 3.0); 12 | -------------------------------------------------------------------------------- /bench/bench_muli.t: -------------------------------------------------------------------------------- 1 | int i; 2 | int a, b; 3 | a = 0; 4 | b = 2; 5 | for(i = 0; i < 1000000; ++i) { 6 | a += b; 7 | } 8 | float f = 0.0; 9 | while(a > 0) { 10 | f += 1.0; 11 | --a; 12 | } 13 | return f; 14 | -------------------------------------------------------------------------------- /test/later-class-field.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Bar; 4 | 5 | var b = new Bar; 6 | b.x = -3.0; 7 | Test.Expect(b.x == -3.0); 8 | return; 9 | 10 | class Bar { 11 | var x : float; 12 | }; 13 | -------------------------------------------------------------------------------- /test/named-param.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Bar { 4 | static Foo(i : int, f : float) : float { 5 | return f - (float) i; 6 | } 7 | } 8 | 9 | Test.Expect(Bar.Foo(f = 3.0, i = 1) == 2.0); 10 | -------------------------------------------------------------------------------- /test/constructor.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class C { 4 | C(v : float) { 5 | value = v; 6 | } 7 | var value : float; 8 | } 9 | 10 | var c = new C(3.14159); 11 | Test.Expect(c.value == 3.14159); 12 | -------------------------------------------------------------------------------- /test/error-widen-weak-ptr-short-to-weak-ptr-int.t: -------------------------------------------------------------------------------- 1 | include "test.t" 2 | 3 | var s = new short(); 4 | 5 | s: = 42s; 6 | 7 | var wpi = (^int) (^short) s; 8 | 9 | wpi: = 42; 10 | 11 | Test.Expect((int) s: == 42); 12 | -------------------------------------------------------------------------------- /test/static-method-with-args.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Foo { 4 | static whee(x : float, y : float) : float { 5 | return x * y; 6 | } 7 | }; 8 | 9 | Test.Expect(Foo.whee(2.0, 3.0) == 6.0); 10 | -------------------------------------------------------------------------------- /bench/bench_mul4f.t: -------------------------------------------------------------------------------- 1 | int i; 2 | float4 a; 3 | float4 b; 4 | float4 c; 5 | a = float4(1.5, 0.5, -1.5, 5.0); 6 | c = float4(1.0, 1.0, 1.0, 1.0); 7 | for(i = 0; i < 100000000; ++i) { 8 | c = a * c; 9 | } 10 | return c.x; 11 | -------------------------------------------------------------------------------- /test/buffer-double-map.t: -------------------------------------------------------------------------------- 1 | var device = new Device(); 2 | var buffer = new hostwriteable Buffer(device); 3 | var data1 = buffer.MapWrite(); 4 | var data2 = buffer.MapWrite(); 5 | data2: = 21; 6 | data2 = null; 7 | data1: = 42; 8 | -------------------------------------------------------------------------------- /test/early-return-int.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class C { 4 | static m() : float { 5 | if (1 == 2) { 6 | return 0.0; 7 | } 8 | return 1.0; 9 | } 10 | } 11 | Test.Expect(C.m() == 1.0); 12 | -------------------------------------------------------------------------------- /test/list-init-vector-arg.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class C { 4 | static M(v : float<4>) : float { 5 | return v.x; 6 | } 7 | } 8 | 9 | var r = C.M({3.0, 0.0, 1.0, 2.0}); 10 | Test.Expect(r == 3.0); 11 | -------------------------------------------------------------------------------- /test/early-return-bool.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class C { 4 | static m() : float { 5 | if (true == false) { 6 | return 0.0; 7 | } 8 | return 1.0; 9 | } 10 | } 11 | Test.Expect(C.m() == 1.0); 12 | -------------------------------------------------------------------------------- /test/error-partial-template.t: -------------------------------------------------------------------------------- 1 | class Foo { 2 | var t : T; 3 | var u : U; 4 | } 5 | 6 | var full : *Foo; 7 | var partial : *Foo; 8 | var noargs : *Foo; 9 | 10 | partial = full; 11 | noargs = full; 12 | -------------------------------------------------------------------------------- /test/local-var-do.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | var a = 0; 3 | var i = 5; 4 | do { 5 | var b = 1; 6 | var c = 2; 7 | a += c; 8 | --i; 9 | } while (i > 0); 10 | Test.Expect(i == 0); 11 | Test.Expect(a == 10); 12 | -------------------------------------------------------------------------------- /test/loop.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var i : int; 4 | var f : float; 5 | var g : float; 6 | f = 3.0; 7 | g = 1.1; 8 | for (i = 0; i < 100; i = i + 1) { 9 | f = f * g; 10 | } 11 | Test.Expect(f == 41341.914062); 12 | -------------------------------------------------------------------------------- /test/named-param-default-value.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Bar { 4 | static Foo(i : int = -5, f : float) : float { 5 | return f - (float) i; 6 | } 7 | } 8 | 9 | Test.Expect(Bar.Foo(f = 3.0) == 8.0); 10 | -------------------------------------------------------------------------------- /test/test.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var v = float<4>(5.0, 0.0, 2.0, 3.0) / float<4>(2.0, 2.0, 2.0, 2.0); 4 | Test.Expect(v.x == 2.5); 5 | Test.Expect(v.y == 0.0); 6 | Test.Expect(v.z == 1.0); 7 | Test.Expect(v.w == 1.5); 8 | -------------------------------------------------------------------------------- /test/constructor-with-default-arg.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class C { 4 | C(v : float = 3.0) { 5 | value = v; 6 | } 7 | var value : float; 8 | } 9 | 10 | var c = new C(); 11 | Test.Expect(c.value == 3.0); 12 | -------------------------------------------------------------------------------- /test/list-init-class-arg.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class C { 4 | clobber(c : &C) 5 | { 6 | f = c.f; 7 | } 8 | var f : float; 9 | } 10 | 11 | var c : C; 12 | c.clobber({42.0}); 13 | Test.Expect(c.f == 42.0); 14 | -------------------------------------------------------------------------------- /test/list-init-default-class-arg.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class C { 4 | var i = 42; 5 | } 6 | 7 | class D { 8 | static RunTest(c : &C = {}) { 9 | Test.Expect(c.i == 42); 10 | } 11 | } 12 | 13 | D.RunTest(); 14 | -------------------------------------------------------------------------------- /test/local-var-while.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var a = 0; 4 | var i = 5; 5 | while (i > 0) { 6 | var b = 1; 7 | var c = 2; 8 | a += c; 9 | --i; 10 | } 11 | Test.Expect(i == 0); 12 | Test.Expect(a == 10); 13 | -------------------------------------------------------------------------------- /test/new.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Foo { 4 | var zzz : [3]int; 5 | var a : float; 6 | }; 7 | var r : float; 8 | { 9 | var f = new Foo; 10 | f.a = -1234.0; 11 | r = f.a; 12 | } 13 | Test.Expect(r == -1234.0); 14 | -------------------------------------------------------------------------------- /bench/bench_mul4f_while.t: -------------------------------------------------------------------------------- 1 | int i; 2 | float4 a; 3 | float4 b; 4 | float4 c; 5 | a = float4(1.5, 0.5, -1.5, 5.0); 6 | c = float4(1.0, 1.0, 1.0, 1.0); 7 | i = 0; 8 | while(i < 100000000) { 9 | c *= a; 10 | ++i; 11 | } 12 | return c.x; 13 | -------------------------------------------------------------------------------- /test/cast-int-vector-to-float-vector.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var a = int<4>(-3, 101, 2, 0); 4 | var b = (float<4>) a; 5 | Test.Expect(b.x == -3.0); 6 | Test.Expect(b.y == 101.0); 7 | Test.Expect(b.z == 2.0); 8 | Test.Expect(b.w == 0.0); 9 | -------------------------------------------------------------------------------- /test/enum-default-value.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | enum Enum { Foo, Bar, Baz }; 4 | class A { 5 | var f = Enum.Bar; 6 | }; 7 | var a : A; 8 | Test.Expect(a.f == Enum.Bar); 9 | a.f = Enum.Foo; 10 | Test.Expect(a.f == Enum.Foo); 11 | -------------------------------------------------------------------------------- /test/forward-field.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Foo { 4 | bar() : float { 5 | return baz; 6 | } 7 | var baz : float; 8 | }; 9 | 10 | var foo = new Foo; 11 | foo.baz = -321.0; 12 | Test.Expect(foo.baz == -321.0); 13 | -------------------------------------------------------------------------------- /test/templated-class-with-auto-formal-arg.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | class C { 3 | static Foo(a = 3) : T { 4 | return (T) a; 5 | } 6 | } 7 | 8 | Test.Expect(C.Foo() == 3.0); 9 | Test.Expect(C.Foo(42) == 42.0); 10 | -------------------------------------------------------------------------------- /third_party/build/libjpeg-turbo/README.md: -------------------------------------------------------------------------------- 1 | - the jconfig.h and jconfigint.h files in this directory were initially generated by libjpeg-turbo's CMake build 2 | - these files are covered by the 3-clause BSD license in LICENSE.md in this directory. 3 | -------------------------------------------------------------------------------- /test/aggregate-return.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | class Foo { 3 | var value : float; 4 | static One() : Foo { 5 | var f = Foo{}; 6 | f.value = 1.0; 7 | return f; 8 | } 9 | } 10 | 11 | Test.Expect(Foo.One().value == 1.0); 12 | -------------------------------------------------------------------------------- /test/error-allocate-raw-ptr.t: -------------------------------------------------------------------------------- 1 | class C { 2 | var f : float; 3 | var i : ∫ 4 | } 5 | 6 | var p0 = new ∫ 7 | var p1 = new *∫ 8 | var p2 = new ^∫ 9 | var p3 = new [3]∫ 10 | var p4 = new C{}; 11 | var p5 = new readonly C{}; 12 | -------------------------------------------------------------------------------- /test/inc-dec-float.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var a = 3.0; 4 | var b = 2.0; 5 | var c = 0.0; 6 | var d = 1.0; 7 | 8 | Test.Expect(a++ == 3.0); 9 | Test.Expect(--b == 1.0); 10 | Test.Expect(++c == 1.0); 11 | Test.Expect(d-- == 1.0); 12 | -------------------------------------------------------------------------------- /bench/bench_mul3f.t: -------------------------------------------------------------------------------- 1 | int i; 2 | float3 a; 3 | float3 b; 4 | float3 c; 5 | a = float3(1.5, 0.5, -1.5); 6 | b = float3(2.5, -1.5, 0.5); 7 | c = float3(0.0, 0.0, 0.0); 8 | for(i = 0; i < 10000000; i = i + 1) { 9 | c = a * b; 10 | } 11 | return c.x; 12 | -------------------------------------------------------------------------------- /test/inc-dec-byte.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var a = 3b; 4 | var b = 2b; 5 | var c = 0b; 6 | var d = 1b; 7 | Test.Expect((int) a++ == 3); 8 | Test.Expect((int) --b == 1); 9 | Test.Expect((int) ++c == 1); 10 | Test.Expect((int) d-- == 1); 11 | -------------------------------------------------------------------------------- /test/inc-dec-short.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var a = 3s; 4 | var b = 2s; 5 | var c = 0s; 6 | var d = 1s; 7 | Test.Expect((int) a++ == 3); 8 | Test.Expect((int) --b == 1); 9 | Test.Expect((int) ++c == 1); 10 | Test.Expect((int) d-- == 1); 11 | -------------------------------------------------------------------------------- /test/vector-constructors.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var v21 = float<2>(1.0); 4 | var v22 = float<2>(2.0, 3.0); 5 | 6 | Test.Expect(v21.x == 1.0); 7 | Test.Expect(v21.y == 1.0); 8 | Test.Expect(v22.x == 2.0); 9 | Test.Expect(v22.y == 3.0); 10 | -------------------------------------------------------------------------------- /test/vector-initializer.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var v21 = float<2>{1.0}; 4 | var v22 = float<2>{2.0, 3.0}; 5 | 6 | Test.Expect(v21.x == 1.0); 7 | Test.Expect(v21.y == 1.0); 8 | Test.Expect(v22.x == 2.0); 9 | Test.Expect(v22.y == 3.0); 10 | -------------------------------------------------------------------------------- /test/allocate-unsized-class.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class C { 4 | var f : float; 5 | var array : []int; 6 | }; 7 | var c = [5] new C; 8 | c.array[2] = 42; 9 | 10 | Test.Expect(c.array[2] == 42); 11 | Test.Expect(c.array.length == 5); 12 | -------------------------------------------------------------------------------- /test/list-init-inherited-field.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class C { 4 | var i : int; 5 | var a = 42.0; 6 | }; 7 | 8 | class D : C { 9 | } 10 | 11 | var d : D = { i = 3, a = 5.0 }; 12 | Test.Expect(d.i == 3); 13 | Test.Expect(d.a == 5.0); 14 | -------------------------------------------------------------------------------- /test/cast-uint-vector-to-float-vector.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var a = uint<4>(3u, 3000000000u, 2u, 0u); 4 | var b = (float<4>) a; 5 | Test.Expect(b.x == 3.0); 6 | Test.Expect(b.y == 3000000000.0); 7 | Test.Expect(b.z == 2.0); 8 | Test.Expect(b.w == 0.0); 9 | -------------------------------------------------------------------------------- /test/file-location.t: -------------------------------------------------------------------------------- 1 | include "include/string.t" 2 | 3 | var filename = System.GetSourceFile(); 4 | var line = System.GetSourceLine(); 5 | 6 | System.Print(filename); 7 | System.Print(":"); 8 | System.Print(String.From(line).Get()); 9 | System.PrintLine(""); 10 | -------------------------------------------------------------------------------- /test/list-default-init-aggregated-class.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class C { 4 | var i = 1; 5 | } 6 | 7 | class D { 8 | var c : C; 9 | } 10 | 11 | var c : C; 12 | Test.Expect(c.i == 1); 13 | 14 | var d : D = {}; 15 | Test.Expect(d.c.i == 1); 16 | -------------------------------------------------------------------------------- /test/vector-scalar-mul-div.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var x = float<2>(1.0, 2.0) * 2.0; 4 | var y = float<2>(3.0, 4.0) / 2.0; 5 | 6 | Test.Expect(x.x == 2.0); 7 | Test.Expect(x.y == 4.0); 8 | Test.Expect(y.x == 1.5); 9 | Test.Expect(y.y == 2.0); 10 | -------------------------------------------------------------------------------- /test/error-invalid-return-value.t: -------------------------------------------------------------------------------- 1 | class C { 2 | ReturnsWeakPtrToInt() : ^int { 3 | var a = 42; 4 | return &a; 5 | } 6 | 7 | ReturnsInt() : int { 8 | return 42.0; 9 | } 10 | 11 | ReturnsFloat() : float { 12 | return 42; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/widen-weak-ptr-to-raw-ptr.t: -------------------------------------------------------------------------------- 1 | include "test.t" 2 | 3 | var i = new int(); 4 | 5 | i: = 0; 6 | 7 | var wpi : ^int = i; 8 | var rpi : &int = wpi; 9 | 10 | i: = 42; 11 | 12 | Test.Expect(i: == 42); 13 | Test.Expect(wpi: == 42); 14 | Test.Expect(rpi == 42); 15 | -------------------------------------------------------------------------------- /test/class-initializer.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class C { 4 | C(_x : float, _y : float) : { y = _x, x = _y } {} 5 | var x : float; 6 | var y : float; 7 | } 8 | 9 | var c = C{21.0, 42.0}; 10 | Test.Expect(c.x == 21.0); 11 | Test.Expect(c.y == 42.0); 12 | -------------------------------------------------------------------------------- /test/method.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Foo { 4 | inc() { 5 | x = x + 1.0; 6 | return; 7 | } 8 | var x : float; 9 | }; 10 | 11 | var foo = new Foo; 12 | foo.x = 0.0; 13 | foo.inc(); 14 | foo.inc(); 15 | foo.inc(); 16 | Test.Expect(foo.x == 3.0); 17 | -------------------------------------------------------------------------------- /test/templated-class-on-primitive-type.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Template { 4 | var foo : T; 5 | set(t : T) { foo = t; } 6 | get() : T { return foo; } 7 | } 8 | 9 | var t = new Template; 10 | t.set(3.0); 11 | Test.Expect(t.get() == 3.0); 12 | -------------------------------------------------------------------------------- /test/field-store.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Bar; 4 | class Foo { 5 | var bar : *Bar; 6 | }; 7 | 8 | class Bar { 9 | var baz : float; 10 | }; 11 | 12 | var foo = new Foo; 13 | foo.bar = new Bar; 14 | foo.bar.baz = 2.0; 15 | Test.Expect(foo.bar.baz == 2.0); 16 | -------------------------------------------------------------------------------- /test/override.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Foo { 4 | func() : float { 5 | return 1234.0; 6 | } 7 | }; 8 | 9 | class Bar : Foo { 10 | func() : float { 11 | return 2345.0; 12 | } 13 | }; 14 | 15 | var b = new Bar; 16 | Test.Expect(b.func() == 2345.0); 17 | -------------------------------------------------------------------------------- /test/stack-method-call.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Foo { 4 | inc() { 5 | x = x + 1.0; 6 | return; 7 | } 8 | var x : float; 9 | }; 10 | 11 | var foo : Foo; 12 | foo.x = 0.0; 13 | foo.inc(); 14 | foo.inc(); 15 | foo.inc(); 16 | Test.Expect(foo.x == 3.0); 17 | -------------------------------------------------------------------------------- /test/error-return-raw-ptr.t: -------------------------------------------------------------------------------- 1 | class ContainsRaw { 2 | var i : ∫ 3 | } 4 | class C { 5 | m() : &int { var i : int; return &i; } 6 | } 7 | 8 | class D { 9 | m() : &[]int { return [3] new int; } 10 | } 11 | 12 | class F { 13 | m() : ContainsRaw { return ContainsRaw{}; } 14 | } 15 | -------------------------------------------------------------------------------- /test/error-shader-validation.t: -------------------------------------------------------------------------------- 1 | class NoNewInShaders { 2 | compute(1) main(cb : &ComputeBuiltins) { 3 | var i = new int; 4 | var a : [3]float; 5 | var slice = &a[1..3]; 6 | } 7 | } 8 | 9 | var device = new Device(); 10 | 11 | new ComputePipeline(device); 12 | -------------------------------------------------------------------------------- /test/inherited-field.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Foo { 4 | var f : float; 5 | }; 6 | class Bar : Foo { 7 | var g : float; 8 | sum() : float { 9 | return f + g; 10 | } 11 | }; 12 | var b = new Bar; 13 | b.f = 3.0; 14 | b.g = 2.0; 15 | Test.Expect(b.sum() == 5.0); 16 | -------------------------------------------------------------------------------- /test/templated-class-initializer.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class S { 4 | S(v : float) { 5 | value = v; 6 | } 7 | var value : float; 8 | } 9 | 10 | class Template { 11 | var value : T = T(5.0); 12 | } 13 | var foo : Template; 14 | Test.Expect(foo.value.value == 5.0); 15 | -------------------------------------------------------------------------------- /test/arrays.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var c : [3]int; 4 | var e : [3][3]float; 5 | e[2][1] = 5.0; 6 | var f = [3] new float; 7 | var g = [3] new [3]float; 8 | f[0] = 1234.0; 9 | g[2][1] = 3.0; 10 | Test.Expect(g[2][1] == 3.0); 11 | Test.Expect(f[0] == 1234.0); 12 | Test.Expect(e[2][1] == 5.0); 13 | -------------------------------------------------------------------------------- /test/constructor-calls-initializer.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class C { 4 | var x : int = 42; 5 | var y : int = 21; 6 | } 7 | 8 | var c1 : C; 9 | Test.Expect(c1.x == 42); 10 | Test.Expect(c1.y == 21); 11 | 12 | var c2 = new C; 13 | Test.Expect(c2.x == 42); 14 | Test.Expect(c2.y == 21); 15 | -------------------------------------------------------------------------------- /test/constructor-with-explicit-initializer.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class C { 4 | C(v1 : float, v2 : float) : { value2 = v1, value1 = v2 } {} 5 | var value1 : float, value2 : float; 6 | } 7 | 8 | var c = C(1.0, 2.0); 9 | Test.Expect(c.value1 == 2.0); 10 | Test.Expect(c.value2 == 1.0); 11 | -------------------------------------------------------------------------------- /test/worst-cast-ever.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Foo { 4 | static cast(x : int) : float { 5 | var y = 0.0; 6 | while (x > 0) { 7 | y += 1.0; 8 | --x; 9 | } 10 | return y; 11 | } 12 | }; 13 | 14 | var foo = new Foo; 15 | Test.Expect(foo.cast(42) == 42.0); 16 | -------------------------------------------------------------------------------- /test/error-workgroup-size.t: -------------------------------------------------------------------------------- 1 | class Foo { 2 | compute(1) cs1() {} 3 | compute(2, 1) cs21() {} 4 | compute(3, 2, 1) cs321() {} 5 | compute() fail_cs0() {} 6 | compute(1, 2, 3, 4) fail_cs1234() {} 7 | compute(false) fail_cs1() {} 8 | fragment(1) fail_fs1() {} 9 | vertex(1) fail_vs1() {} 10 | }; 11 | -------------------------------------------------------------------------------- /test/vector-array-access.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | var v : float<4>; 3 | var i0 = 0, i1 = 1, i2 = 2, i3 = 3; 4 | v[i0] = 5.0; 5 | v[i1] = 6.0; 6 | v[i2] = 7.0; 7 | v[i3] = 8.0; 8 | Test.Expect(v[i0] == 5.0); 9 | Test.Expect(v[i1] == 6.0); 10 | Test.Expect(v[i2] == 7.0); 11 | Test.Expect(v[i3] == 8.0); 12 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | # This is the list of Toucan authors for copyright purposes. 2 | # 3 | # This does not necessarily list everyone who has contributed code, since in 4 | # some cases, their employer may be the copyright holder. To see the full list 5 | # of contributors, see the revision history in source control. 6 | Google LLC 7 | -------------------------------------------------------------------------------- /bench/dynamic_array_float.t: -------------------------------------------------------------------------------- 1 | int outer_count = 1000000; 2 | float[] a = new float[1024]; 3 | for (int i = 0; i < a.length; ++i) { 4 | a[i] = 2000000.0; 5 | } 6 | for (int j = 0; j < outer_count; ++j) { 7 | for (int i = 0; i < a.length; ++i) { 8 | a[i] = a[i] * 1.00001 + 1.0; 9 | } 10 | } 11 | return a[0]; 12 | -------------------------------------------------------------------------------- /test/class-constructor-calls-constructor.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class C { 4 | C(_x : float, _y : float) : { x = _x + 5.0, y = _y + 2.0 } {} 5 | C(_x : float) : C(_x, _x) {} 6 | var x : float, y : float; 7 | } 8 | 9 | var c = C(40.0); 10 | Test.Expect(c.x == 45.0); 11 | Test.Expect(c.y == 42.0); 12 | -------------------------------------------------------------------------------- /test/string-conversions.t: -------------------------------------------------------------------------------- 1 | include "include/string.t" 2 | 3 | System.PrintLine(String.From(0).buffer); 4 | System.PrintLine(String.From(1).buffer); 5 | System.PrintLine(String.From(9).buffer); 6 | System.PrintLine(String.From(-1).buffer); 7 | System.PrintLine(String.From(12).buffer); 8 | System.PrintLine(String.From(123456789).buffer); 9 | -------------------------------------------------------------------------------- /test/templated-derived-class.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Base { 4 | Foo() : T { 5 | return (T) 42; 6 | } 7 | } 8 | 9 | class Derived : Base { 10 | } 11 | 12 | var ci = new Derived; 13 | Test.Expect(ci.Foo() == 42); 14 | 15 | var df = new Derived; 16 | Test.Expect(df.Foo() == 42.0); 17 | -------------------------------------------------------------------------------- /test/list-init-aggregated-class.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class C { 4 | var i : int; 5 | var a = 42.0; 6 | 7 | }; 8 | 9 | class D { 10 | var c : C; 11 | var f : float; 12 | } 13 | 14 | var d : D = { { 3, 5.0 }, 2.0 }; 15 | Test.Expect(d.c.i == 3); 16 | Test.Expect(d.c.a == 5.0); 17 | Test.Expect(d.f == 2.0); 18 | -------------------------------------------------------------------------------- /test/error-stack-allocate-raw-ptr-aggregate.t: -------------------------------------------------------------------------------- 1 | class C { 2 | var pi : ∫ 3 | } 4 | 5 | class D { 6 | var c : readonly C; 7 | } 8 | 9 | var i = 0; 10 | var ok = &i; 11 | var e0 = [3]&int{}; 12 | var e1 : [3]∫ 13 | var e2 = C{}; 14 | var e3 : C; 15 | var e4 : readonly C; 16 | var e5 : D; 17 | var e6 : [3]C; 18 | var e6 : [3]D; 19 | -------------------------------------------------------------------------------- /test/field-access.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Foo { 4 | var f : float; 5 | var vec : float<4>; 6 | }; 7 | 8 | var foo = new Foo; 9 | foo.vec = float<4>(1.0, 2.0, 3.0, 4.0); 10 | Test.Expect(foo.vec.x == 1.0); 11 | Test.Expect(foo.vec.y == 2.0); 12 | Test.Expect(foo.vec.z == 3.0); 13 | Test.Expect(foo.vec.w == 4.0); 14 | -------------------------------------------------------------------------------- /bench/dynamic_array_int.t: -------------------------------------------------------------------------------- 1 | { 2 | int outer_count = 1000000; 3 | int[] a = new int[1024]; 4 | for (int i = 0; i < a.length; ++i) { 5 | a[i] = 2000000; 6 | } 7 | for (int j = 0; j < outer_count; ++j) { 8 | for (int i = 0; i < a.length; ++i) { 9 | a[i] = a[i] * 2 + 1; 10 | } 11 | } 12 | return 3.0; // a[0]; 13 | } 14 | -------------------------------------------------------------------------------- /test/list-init-padded-class.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class C { 4 | var f : float; 5 | var v : float<4>; 6 | } 7 | 8 | var c : C = { 0.0, { 1.0, 2.0, 3.0, 4.0 } }; 9 | 10 | Test.Expect(c.f == 0.0); 11 | Test.Expect(c.v.x == 1.0); 12 | Test.Expect(c.v.y == 2.0); 13 | Test.Expect(c.v.z == 3.0); 14 | Test.Expect(c.v.w == 4.0); 15 | -------------------------------------------------------------------------------- /test/vector-binop.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var a = int<2>(0, 1); 4 | var b = int<2>(2, 1); 5 | var c = int<2>(3, 4); 6 | Test.Expect(Math.all(a == a)); 7 | Test.Expect(!Math.all(a == b)); 8 | Test.Expect(Math.any(a == b)); 9 | Test.Expect(!Math.any(a == c)); 10 | Test.Expect(!Math.any(a != a)); 11 | Test.Expect(!Math.all(a != b)); 12 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | # http://clang.llvm.org/docs/ClangFormatStyleOptions.html 2 | BasedOnStyle: Chromium 3 | 4 | ColumnLimit: 100 5 | 6 | AllowShortBlocksOnASingleLine: true 7 | AllowShortCaseLabelsOnASingleLine: true 8 | AllowShortFunctionsOnASingleLine: true 9 | AllowShortIfStatementsOnASingleLine: true 10 | 11 | AlignConsecutiveDeclarations: true 12 | -------------------------------------------------------------------------------- /test/error-listexpr-mismatch.t: -------------------------------------------------------------------------------- 1 | class C { 2 | var f : float; 3 | var v : float<2>; 4 | } 5 | 6 | var c : C; 7 | c = {}; // valid 8 | c = {1.0, {2.0, 3.0}}; // valid 9 | c = {{}, {2.0, 3.0}}; 10 | c = {{1}, {2.0, 3.0}}; 11 | c = {{1, 2}, {3.0, 4.0}}; 12 | c = {uint<2>{}, {3.0, 4.0}}; 13 | c = {1, {2.0, 3.0}}; 14 | c = {1ub}; 15 | -------------------------------------------------------------------------------- /test/vector-constructors3.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var v31 = float<3>(1.0); 4 | var v32 = float<3>(2.0, 3.0); 5 | var v33 = float<3>(4.0, 5.0, 6.0); 6 | 7 | Test.Expect(v31.x == 1.0); 8 | Test.Expect(v32.x == 2.0); 9 | Test.Expect(v32.y == 3.0); 10 | Test.Expect(v33.x == 4.0); 11 | Test.Expect(v33.y == 5.0); 12 | Test.Expect(v33.z == 6.0); 13 | -------------------------------------------------------------------------------- /test/array-float.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var outer_count = 200; 4 | var a : [1024]float; 5 | for (var i = 0; i < a.length; i++) { 6 | a[i] = 2000000.0; 7 | } 8 | for (var j = 0; j < outer_count; ++j) { 9 | for (var i = 0; i < a.length; ++i) { 10 | a[i] = a[i] * 1.00001 + 1.0; 11 | } 12 | } 13 | 14 | Test.Expect(a[0] == 2004203.875); 15 | -------------------------------------------------------------------------------- /test/complex-method.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Foo { 4 | static dot(arg1 : float<4>, arg2 : float<4>) : float { 5 | var tmp = arg1 * arg2; 6 | return tmp.x + tmp.y + tmp.z + tmp.w; 7 | } 8 | }; 9 | 10 | var foo = new Foo; 11 | var result = foo.dot(float<4>(1.0, 0.5, 0.0, 1.0), float<4>(0.5, 1.0, 0.0, 9.0)); 12 | Test.Expect(result == 10.0); 13 | -------------------------------------------------------------------------------- /test/file-location-default-arg.t: -------------------------------------------------------------------------------- 1 | include "include/string.t" 2 | 3 | class C { 4 | static f(filename : *[]ubyte = System.GetSourceFile(), line : int = System.GetSourceLine()) { 5 | System.Print(filename); 6 | System.Print(":"); 7 | System.Print(String.From(line).Get()); 8 | System.PrintLine(""); 9 | } 10 | } 11 | 12 | C.f(); 13 | C.f(); 14 | C.f(); 15 | -------------------------------------------------------------------------------- /test/overload.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Foo { 4 | bar(a : int) : float { 5 | var f = 0.0; 6 | for (; a > 0; --a) { 7 | f += 1.0; 8 | } 9 | return f; 10 | } 11 | bar(a : float) : float { 12 | return 0.0-a; 13 | } 14 | }; 15 | 16 | var f = new Foo; 17 | Test.Expect(f.bar(3) == 3.0); 18 | Test.Expect(f.bar(-4.0) == 4.0); 19 | -------------------------------------------------------------------------------- /test/templated-class.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Bar { 4 | get() : float { 5 | return 3.0; 6 | } 7 | } 8 | 9 | class Template { 10 | var foo : *T; 11 | set(t : *T) { foo = t; } 12 | get() : float { return foo.get(); } 13 | } 14 | 15 | var templateBar = new Template; 16 | templateBar.set(new Bar); 17 | Test.Expect(templateBar.get() == 3.0); 18 | -------------------------------------------------------------------------------- /test/chained-method-call.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Foo { 4 | var value : float; 5 | plusOne() : Foo { 6 | var f : Foo; 7 | f.value = value + 1.0; 8 | return f; 9 | } 10 | static zero() : Foo { 11 | var f : Foo; 12 | f.value = 0.0; 13 | return f; 14 | } 15 | } 16 | 17 | var f = Foo.zero().plusOne(); 18 | Test.Expect(f.value == 1.0); 19 | -------------------------------------------------------------------------------- /test/enum.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | enum Enum { Foo, Bar, Baz }; 4 | class A { 5 | init() { 6 | f = Enum.Foo; 7 | } 8 | var f : Enum; 9 | }; 10 | var a = new A; 11 | a.init(); 12 | Test.Expect(a.f == Enum.Foo); 13 | a.f = Enum.Bar; 14 | Test.Expect(a.f == Enum.Bar); 15 | var r = 0.0; 16 | if (a.f == Enum.Bar ) { 17 | r = 1.0; 18 | } 19 | Test.Expect(r == 1.0); 20 | -------------------------------------------------------------------------------- /test/method-chained.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Bar { 4 | Bar() { x = 2.0; } 5 | bump() : float { 6 | x += 1.0; 7 | return x; 8 | } 9 | var x : float; 10 | } 11 | 12 | class Foo { 13 | bar() : *Bar { 14 | return new Bar(); 15 | } 16 | }; 17 | 18 | class Bump { 19 | } 20 | 21 | var foo = new Foo; 22 | Test.Expect(foo.bar().bump() == 3.0); 23 | -------------------------------------------------------------------------------- /test/templated-derived-class-with-shader.t: -------------------------------------------------------------------------------- 1 | class Base { 2 | vertex main(vb : &VertexBuiltins) { 3 | vb.position = {1.0, 0.0, 0.0, 1.0}; 4 | } 5 | } 6 | 7 | class C : Base { 8 | fragment main(fb : &FragmentBuiltins) { 9 | fragColor.Set({0.0, 1.0, 0.0, 1.0}); 10 | } 11 | var fragColor : *ColorOutput; 12 | } 13 | 14 | var p = new RenderPipeline>; 15 | -------------------------------------------------------------------------------- /test/increment-with-side-effects.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Bar { 4 | var a : int; 5 | } 6 | 7 | class Foo { 8 | Foo() { bar = new Bar; } 9 | GetBar() : ^Bar { count += 1; return bar; } 10 | var bar : *Bar; 11 | var count : int; 12 | } 13 | 14 | var foo = new Foo(); 15 | foo.GetBar().a += 1; 16 | 17 | Test.Expect(foo.bar.a == 1); 18 | Test.Expect(foo.count == 1); 19 | -------------------------------------------------------------------------------- /test/chained-array-access.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Foo { 4 | var value : float; 5 | plusOne() : Foo { 6 | var f : Foo; 7 | f.value = value + 1.0; 8 | return f; 9 | } 10 | static zero() : [1]Foo { 11 | var f : [1]Foo; 12 | f[0].value = 0.0; 13 | return f; 14 | } 15 | } 16 | 17 | var f = Foo.zero()[0].plusOne(); 18 | Test.Expect(f.value == 1.0); 19 | -------------------------------------------------------------------------------- /test/post-increment-with-side-effects.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Bar { 4 | var a : int; 5 | } 6 | 7 | class Foo { 8 | Foo() { bar = new Bar; } 9 | GetBar() : ^Bar { count += 1; return bar; } 10 | var bar : *Bar; 11 | var count : int; 12 | } 13 | 14 | var foo = new Foo(); 15 | foo.GetBar().a++; 16 | 17 | Test.Expect(foo.bar.a == 1); 18 | Test.Expect(foo.count == 1); 19 | -------------------------------------------------------------------------------- /test/list-init-array-arg.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class C { 4 | static pf(a : &[3]int) { 5 | Test.Expect(a[0] == 3); 6 | Test.Expect(a[1] == 2); 7 | Test.Expect(a[2] == 1); 8 | } 9 | static pv(a : &[]int) { 10 | Test.Expect(a[0] == 3); 11 | Test.Expect(a[1] == 2); 12 | Test.Expect(a[2] == 1); 13 | } 14 | } 15 | 16 | C.pf({3, 2, 1}); 17 | C.pv({3, 2, 1}); 18 | -------------------------------------------------------------------------------- /test/null-ptr.t: -------------------------------------------------------------------------------- 1 | include "test.t" 2 | 3 | var n : *int = null; 4 | var a = new int; 5 | var b = new int; 6 | var c = a; 7 | 8 | Test.Assert(n == null); 9 | Test.Assert(null == n); 10 | Test.Assert(a != null); 11 | Test.Assert(null != a); 12 | Test.Assert(a != b); 13 | Test.Assert(b != a); 14 | Test.Assert(a == c); 15 | Test.Assert(c == a); 16 | Test.Assert(b != null); 17 | Test.Assert(null != b); 18 | -------------------------------------------------------------------------------- /test/templated-vector.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Template { 4 | var foo : T<4>; 5 | Template(t : T<4>) { foo = t; } 6 | get() : T<4> { return foo; } 7 | } 8 | 9 | var temp = new Template(float<4>(1.0, 2.0, 3.0, 4.0)); 10 | var f : float<4> = temp.get(); 11 | Test.Expect(f.x == 1.0); 12 | Test.Expect(f.y == 2.0); 13 | Test.Expect(f.z == 3.0); 14 | Test.Expect(f.w == 4.0); 15 | -------------------------------------------------------------------------------- /test/destructor.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Bar { 4 | Bar(b: *bool) { 5 | destroyed = b; 6 | } 7 | ~Bar() { 8 | destroyed: = true; 9 | } 10 | var destroyed: *bool; 11 | }; 12 | 13 | var result = new bool; 14 | { 15 | var f = new Bar(result); 16 | } 17 | Test.Expect(result: == true); 18 | 19 | result: = false; 20 | { 21 | var f = Bar(result); 22 | } 23 | Test.Expect(result: == true); 24 | -------------------------------------------------------------------------------- /test/error-index-buffer-get.t: -------------------------------------------------------------------------------- 1 | class Pipeline { 2 | vertex main(vb : &VertexBuiltins) { 3 | vb.position = vertices.Get(); 4 | var i = indices.Get(); 5 | } 6 | fragment main(fb : &FragmentBuiltins) { 7 | fragColor.Set( {0.0, 1.0, 0.0, 1.0} ); 8 | } 9 | var vertices : *VertexInput>; 10 | var indices : *index Buffer<[]uint>; 11 | var fragColor : *ColorOutput; 12 | } 13 | -------------------------------------------------------------------------------- /test/raw-ptr.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var i = 3; 4 | var pi : &int = &i; 5 | pi = 5; 6 | Test.Expect(i == 5); 7 | 8 | class C { 9 | var f : float; 10 | } 11 | 12 | var c = C{ 21.0 }; 13 | var pf = &c.f; 14 | pf = 42.0; 15 | Test.Expect(c.f == 42.0); 16 | 17 | var ii = new int(); 18 | ii: = 21; 19 | Test.Expect(ii: == 21); 20 | var pii : &int = ii; 21 | pii = 42; 22 | ii = null; 23 | Test.Expect(pii == 42); 24 | -------------------------------------------------------------------------------- /test/list-init-vector.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var v21 : float<2> = {1.0, 0.0}; 4 | var v22 : float<2> = {2.0, 3.0}; 5 | 6 | var v : int<4> = {1, 2, 3, 4}; 7 | v = {1, 1, 1, 1}; 8 | 9 | Test.Expect(v21.x == 1.0); 10 | Test.Expect(v21.y == 0.0); 11 | Test.Expect(v22.x == 2.0); 12 | Test.Expect(v22.y == 3.0); 13 | Test.Expect(v.x == 1); 14 | Test.Expect(v.y == 1); 15 | Test.Expect(v.z == 1); 16 | Test.Expect(v.w == 1); 17 | -------------------------------------------------------------------------------- /test/spirv-call-graph.t: -------------------------------------------------------------------------------- 1 | var device = new Device(); 2 | 3 | class Pipeline { 4 | static a() : float { 5 | return 5.0; 6 | } 7 | static b() : float { 8 | return Pipeline.a(); 9 | } 10 | compute(1, 1, 1) main(cb : &ComputeBuiltins) { 11 | var temp = Pipeline.b(); 12 | } 13 | } 14 | 15 | // This passes by generating valid SPIR-V during codegen. 16 | var tessPipeline = new ComputePipeline(device); 17 | -------------------------------------------------------------------------------- /third_party/android_native_app_glue/README: -------------------------------------------------------------------------------- 1 | Name: android_native_app_glue 2 | URL: https://android.googlesource.com/platform/ndk/+/5aac75cf5bea628f44bc8e09fe672573aeac0849/sources/android/native_app_glue 3 | License: Apache-2.0 4 | License file: NOTICE 5 | 6 | Description: 7 | Glue library to interface native apps with ANativeActivity. 8 | It provides a synchronous event loop by running the application on 9 | a separate thread. 10 | -------------------------------------------------------------------------------- /test/templated-on-class-and-primitive-type.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Foo { 4 | var mine : T; 5 | Foo(t : T) { 6 | var s = t; 7 | mine = s; 8 | } 9 | } 10 | 11 | class Bar { 12 | static GetFloat() : float { 13 | return 5.0; 14 | } 15 | } 16 | 17 | var foofloat = Foo(3.0); 18 | var foobar : Foo; 19 | Test.Expect(foobar.mine.GetFloat() == 5.0); 20 | Test.Expect(foofloat.mine == 3.0); 21 | -------------------------------------------------------------------------------- /bench/array_float4.t: -------------------------------------------------------------------------------- 1 | int count = 1000000; 2 | float<4>[256] a; 3 | float<4> mul = float<4>(1.00001, 1.00001, 1.00001, 1.00001); 4 | float<4> add = float<4>(1.0, 1.0, 1.0, 1.0); 5 | for (int i = 0; i < a.length; ++i) { 6 | a[i] = float<4>(2000000.0, 2000000.0, 2000000.0, 2000000.0); 7 | } 8 | for (int j = 0; j < count; ++j) { 9 | for (int i = 0; i < a.length; ++i) { 10 | a[i] = a[i] * mul + add; 11 | } 12 | } 13 | return a[1].x; 14 | -------------------------------------------------------------------------------- /test/list-init-matrix.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var m : float<4, 4> = {{1.0, 0.0, 0.0, 0.0}, 4 | {0.0, 1.0, 0.0, 0.0}, 5 | {0.0, 0.0, 1.0, 0.0}, 6 | {5.0,-3.0, 1.0, 1.0}}; 7 | 8 | Test.Expect(m[0][0] == 1.0); 9 | Test.Expect(m[0][1] == 0.0); 10 | Test.Expect(m[3][0] == 5.0); 11 | Test.Expect(m[3][1] == -3.0); 12 | Test.Expect(m[3][2] == 1.0); 13 | Test.Expect(m[3][3] == 1.0); 14 | -------------------------------------------------------------------------------- /test/templated-matrix.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Template { 4 | var foo : T<2, 2>; 5 | Template(t : T<2, 2>) { foo = t; } 6 | get() : T<2, 2> { return foo; } 7 | } 8 | 9 | var temp = new Template(float<2, 2>(float<2>(1.0, 2.0), float<2>(3.0, 4.0))); 10 | var f : float<2, 2> = temp.get(); 11 | Test.Expect(f[0][0] == 1.0); 12 | Test.Expect(f[0][1] == 2.0); 13 | Test.Expect(f[1][0] == 3.0); 14 | Test.Expect(f[1][1] == 4.0); 15 | -------------------------------------------------------------------------------- /test/matrix-constructor.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | var m = float<4,4>(float<4>(1.0, 0.0, 0.0, 0.0), 3 | float<4>(0.0, 1.0, 0.0, 0.0), 4 | float<4>(0.0, 0.0, 1.0, 0.0), 5 | float<4>(5.0,-3.0, 1.0, 1.0)); 6 | 7 | Test.Expect(m[0][0] == 1.0); 8 | Test.Expect(m[0][1] == 0.0); 9 | Test.Expect(m[3][0] == 5.0); 10 | Test.Expect(m[3][1] == -3.0); 11 | Test.Expect(m[3][2] == 1.0); 12 | Test.Expect(m[3][3] == 1.0); 13 | -------------------------------------------------------------------------------- /test/error-texture-from-buffer-incorrect-format.t: -------------------------------------------------------------------------------- 1 | var device = new Device(); 2 | var window = new Window({640, 480}); 3 | var tex = new sampleable Texture1D(device, 1); 4 | var buffer = new hostwriteable Buffer<[]float<4>>(device); 5 | { 6 | var data = buffer.MapWrite(); 7 | data[0] = float<4>(1.0, 1.0, 1.0, 1.0); 8 | } 9 | var encoder = new CommandEncoder(device); 10 | tex.CopyFromBuffer(encoder, buffer, 1); 11 | device.GetQueue().Submit(encoder.Finish()); 12 | -------------------------------------------------------------------------------- /test/dereference.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var f = new float(); 4 | f: = 3.0; 5 | var v = new float<3>(); 6 | v: = float<3>(2.0, 4.0, 6.0); 7 | var temp = v:; 8 | var a = new [3]float(); 9 | a: = [3]float(3.0, 2.0, 1.0); 10 | var atemp = a:; 11 | Test.Expect(f: == 3.0); 12 | Test.Expect(temp.x == 2.0); 13 | Test.Expect(temp.y == 4.0); 14 | Test.Expect(temp.z == 6.0); 15 | Test.Expect(atemp[0] == 3.0); 16 | Test.Expect(atemp[1] == 2.0); 17 | Test.Expect(atemp[2] == 1.0); 18 | -------------------------------------------------------------------------------- /test/array-float4.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var count = 200; 4 | var a : [256]float<4>; 5 | var mul = float<4>(1.00001, 1.00001, 1.00001, 1.00001); 6 | var add = float<4>(1.0, 1.0, 1.0, 1.0); 7 | for (var i = 0; i < a.length; ++i) { 8 | a[i] = float<4>(2000000.0, 2000000.0, 2000000.0, 2000000.0); 9 | } 10 | for (var j = 0; j < count; ++j) { 11 | for (var i = 0; i < a.length; ++i) { 12 | a[i] = a[i] * mul + add; 13 | } 14 | } 15 | Test.Expect(a[1].x == 2004203.875); 16 | -------------------------------------------------------------------------------- /samples/include/cubic.t: -------------------------------------------------------------------------------- 1 | class Cubic { 2 | FromBezier(p : [4]T) { 3 | a = p[0]; 4 | b = -3.0 * p[0] + 3.0 * p[1]; 5 | c = 3.0 * p[0] - 6.0 * p[1] + 3.0 * p[2]; 6 | d = -p[0] + 3.0 * p[1] - 3.0 * p[2] + p[3]; 7 | } 8 | 9 | Evaluate(p : float) : T { 10 | return a + p * (b + p * (c + p * d)); 11 | } 12 | 13 | EvaluateTangent(p : float) : T { 14 | return b + p * (2.0 * c + 3.0 * p * d); 15 | } 16 | 17 | var a : T, b : T, c : T, d : T; 18 | } 19 | -------------------------------------------------------------------------------- /bench/bench_mat4f.t: -------------------------------------------------------------------------------- 1 | int i; 2 | float4 m0; 3 | float4 m1; 4 | float4 m2; 5 | float4 m3; 6 | float4 v; 7 | float x; 8 | float y; 9 | float z; 10 | float w; 11 | m0 = float4(1.0, 0.0, 0.0, 0.0); 12 | m0 = float4(0.0, 1.0, 0.0, 0.0); 13 | m0 = float4(0.0, 0.0, 1.0, 0.0); 14 | m0 = float4(0.0, 0.0, 0.0, 1.0); 15 | v = float4(1.0, 2.0, 3.0, -4.0); 16 | for(i = 0; i < 10000000; i = i + 1) { 17 | x = dot(m0, v); 18 | y = dot(m1, v); 19 | z = dot(m2, v); 20 | w = dot(m3, v); 21 | } 22 | x; 23 | y; 24 | z; 25 | w; 26 | return x; 27 | -------------------------------------------------------------------------------- /test/destructor-set-null.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Bar; 4 | 5 | class Foo { 6 | Foo(count : ^int) : { count = count } { 7 | count:++; 8 | } 9 | ~Foo() { 10 | count:--; 11 | } 12 | 13 | var count : ^int; 14 | }; 15 | 16 | var count = new int; 17 | Test.Expect(count: == 0); 18 | var foo = new Foo(count); 19 | Test.Expect(count: == 1); 20 | foo = null; 21 | Test.Expect(count: == 0); 22 | 23 | { 24 | var foo = Foo(count); 25 | Test.Expect(count: == 1); 26 | } 27 | Test.Expect(count: == 0); 28 | 29 | -------------------------------------------------------------------------------- /test/error-validate-bind-group.t: -------------------------------------------------------------------------------- 1 | var device = new Device(); 2 | class C { 3 | var i : int; 4 | var sp : *int; 5 | var wp : ^int; 6 | var a : [3]float; 7 | var v : int<3>; 8 | var s : *storage Sampler; 9 | var t : Texture2D; 10 | var vb : *vertex Buffer>; 11 | var ib : *index Buffer>; 12 | var ib : *hostreadable Buffer>; 13 | var ib : *hostwriteable Buffer>; 14 | var ra : []byte; 15 | } 16 | new BindGroup(device, null); 17 | new BindGroup(device, {}); 18 | -------------------------------------------------------------------------------- /test/templated-class-with-auto-field.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class C { 4 | var s1 = (T) 3; 5 | var s2 : T = (T) 3; 6 | var v1 = T<2>{}; 7 | var v2 : T<2> = T<2>{}; 8 | } 9 | 10 | var ci = C{}; 11 | Test.Expect(ci.s1 == 3); 12 | Test.Expect(ci.s2 == 3); 13 | Test.Expect(Math.all(ci.v1 == int<2>{})); 14 | Test.Expect(Math.all(ci.v2 == int<2>{})); 15 | 16 | var cf = C{}; 17 | Test.Expect(cf.s1 == 3.0); 18 | Test.Expect(cf.s2 == 3.0); 19 | Test.Expect(Math.all(cf.v1 == float<2>{})); 20 | Test.Expect(Math.all(cf.v2 == float<2>{})); 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | buildtools 2 | out 3 | bin 4 | third_party/abseil-cpp 5 | third_party/binaryen 6 | third_party/dawn 7 | third_party/egl-registry 8 | third_party/emscripten 9 | third_party/getopt 10 | third_party/home-cube 11 | third_party/jinja2 12 | third_party/libjpeg-turbo 13 | third_party/llvm 14 | third_party/markupsafe 15 | third_party/ninja 16 | third_party/opengl-registry 17 | third_party/winflexbison 18 | third_party/SPIRV-Headers 19 | third_party/SPIRV-Tools 20 | third_party/Vulkan-Headers 21 | third_party/Vulkan-Tools 22 | third_party/Vulkan-Utility-Libraries 23 | -------------------------------------------------------------------------------- /test/matrix-array-access.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | var m : float<4, 4>; 3 | var i0 = 0, i1 = 1, i2 = 2, i3 = 3; 4 | m[i0][i0] = 4.0; 5 | m[i0][i1] = 3.0; 6 | m[i0][i2] = 2.0; 7 | m[i0][i3] = 1.0; 8 | m[i3][i0] = 5.0; 9 | m[i3][i1] = 6.0; 10 | m[i3][i2] = 7.0; 11 | m[i3][i3] = 8.0; 12 | Test.Expect(m[i0][i0] == 4.0); 13 | Test.Expect(m[i0][i1] == 3.0); 14 | Test.Expect(m[i0][i2] == 2.0); 15 | Test.Expect(m[i0][i3] == 1.0); 16 | Test.Expect(m[i3][i0] == 5.0); 17 | Test.Expect(m[i3][i1] == 6.0); 18 | Test.Expect(m[i3][i2] == 7.0); 19 | Test.Expect(m[i3][i3] == 8.0); 20 | -------------------------------------------------------------------------------- /samples/include/cube-loader.t: -------------------------------------------------------------------------------- 1 | class CubeLoader { 2 | Load(data : *[]ubyte, face : uint) { 3 | var image = new Image(data); 4 | var size = image.GetSize(); 5 | var buffer = new hostwriteable Buffer<[]ubyte<4>>(device, texture.MinBufferWidth() * size.y); 6 | image.Decode(buffer.MapWrite(), texture.MinBufferWidth()); 7 | var encoder = new CommandEncoder(device); 8 | texture.CopyFromBuffer(encoder, buffer, size, face); 9 | device.GetQueue().Submit(encoder.Finish()); 10 | } 11 | var device: *Device; 12 | var texture: *TextureCube; 13 | } 14 | -------------------------------------------------------------------------------- /test/error-non-addable-qualifiers.t: -------------------------------------------------------------------------------- 1 | var b : *Buffer<[]uint>; 2 | var fb : *Buffer; 3 | var u : *uniform Buffer = fb; 4 | var s : *storage Buffer<[]uint> = b; 5 | var v : *vertex Buffer<[]uint> = b; 6 | var i : *index Buffer<[]uint> = b; 7 | var us : *uniform storage Buffer = fb; 8 | var hr : *hostreadable Buffer<[]uint> = b; 9 | var hw : *hostwriteable Buffer<[]uint> = b; 10 | 11 | var t : *Texture2D; 12 | var st : *sampleable Texture2D = t; 13 | var rt : *renderable Texture2D = t; 14 | var srt : *sampleable renderable Texture2D = t; 15 | -------------------------------------------------------------------------------- /bench/array_float4_unroll.t: -------------------------------------------------------------------------------- 1 | int outer_count = 1000000; 2 | float4[256] a; 3 | float4 mul = float4(1.00001, 1.00001, 1.00001, 1.00001); 4 | float4 add = float4(1.0, 1.0, 1.0, 1.0); 5 | float4 init = float4(2000000.0, 2000000.0, 2000000.0, 2000000.0); 6 | for (int i = 0; i < a.length; ++i) { 7 | a[i] = init; 8 | } 9 | for (int j = 0; j < outer_count; ++j) { 10 | for (int i = 0; i < a.length;) { 11 | a[i] = a[i] * mul + add; 12 | ++i; 13 | a[i] = a[i] * mul + add; 14 | ++i; 15 | a[i] = a[i] * mul + add; 16 | ++i; 17 | a[i] = a[i] * mul + add; 18 | ++i; 19 | } 20 | } 21 | return a[1].x; 22 | -------------------------------------------------------------------------------- /test/spirv-if-stmt.t: -------------------------------------------------------------------------------- 1 | using Vertex = float<4>; 2 | 3 | class ComputeBindings { 4 | var vertStorage : *storage Buffer<[]Vertex>; 5 | } 6 | 7 | class BumpCompute { 8 | compute(1, 1, 1) main(cb : &ComputeBuiltins) { 9 | var verts = bindings.Get().vertStorage.Map(); 10 | var pos = cb.globalInvocationId.x; 11 | if (pos % 2 == 1) { 12 | verts[pos] += float<4>( 1.0, 0.0, 0.0, 0.0); 13 | } 14 | } 15 | var bindings : *BindGroup; 16 | } 17 | 18 | var device = new Device(); 19 | 20 | // This test passes by producing valid SPIR-V. 21 | var pipeline = new ComputePipeline(device); 22 | -------------------------------------------------------------------------------- /test/error-swizzle.t: -------------------------------------------------------------------------------- 1 | 2 | include "include/test.t" 3 | 4 | var v : int<3>; 5 | v.yz = v.xx; // Valid 6 | v.xx = int<2>{4, 3}; // Error: duplicate indices on store 7 | v.w = 0; // Error: invalid component 8 | v.w; // Error: invalid component 9 | v.q; // Error: invalid component 10 | v.a; // Error: invalid component 11 | v.xy = 3; // Error: rhs is not a vector 12 | v.xy = int<3>(); // Error: rhs vector is wrong length 13 | v.x = null; // Error: null is not widenable to int 14 | -------------------------------------------------------------------------------- /third_party/android_native_app_glue/NOTICE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2010 The Android Open Source Project 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /samples/window.t: -------------------------------------------------------------------------------- 1 | var device = new Device(); 2 | var window = new Window(System.GetScreenSize()); 3 | var swapChain = new SwapChain(device, window); 4 | var framebuffer = swapChain.GetCurrentTexture(); 5 | var encoder = new CommandEncoder(device); 6 | class Pipeline { 7 | var color : *ColorOutput; 8 | } 9 | var fb = framebuffer.CreateColorOutput(LoadOp.Clear, StoreOp.Store, float<4>(0.0, 1.0, 0.0, 1.0)); 10 | var renderPass = new RenderPass(encoder, { fb }); 11 | renderPass.End(); 12 | device.GetQueue().Submit(encoder.Finish()); 13 | swapChain.Present(); 14 | 15 | while (System.IsRunning()) System.GetNextEvent(); 16 | -------------------------------------------------------------------------------- /test/error-assign-padded-array.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Uniforms { 4 | var array : [3]int; 5 | } 6 | 7 | var uniforms : Uniforms; 8 | uniforms.array = {42, 21, 7}; 9 | 10 | var device = new Device(); 11 | 12 | var uniformBuf = new uniform Buffer(device, &uniforms); 13 | var hostBuf = new hostreadable Buffer(device); 14 | 15 | var encoder = new CommandEncoder(device); 16 | hostBuf.CopyFromBuffer(encoder, uniformBuf); 17 | device.GetQueue().Submit(encoder.Finish()); 18 | 19 | var result = hostBuf.MapRead(); 20 | Test.Expect(result.array[0] == 42); 21 | Test.Expect(result.array[1] == 21); 22 | Test.Expect(result.array[2] == 7); 23 | -------------------------------------------------------------------------------- /test/error-invalid-class-casts.t: -------------------------------------------------------------------------------- 1 | // Test some widening casts 2 | class Base { 3 | }; 4 | class Derived : Base { 5 | }; 6 | class Base2 { 7 | }; 8 | class Derived2 : Base2 { 9 | }; 10 | 11 | var d = new Derived; 12 | var b2 = new Base2; 13 | var d2 = new Derived2; 14 | var i : int = null; // error; int cannot be widened to null 15 | var b : *Base = null; // valid; null can be widened to any pointer 16 | b = d; // valid; Derived* can be widened to Base* 17 | b = b2; // error, b2 is not derived from b 18 | b2 = d2; // valid; Derived2 can be widened to Base2* 19 | d2 = d; // error; Derived2 and Derived are unrelated 20 | -------------------------------------------------------------------------------- /test/class-constructor.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class C { 4 | C() {} 5 | C(_x : float, _y : float) : { y = _x, x = _y } {} 6 | var x : float = -1.0; 7 | var y : float = -2.0; 8 | } 9 | 10 | var c = C(21.0, 42.0); 11 | Test.Expect(c.x == 42.0); 12 | Test.Expect(c.y == 21.0); 13 | 14 | var pc = new C(7.0, 14.0); 15 | Test.Expect(pc.x == 14.0); 16 | Test.Expect(pc.y == 7.0); 17 | 18 | var ic = C{21.0, 42.0}; 19 | Test.Expect(ic.x == 21.0); 20 | Test.Expect(ic.y == 42.0); 21 | 22 | var dic = C{}; 23 | Test.Expect(dic.x == -1.0); 24 | Test.Expect(dic.y == -2.0); 25 | 26 | var pdic = new C(); 27 | Test.Expect(pdic.x == -1.0); 28 | Test.Expect(pdic.y == -2.0); 29 | -------------------------------------------------------------------------------- /test/mutual-recursion.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Foo { 4 | var y : float; 5 | foo(x : int) { 6 | if (x > 0) this.bar(x - 1); 7 | return; 8 | } 9 | bar(x : int) { 10 | y += 1.0; 11 | this.foo(x); 12 | return; 13 | } 14 | }; 15 | 16 | var foo = new Foo; 17 | foo.y = 0.0; 18 | foo.foo(10); 19 | Test.Expect(foo.y == 10.0); 20 | 21 | class Bar { 22 | var y : float; 23 | foo(x : int, y = 0) { 24 | if (x > 0) this.bar(x - 1, 1.0); 25 | return; 26 | } 27 | bar(x : int, z = 0.0) { 28 | y += 1.0; 29 | this.foo(x, 42); 30 | return; 31 | } 32 | }; 33 | 34 | var bar = new Bar; 35 | bar.y = 0.0; 36 | bar.foo(10); 37 | Test.Expect(bar.y == 10.0); 38 | -------------------------------------------------------------------------------- /test/vector-constructors4.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var v41 = float<4>(1.0); 4 | var v42 = float<4>(2.0, 3.0); 5 | var v43 = float<4>(4.0, 5.0, 6.0); 6 | var v44 = float<4>(7.0, 8.0, 9.0, 10.0); 7 | 8 | Test.Expect(v41.x == 1.0); 9 | Test.Expect(v41.y == 1.0); 10 | Test.Expect(v41.z == 1.0); 11 | Test.Expect(v41.w == 1.0); 12 | Test.Expect(v42.x == 2.0); 13 | Test.Expect(v42.y == 3.0); 14 | Test.Expect(v42.z == 0.0); 15 | Test.Expect(v42.w == 0.0); 16 | Test.Expect(v43.x == 4.0); 17 | Test.Expect(v43.y == 5.0); 18 | Test.Expect(v43.z == 6.0); 19 | Test.Expect(v43.w == 0.0); 20 | Test.Expect(v44.x == 7.0); 21 | Test.Expect(v44.y == 8.0); 22 | Test.Expect(v44.z == 9.0); 23 | Test.Expect(v44.w == 10.0); 24 | -------------------------------------------------------------------------------- /test/include/test.t: -------------------------------------------------------------------------------- 1 | include "string.t" 2 | class Test { 3 | static Expect(expr : bool, file : ^[]ubyte = System.GetSourceFile(), line : uint = System.GetSourceLine()) { 4 | if (!expr) { 5 | System.Print(file); 6 | System.Print(":"); 7 | System.Print(String.From(line).Get()); 8 | System.PrintLine(": expectation failed"); 9 | } 10 | } 11 | static Assert(expr : bool, file : ^[]ubyte = System.GetSourceFile(), line : uint = System.GetSourceLine()) { 12 | if (!expr) { 13 | System.Print(file); 14 | System.Print(":"); 15 | System.Print(String.From(line).Get()); 16 | System.PrintLine(": assertion failed"); 17 | System.Abort(); 18 | } 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /test/matrix-initializer.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | var m = float<4,4>{float<4>{1.0, 0.0, 0.0, 0.0}, 3 | float<4>{0.0, 1.0, 0.0, 0.0}, 4 | float<4>{0.0, 0.0, 1.0, 0.0}, 5 | float<4>{5.0,-3.0, 1.0, 1.0}}; 6 | Test.Expect(m[0][0] == 1.0); 7 | Test.Expect(m[0][1] == 0.0); 8 | Test.Expect(m[3][0] == 5.0); 9 | Test.Expect(m[3][1] == -3.0); 10 | Test.Expect(m[3][2] == 1.0); 11 | Test.Expect(m[3][3] == 1.0); 12 | 13 | var v = int<3>(3, 2, 1); 14 | var m2 = int<3,2>(v); 15 | 16 | Test.Expect(m2[0][0] == 3); 17 | Test.Expect(m2[0][1] == 2); 18 | Test.Expect(m2[0][2] == 1); 19 | Test.Expect(m2[1][0] == 3); 20 | Test.Expect(m2[1][1] == 2); 21 | Test.Expect(m2[1][2] == 1); 22 | -------------------------------------------------------------------------------- /test/slice.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var array = [3]int{0, 1, 2}; 4 | var slice12 = &array[1..3]; 5 | 6 | Test.Expect(slice12.length == 2); 7 | Test.Expect(slice12[0] == 1); 8 | Test.Expect(slice12[1] == 2); 9 | 10 | var slice1n = &array[1..]; 11 | 12 | Test.Expect(slice1n.length == 2); 13 | Test.Expect(slice1n[0] == 1); 14 | Test.Expect(slice1n[1] == 2); 15 | 16 | Test.Expect(array[..].length == 3); 17 | Test.Expect(array[..1].length == 1); 18 | Test.Expect(array[..2].length == 2); 19 | Test.Expect(array[..3].length == 3); 20 | 21 | Test.Expect(array[0..0].length == 0); 22 | Test.Expect(array[0..1].length == 1); 23 | Test.Expect(array[0..2].length == 2); 24 | Test.Expect(array[0..3].length == 3); 25 | Test.Expect(array[0..].length == 3); 26 | -------------------------------------------------------------------------------- /test/test.sh: -------------------------------------------------------------------------------- 1 | # Copyright 2023 The Toucan Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | testpath=`dirname $0` 16 | for file in `ls ${testpath}/*.t` 17 | do 18 | echo $file 19 | out/Debug/tj < $file 20 | done 21 | -------------------------------------------------------------------------------- /tools/git-sync-deps.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | :: Copyright 2024 The Toucan Authors 3 | :: 4 | :: Licensed under the Apache License, Version 2.0 (the "License"); 5 | :: you may not use this file except in compliance with the License. 6 | :: You may obtain a copy of the License at 7 | :: 8 | :: https://www.apache.org/licenses/LICENSE-2.0 9 | :: 10 | :: Unless required by applicable law or agreed to in writing, software 11 | :: distributed under the License is distributed on an "AS IS" BASIS, 12 | :: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | :: See the License for the specific language governing permissions and 14 | :: limitations under the License. 15 | 16 | set GIT_SYNC_DEPS_PATH=%~dp0\..\DEPS 17 | python3 third_party\skia\tools\git-sync-deps 18 | -------------------------------------------------------------------------------- /.gn: -------------------------------------------------------------------------------- 1 | # Copyright 2023 The Toucan Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | buildconfig = "//gn/BUILDCONFIG.gn" 16 | script_executable = "python3" 17 | 18 | default_args = { 19 | dawn_use_built_dxc = false 20 | } 21 | -------------------------------------------------------------------------------- /tools/first-dir-entry.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright 2024 The Toucan Authors 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | import os 18 | import sys 19 | 20 | sys.stdout.write(os.listdir(sys.argv[1])[0]) 21 | -------------------------------------------------------------------------------- /tools/run.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright 2023 The Toucan Authors 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | import sys 18 | import subprocess 19 | args = sys.argv 20 | args.pop(0) 21 | subprocess.check_call(args) 22 | -------------------------------------------------------------------------------- /third_party/android_native_app_glue/BUILD.gn: -------------------------------------------------------------------------------- 1 | # Copyright 2025 The Toucan Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | 16 | source_set("android_native_app_glue") { 17 | sources = [ 18 | "android_native_app_glue.c", 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /api/api_android.h: -------------------------------------------------------------------------------- 1 | // Copyright 2024 The Toucan Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | struct android_app; 16 | 17 | namespace Toucan { 18 | 19 | void SetAndroidApp(struct android_app* app); 20 | 21 | }; // namespace Toucan 22 | -------------------------------------------------------------------------------- /test/image.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var image = new Image(null); 4 | Test.Expect(image == null); 5 | 6 | var data = inline("test/include/small.jpg"); 7 | 8 | image = new Image(data); 9 | var d = [1] new writeonly ubyte<4>; 10 | image.Decode(d, 1); 11 | Test.Expect((uint) d[0].r == 190u); 12 | Test.Expect((uint) d[0].g == 190u); 13 | Test.Expect((uint) d[0].b == 190u); 14 | Test.Expect((uint) d[0].a == 255u); 15 | 16 | var copy = [data.length] new ubyte; 17 | for (var i = 0; i < data.length; ++i) { 18 | copy[i] = data[i]; 19 | } 20 | 21 | image = new Image(copy); 22 | copy = null; 23 | d[0] = ubyte<4>{}; 24 | image.Decode(d, 1); 25 | Test.Expect((uint) d[0].r == 190u); 26 | Test.Expect((uint) d[0].g == 190u); 27 | Test.Expect((uint) d[0].b == 190u); 28 | Test.Expect((uint) d[0].a == 255u); 29 | -------------------------------------------------------------------------------- /gn/rm.py: -------------------------------------------------------------------------------- 1 | # Copyright 2023 The Toucan Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import os 16 | import shutil 17 | import sys 18 | 19 | dst, = sys.argv[1:] 20 | 21 | if os.path.exists(dst): 22 | if os.path.isdir(dst): 23 | shutil.rmtree(dst) 24 | else: 25 | os.remove(dst) 26 | -------------------------------------------------------------------------------- /BUILD.gn: -------------------------------------------------------------------------------- 1 | # Copyright 2023 The Toucan Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | group("all") { 16 | deps = [ 17 | "//samples:samples", 18 | "//test:tests", 19 | ] 20 | if (!is_wasm && !is_android && !is_ios) { 21 | deps += [ 22 | "//compilers:tj", 23 | ] 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /api/init_types.h: -------------------------------------------------------------------------------- 1 | // Copyright 2023 The Toucan Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | namespace Toucan { 16 | class Type; 17 | class TypeTable; 18 | // This function will be generated by the bindings generator. 19 | Type** InitTypes(TypeTable* types); 20 | }; // namespace Toucan 21 | -------------------------------------------------------------------------------- /test/include/string.t: -------------------------------------------------------------------------------- 1 | class String { 2 | String(b : *[]ubyte) { buffer = b; } 3 | static IntLog2(value : int) : int { return 31 - Math.clz(value | 1); } 4 | static From(value : int) : *String { 5 | var table = [9]int(9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999); 6 | var negative = false; 7 | if (value < 0) { 8 | negative = true; 9 | value = -value; 10 | } 11 | var len = (9 * String.IntLog2(value)) / 32; 12 | if (value > table[len]) len += 1; 13 | len += 1; 14 | if (negative) len += 1; 15 | var b = [len] new ubyte; 16 | for (var j = len - 1; j >= 0; j--) { 17 | b[j] = (ubyte) (value % 10) + 48ub; 18 | value /= 10; 19 | } 20 | if (negative) b[0] = 45ub; 21 | return new String(b); 22 | } 23 | Get() : *[]ubyte { return buffer; } 24 | var buffer : *[]ubyte; 25 | } 26 | -------------------------------------------------------------------------------- /bench/native1.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2023 The Toucan Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | int main() { 18 | float a = 0.0000001f, c = 0.0f; 19 | for (int i = 0; i < 1000000000; ++i) { 20 | c = a + c; 21 | } 22 | printf("%f\n", c); 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /emscripten/BUILD.gn: -------------------------------------------------------------------------------- 1 | # Copyright 2024 The Toucan Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Copy handwritten `.proto` file to build directory 16 | copy("images") { 17 | sources = [ 18 | "toucan-logo-and-name.svg", 19 | ] 20 | outputs = [ "$root_out_dir/images/toucan-logo-and-name.svg" ] 21 | } 22 | -------------------------------------------------------------------------------- /.emscripten: -------------------------------------------------------------------------------- 1 | # Copyright 2023 The Toucan Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import os 16 | 17 | this_file = os.getenv('EM_CONFIG') 18 | root_dir = os.path.dirname(this_file) 19 | 20 | LLVM_ROOT = os.path.join(root_dir, 'third_party', 'llvm', 'llvm', 'out', 'Release', 'bin') 21 | BINARYEN_ROOT = os.path.join(root_dir, 'third_party', 'binaryen') 22 | -------------------------------------------------------------------------------- /test/array-initialization.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var a = [3] new int; 4 | var b = [3] new int{}; 5 | var c = [3] new int{42}; 6 | var d = [3] new int{3, 2, 1}; 7 | 8 | Test.Expect(a[0] == 0 && a[1] == 0 && a[2] == 0); 9 | Test.Expect(b[0] == 0 && b[1] == 0 && b[2] == 0); 10 | Test.Expect(c[0] == 42 && c[1] == 42 && c[2] == 42); 11 | Test.Expect(d[0] == 3 && d[1] == 2 && d[2] == 1); 12 | 13 | var e = [3] int(); 14 | var f = [3] int(42); 15 | var g = [3] int(3, 2, 1); 16 | 17 | Test.Expect(e[0] == 0 && e[1] == 0 && e[2] == 0); 18 | Test.Expect(f[0] == 42 && f[1] == 42 && f[2] == 42); 19 | Test.Expect(g[0] == 3 && g[1] == 2 && g[2] == 1); 20 | 21 | var h : [3] int = {}; 22 | var i : [3] int = {42}; 23 | var j : [3] int = {3, 2, 1}; 24 | 25 | Test.Expect(h[0] == 0 && h[1] == 0 && h[2] == 0); 26 | Test.Expect(i[0] == 42 && i[1] == 42 && i[2] == 42); 27 | Test.Expect(j[0] == 3 && j[1] == 2 && j[2] == 1); 28 | -------------------------------------------------------------------------------- /bench/array_float_unrolled.t: -------------------------------------------------------------------------------- 1 | int outer_count = 1000000; 2 | float[1024] a; 3 | for (int i = 0; i < a.length; ++i) { 4 | a[i] = 2000000.0; 5 | } 6 | for (int j = 0; j < outer_count; ++j) { 7 | for (int i = 0; i < a.length; i += 16) { 8 | a[i] = a[i] * 1.00001 + 1.0; 9 | a[i+1] = a[i+1] * 1.00001 + 1.0; 10 | a[i+2] = a[i+2] * 1.00001 + 1.0; 11 | a[i+3] = a[i+3] * 1.00001 + 1.0; 12 | a[i+4] = a[i+4] * 1.00001 + 1.0; 13 | a[i+5] = a[i+5] * 1.00001 + 1.0; 14 | a[i+6] = a[i+6] * 1.00001 + 1.0; 15 | a[i+7] = a[i+7] * 1.00001 + 1.0; 16 | a[i+8] = a[i+8] * 1.00001 + 1.0; 17 | a[i+9] = a[i+9] * 1.00001 + 1.0; 18 | a[i+10] = a[i+10] * 1.00001 + 1.0; 19 | a[i+11] = a[i+11] * 1.00001 + 1.0; 20 | a[i+12] = a[i+12] * 1.00001 + 1.0; 21 | a[i+13] = a[i+13] * 1.00001 + 1.0; 22 | a[i+14] = a[i+14] * 1.00001 + 1.0; 23 | a[i+15] = a[i+15] * 1.00001 + 1.0; 24 | } 25 | } 26 | return a[0]; 27 | -------------------------------------------------------------------------------- /test/BUILD.gn: -------------------------------------------------------------------------------- 1 | # Copyright 2023 The Toucan Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import("../toucan_executable.gni") 16 | 17 | group("tests") { 18 | deps = [ 19 | ":empty", 20 | ":hello", 21 | ] 22 | } 23 | 24 | toucan_executable("empty") { 25 | sources = [ "empty.t" ] 26 | } 27 | 28 | toucan_executable("hello") { 29 | sources = [ "hello.t" ] 30 | } 31 | -------------------------------------------------------------------------------- /tools/git-sync-deps: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright 2023 The Toucan Authors 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | import subprocess, os 18 | subenv = os.environ.copy() 19 | subenv["GIT_SYNC_DEPS_PATH"] = os.path.normpath(os.path.join(os.path.dirname(__file__), os.pardir, 'DEPS')) 20 | subprocess.check_call('third_party/skia/tools/git-sync-deps', env=subenv) 21 | -------------------------------------------------------------------------------- /samples/include/tex-coord-utils.t: -------------------------------------------------------------------------------- 1 | enum ProjectedPlane { 2 | XY = 0, 3 | XZ = 1, 4 | YZ = 2 5 | } 6 | 7 | class TexCoordUtils { 8 | static ComputeProjectedPlaneUVs(vertices : *[]VertexType, plane : ProjectedPlane) { 9 | var extentMin = float<2>{ 1000000.0, 1000000.0}; 10 | var extentMax = float<2>{-1000000.0, -1000000.0}; 11 | var ProjectedPlaneToComponent : [3]uint<2> = { 12 | { 0, 1 }, { 0, 2 }, { 1, 2 } 13 | }; 14 | var components = ProjectedPlaneToComponent[plane]; 15 | for (var i = 0; i < vertices.length; ++i) { 16 | var v = &vertices[i]; 17 | v.uv.x = v.position[components.x]; 18 | v.uv.y = v.position[components.y]; 19 | 20 | extentMin = Math.min(v.uv, extentMin); 21 | extentMax = Math.max(v.uv, extentMax); 22 | } 23 | for (var i = 0; i < vertices.length; ++i) { 24 | vertices[i].uv = (vertices[i].uv - extentMin) / (extentMax - extentMin); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /api/init_api.h: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Toucan Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | namespace Toucan { 16 | extern bool exitOnAbort; 17 | class SymbolTable; 18 | class TypeTable; 19 | class NodeVector; 20 | class Type; 21 | // This function will be generated by the bindings generator. 22 | void InitAPI(SymbolTable* symbols, TypeTable* types, NodeVector* nodes); 23 | }; // namespace Toucan 24 | -------------------------------------------------------------------------------- /tools/unixify.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright 2025 The Toucan Authors 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | import sys 18 | 19 | filename = sys.argv[1] 20 | 21 | with open(filename, 'rb') as f: 22 | contents = f.read() 23 | 24 | contents = contents.replace(b'\r\n', b'\n') 25 | contents = contents.replace(b'test\\', b'test/') 26 | 27 | with open(filename, 'wb') as f: 28 | f.write(contents) 29 | -------------------------------------------------------------------------------- /gn/cp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright 2023 The Toucan Authors 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | import os 18 | import shutil 19 | import sys 20 | 21 | src, dst = sys.argv[1:] 22 | 23 | if os.path.exists(dst): 24 | if os.path.isdir(dst): 25 | shutil.rmtree(dst) 26 | else: 27 | os.remove(dst) 28 | 29 | if os.path.isdir(src): 30 | shutil.copytree(src, dst) 31 | else: 32 | shutil.copy2(src, dst) 33 | -------------------------------------------------------------------------------- /test/unfold-vector.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var v2 = float<2>{1.0, 2.0}; 4 | var v3 = float<3>{@v2, 3.0}; 5 | var v4 = float<4>{@v3, 4.0}; 6 | 7 | Test.Expect(v4.x == 1.0); 8 | Test.Expect(v4.y == 2.0); 9 | Test.Expect(v4.z == 3.0); 10 | Test.Expect(v4.w == 4.0); 11 | 12 | class Funky { 13 | var i : int; 14 | var v : float<4>; 15 | } 16 | 17 | class C { 18 | static vecify(a : float, b : float, c : float, d : float) : float<4> { 19 | return float<4>{a, b, c, d}; 20 | } 21 | static defunkify(f : Funky) { 22 | } 23 | } 24 | 25 | var a = C.vecify(1.0, @float<2>{2.0, 3.0}, 4.0); 26 | Test.Expect(a.x == 1.0 && a.y == 2.0 && a.z == 3.0 && a.w == 4.0); 27 | 28 | var b = C.vecify(1.0, @float<3>{2.0, 3.0, 4.0}); 29 | Test.Expect(b.x == 1.0 && b.y == 2.0 && b.z == 3.0 && b.w == 4.0); 30 | 31 | var c = C.vecify(@float<2>{1.0, 2.0}, @float<2>{3.0, 4.0}); 32 | Test.Expect(c.x == 1.0 && c.y == 2.0 && c.z == 3.0 && c.w == 4.0); 33 | 34 | C.defunkify({ 1, {@float<2>{1.0, 2.0}, @float<2>{3.0, 4.0} }} ); 35 | -------------------------------------------------------------------------------- /test/indexed-method-return.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class Foo { 4 | static generateArray() : *[]float { 5 | var r = [10] new float; 6 | r[9] = 1234.0; 7 | return r; 8 | } 9 | static generateFixedArray() : [3]int { 10 | return [3]int(3, 2, 1); 11 | } 12 | static generateVector() : float<2> { 13 | return float<2>{42.0, 21.0}; 14 | } 15 | static generateMatrix() : float<2, 2> { 16 | return float<2, 2>{float<2>{4.0, 3.0}, float<2>{2.0, 1.0}}; 17 | } 18 | } 19 | 20 | Test.Expect(Foo.generateArray()[9] == 1234.0); 21 | Test.Expect(Foo.generateFixedArray()[0] == 3); 22 | Test.Expect(Foo.generateFixedArray()[1] == 2); 23 | Test.Expect(Foo.generateFixedArray()[2] == 1); 24 | Test.Expect(Foo.generateVector()[0] == 42.0); 25 | Test.Expect(Foo.generateVector()[1] == 21.0); 26 | Test.Expect(Foo.generateMatrix()[0][0] == 4.0); 27 | Test.Expect(Foo.generateMatrix()[0][1] == 3.0); 28 | Test.Expect(Foo.generateMatrix()[1][0] == 2.0); 29 | Test.Expect(Foo.generateMatrix()[1][1] == 1.0); 30 | -------------------------------------------------------------------------------- /test/spirv-uint.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class ComputeBindings { 4 | var buffer : *storage Buffer; 5 | } 6 | 7 | class Compute { 8 | compute(1, 1, 1) main(cb : &ComputeBuiltins) { 9 | var buffer = bindings.Get().buffer.MapWrite(); 10 | buffer: = 42u; 11 | } 12 | var bindings : *BindGroup; 13 | } 14 | 15 | var device = new Device(); 16 | 17 | var computePipeline = new ComputePipeline(device); 18 | 19 | var storageBuf = new storage Buffer(device, 1); 20 | var hostBuf = new hostreadable Buffer(device, 1); 21 | 22 | var bg = new BindGroup(device, {buffer = storageBuf}); 23 | 24 | var encoder = new CommandEncoder(device); 25 | var computePass = new ComputePass(encoder, {bindings = bg}); 26 | computePass.SetPipeline(computePipeline); 27 | computePass.Dispatch(1, 1, 1); 28 | computePass.End(); 29 | hostBuf.CopyFromBuffer(encoder, storageBuf); 30 | device.GetQueue().Submit(encoder.Finish()); 31 | 32 | Test.Expect(hostBuf.MapRead(): == 42u); 33 | -------------------------------------------------------------------------------- /test/compute-simple.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class ComputeBindings { 4 | var buffer : *storage Buffer<[]int>; 5 | } 6 | 7 | class Compute { 8 | compute(1, 1, 1) main(cb : &ComputeBuiltins) { 9 | var buffer = bindings.Get().buffer.MapWrite(); 10 | buffer[0] = 42; 11 | } 12 | var bindings : *BindGroup; 13 | } 14 | 15 | var device = new Device(); 16 | 17 | var computePipeline = new ComputePipeline(device); 18 | 19 | var storageBuf = new storage Buffer<[]int>(device, 1); 20 | var hostBuf = new hostreadable Buffer<[]int>(device, 1); 21 | 22 | var bg = new BindGroup(device, {buffer = storageBuf}); 23 | 24 | var encoder = new CommandEncoder(device); 25 | var computePass = new ComputePass(encoder, {bindings = bg}); 26 | computePass.SetPipeline(computePipeline); 27 | computePass.Dispatch(1, 1, 1); 28 | computePass.End(); 29 | hostBuf.CopyFromBuffer(encoder, storageBuf); 30 | device.GetQueue().Submit(encoder.Finish()); 31 | 32 | Test.Expect(hostBuf.MapRead()[0] == 42); 33 | -------------------------------------------------------------------------------- /test/spirv-insert-element.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class ComputeBindings { 4 | var buffer : *storage Buffer>; 5 | } 6 | 7 | class Compute { 8 | compute(1, 1, 1) main(cb : &ComputeBuiltins) { 9 | var buffer = bindings.Get().buffer.MapWrite(); 10 | buffer.y = 42; 11 | } 12 | var bindings : *BindGroup; 13 | } 14 | 15 | var device = new Device(); 16 | 17 | var computePipeline = new ComputePipeline(device); 18 | 19 | var storageBuf = new storage Buffer>(device, 1); 20 | var hostBuf = new hostreadable Buffer>(device, 1); 21 | 22 | var bg = new BindGroup(device, {buffer = storageBuf}); 23 | 24 | var encoder = new CommandEncoder(device); 25 | var computePass = new ComputePass(encoder, {bindings = bg}); 26 | computePass.SetPipeline(computePipeline); 27 | computePass.Dispatch(1, 1, 1); 28 | computePass.End(); 29 | hostBuf.CopyFromBuffer(encoder, storageBuf); 30 | device.GetQueue().Submit(encoder.Finish()); 31 | 32 | Test.Expect(hostBuf.MapRead().y == 42); 33 | -------------------------------------------------------------------------------- /utils/hash_pair.h: -------------------------------------------------------------------------------- 1 | // Copyright 2023 The Toucan Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef _UTILS_HASH_PAIR_H 16 | #define _UTILS_HASH_PAIR_H 17 | 18 | #include 19 | 20 | namespace std { 21 | template 22 | struct hash> { 23 | std::size_t operator()(const std::pair& k) const { 24 | return (hash()(k.first) ^ (hash()(k.second) << 1)) >> 1; 25 | } 26 | }; 27 | } // namespace std 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /test/swizzle-store.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var v : int<4>; 4 | v.x = 4; 5 | v.y = 3; 6 | v.z = 2; 7 | v.w = 1; 8 | Test.Expect(v.x == 4); 9 | Test.Expect(v.y == 3); 10 | Test.Expect(v.z == 2); 11 | Test.Expect(v.w == 1); 12 | v.xz = int<2>{1, 3}; 13 | v.wy = int<2>{4, 2}; 14 | Test.Expect(v.x == 1); 15 | Test.Expect(v.y == 2); 16 | Test.Expect(v.z == 3); 17 | Test.Expect(v.w == 4); 18 | v.wzxy = int<4>{8, 7, 5, 6}; 19 | Test.Expect(v.x == 5); 20 | Test.Expect(v.y == 6); 21 | Test.Expect(v.z == 7); 22 | Test.Expect(v.w == 8); 23 | 24 | var pv = new int<4>; 25 | pv.x = 4; 26 | pv.y = 3; 27 | pv.z = 2; 28 | pv.w = 1; 29 | Test.Expect(pv.x == 4); 30 | Test.Expect(pv.y == 3); 31 | Test.Expect(pv.z == 2); 32 | Test.Expect(pv.w == 1); 33 | pv.xz = int<2>{1, 3}; 34 | pv.wy = int<2>{4, 2}; 35 | Test.Expect(pv.x == 1); 36 | Test.Expect(pv.y == 2); 37 | Test.Expect(pv.z == 3); 38 | Test.Expect(pv.w == 4); 39 | pv.wzxy = int<4>{8, 7, 5, 6}; 40 | Test.Expect(pv.x == 5); 41 | Test.Expect(pv.y == 6); 42 | Test.Expect(pv.z == 7); 43 | Test.Expect(pv.w == 8); 44 | -------------------------------------------------------------------------------- /ast/file_location.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Toucan Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "file_location.h" 16 | 17 | namespace Toucan { 18 | 19 | FileLocation::FileLocation() : filename(nullptr), lineNum(0) {} 20 | 21 | FileLocation::FileLocation(const FileLocation& other) 22 | : filename(other.filename), lineNum(other.lineNum) {} 23 | 24 | FileLocation::FileLocation(std::shared_ptr f, int n) : filename(f), lineNum(n) {} 25 | 26 | } // namespace Toucan 27 | -------------------------------------------------------------------------------- /test/compute-empty-class.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class ComputeBindings { 4 | var buffer : *storage Buffer; 5 | } 6 | 7 | class C { 8 | } 9 | 10 | class Compute { 11 | compute(1, 1, 1) main(cb : &ComputeBuiltins) { 12 | var buffer = bindings.Get().buffer.MapWrite(); 13 | var c : C; 14 | buffer: = 42; 15 | } 16 | var bindings : *BindGroup; 17 | } 18 | 19 | var device = new Device(); 20 | 21 | var computePipeline = new ComputePipeline(device); 22 | 23 | var storageBuf = new storage Buffer(device); 24 | var hostBuf = new hostreadable Buffer(device); 25 | 26 | var bg = new BindGroup(device, {buffer = storageBuf}); 27 | 28 | var encoder = new CommandEncoder(device); 29 | var computePass = new ComputePass(encoder, {bindings = bg}); 30 | computePass.SetPipeline(computePipeline); 31 | computePass.Dispatch(1, 1, 1); 32 | computePass.End(); 33 | hostBuf.CopyFromBuffer(encoder, storageBuf); 34 | device.GetQueue().Submit(encoder.Finish()); 35 | 36 | Test.Expect(hostBuf.MapRead(): == 42); 37 | -------------------------------------------------------------------------------- /ast/BUILD.gn: -------------------------------------------------------------------------------- 1 | # Copyright 2023 The Toucan Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | source_set("ast") { 16 | sources = [ 17 | "api_validator.cc", 18 | "ast.cc", 19 | "constant_folder.cc", 20 | "file_location.cc", 21 | "native_class.cc", 22 | "copy_visitor.cc", 23 | "semantic_pass.cc", 24 | "shader_prep_pass.cc", 25 | "shader_validation_pass.cc", 26 | "symbol.cc", 27 | "type.cc", 28 | "type_replacement_pass.cc" 29 | ] 30 | include_dirs = [ 31 | "..", 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /tools/run-llvm-config: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Invokes llvm-config, and massages the result into a list of libs usable by GN. 4 | # argv[1] is the path to the llvm-config binary. 5 | # argv[2] is the output file (llvm_libs.gni) 6 | # 7 | # [ 8 | # "Foo", 9 | # "Bar", 10 | # ] 11 | 12 | import io 13 | import sys 14 | import subprocess 15 | 16 | llvm_config = sys.argv[1] 17 | suffix = '${lib}' 18 | result = sys.argv[2] 19 | 20 | with open(result, 'w') as output: 21 | output.write('if (is_win) {\n') 22 | output.write(' lib = ".lib"\n') 23 | output.write('} else {\n') 24 | output.write(' lib = ""\n') 25 | output.write('}\n\n') 26 | 27 | with subprocess.Popen([llvm_config, "--libs", "engine", "mcjit", "x86codegen", "armcodegen", "aarch64codegen", "webassemblycodegen"], stdout=subprocess.PIPE) as input: 28 | 29 | output.write('llvm_libs = [\n') 30 | for line in io.TextIOWrapper(input.stdout, encoding="utf-8"): 31 | for lib in line.split(): 32 | output.write(' "' + lib[2:] + suffix + '",\n') 33 | output.write(']\n') 34 | -------------------------------------------------------------------------------- /tools/vswhere.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright 2024 The Toucan Authors 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | import os 18 | import sys 19 | import subprocess 20 | 21 | vswhere = os.path.expandvars(os.path.join('%ProgramFiles(x86)%', 'Microsoft Visual Studio', 'Installer', 'vswhere.exe')) 22 | paths = subprocess.check_output([vswhere, '-products', '*', '-property', 'installationPath']); 23 | paths = paths.decode('utf-8').splitlines() 24 | if paths: 25 | path = os.path.join(paths[0], 'VC') 26 | sys.stdout.write(path) 27 | -------------------------------------------------------------------------------- /samples/main.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2023 The Toucan Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | using namespace Toucan; 22 | 23 | extern "C" { 24 | 25 | extern void toucan_main(); 26 | const Type* const* _type_list; 27 | } 28 | 29 | int main(int argc, char** argv) { 30 | TypeTable types; 31 | _type_list = InitTypes(&types); 32 | types.ComputeFieldOffsets(); 33 | toucan_main(); 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /samples/triangle.t: -------------------------------------------------------------------------------- 1 | class Pipeline { 2 | vertex main(vb : &VertexBuiltins) { vb.position = {@vertices.Get(), 0.0, 1.0}; } 3 | fragment main(fb : &FragmentBuiltins) { fragColor.Set( {0.0, 1.0, 0.0, 1.0} ); } 4 | var vertices : *VertexInput>; 5 | var fragColor : *ColorOutput; 6 | } 7 | var device = new Device(); 8 | var window = new Window(System.GetScreenSize()); 9 | var swapChain = new SwapChain(device, window); 10 | var verts = [3]float<2>{ { 0.0, 1.0 }, {-1.0, -1.0 }, { 1.0, -1.0 } }; 11 | var vb = new vertex Buffer<[]float<2>>(device, &verts); 12 | var vi = new VertexInput>(vb); 13 | var fb = swapChain.GetCurrentTexture().CreateColorOutput(LoadOp.Clear); 14 | var pipeline = new RenderPipeline(device); 15 | var encoder = new CommandEncoder(device); 16 | var renderPass = new RenderPass(encoder, { vertices = vi, fragColor = fb }); 17 | renderPass.SetPipeline(pipeline); 18 | renderPass.Draw(3, 1, 0, 0); 19 | renderPass.End(); 20 | device.GetQueue().Submit(encoder.Finish()); 21 | swapChain.Present(); 22 | while (System.IsRunning()) System.GetNextEvent(); 23 | -------------------------------------------------------------------------------- /parser/lexer.h: -------------------------------------------------------------------------------- 1 | // Copyright 2023 The Toucan Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef _LEXER_H 16 | #define _LEXER_H 17 | extern std::string GetFileName(); 18 | extern int GetLineNum(); 19 | extern void IncLineNum(); 20 | extern void yyerror(const char* str); 21 | extern FILE* IncludeFile(const char* filename); 22 | extern void PopFile(); 23 | namespace Toucan { 24 | class Arg; 25 | class ArgList; 26 | class Expr; 27 | class Stmt; 28 | class UnresolvedInitializer; 29 | }; // namespace Toucan 30 | #endif 31 | #define register 32 | -------------------------------------------------------------------------------- /test/removable-qualifiers.t: -------------------------------------------------------------------------------- 1 | { 2 | var b : *Buffer; 3 | var u : *uniform Buffer; 4 | var s : *storage Buffer; 5 | var us : *uniform storage Buffer; 6 | var hr : *hostreadable Buffer; 7 | var hw : *hostwriteable Buffer; 8 | b = u; 9 | b = s; 10 | b = us; 11 | u = us; 12 | s = us; 13 | b = hr; 14 | b = hw; 15 | } 16 | 17 | { 18 | var b : *Buffer<[]uint>; 19 | var s : *storage Buffer<[]uint>; 20 | var v : *vertex Buffer<[]uint>; 21 | var i : *index Buffer<[]uint>; 22 | var vs : *vertex storage Buffer<[]uint>; 23 | var is : *index storage Buffer<[]uint>; 24 | var vis : *vertex index storage Buffer<[]uint>; 25 | b = s; 26 | b = v; 27 | b = i; 28 | s = vs; 29 | s = is; 30 | s = vis; 31 | i = is; 32 | i = vis; 33 | v = vs; 34 | v = vis; 35 | vs = vis; 36 | is = vis; 37 | } 38 | 39 | var t : *Texture2D; 40 | var st : *sampleable Texture2D; 41 | var rt : *renderable Texture2D; 42 | var srt : *sampleable renderable Texture2D; 43 | 44 | t = st; 45 | t = rt; 46 | t = srt; 47 | st = srt; 48 | rt = srt; 49 | -------------------------------------------------------------------------------- /test/compute-vector-cast.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class ComputeBindings { 4 | var buffer : *storage Buffer<[]uint<2>>; 5 | } 6 | 7 | class Compute { 8 | compute(1, 1, 1) main(cb : &ComputeBuiltins) { 9 | var buffer = bindings.Get().buffer.MapWrite(); 10 | var f = float<2>(42.0, 21.0); 11 | buffer[0] = (uint<2>)f; 12 | } 13 | var bindings : *BindGroup; 14 | } 15 | 16 | var device = new Device(); 17 | 18 | var computePipeline = new ComputePipeline(device); 19 | 20 | var storageBuf = new storage Buffer<[]uint<2>>(device, 1); 21 | var hostBuf = new hostreadable Buffer<[]uint<2>>(device, 1); 22 | 23 | var bg = new BindGroup(device, {buffer = storageBuf}); 24 | 25 | var encoder = new CommandEncoder(device); 26 | var computePass = new ComputePass(encoder, {bindings = bg}); 27 | computePass.SetPipeline(computePipeline); 28 | computePass.Dispatch(1, 1, 1); 29 | computePass.End(); 30 | hostBuf.CopyFromBuffer(encoder, storageBuf); 31 | device.GetQueue().Submit(encoder.Finish()); 32 | 33 | var result = hostBuf.MapRead()[0]; 34 | Test.Expect(result.x == 42 && result.y == 21); 35 | -------------------------------------------------------------------------------- /tools/fetch-win-flex-bison.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright 2024 The Toucan Authors 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | import os, tempfile, zipfile 18 | from urllib.request import urlopen 19 | 20 | win_flex_bison_zip = os.path.join(tempfile.mkdtemp(), 'win_flex_bison.zip') 21 | with open(win_flex_bison_zip, 'wb') as f: 22 | url = "https://github.com/lexxmark/winflexbison/releases/download/v2.5.25/win_flex_bison-2.5.25.zip" 23 | f.write(urlopen(url).read()) 24 | 25 | with zipfile.ZipFile(win_flex_bison_zip, 'r') as f: 26 | f.extractall('third_party/winflexbison') 27 | -------------------------------------------------------------------------------- /test/compute-swizzle.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class ComputeBindings { 4 | var buffer : *storage Buffer>; 5 | } 6 | 7 | class Compute { 8 | compute(1, 1, 1) main(cb : &ComputeBuiltins) { 9 | var buffer = bindings.Get().buffer.MapWrite(); 10 | buffer: = buffer.wzyx; 11 | } 12 | var bindings : *BindGroup; 13 | } 14 | 15 | var device = new Device(); 16 | 17 | var computePipeline = new ComputePipeline(device); 18 | 19 | var storageBuf = new storage Buffer>(device, {1, 2, 3, 4}); 20 | var hostBuf = new hostreadable Buffer>(device, 1); 21 | 22 | var bg = new BindGroup(device, {buffer = storageBuf}); 23 | 24 | var encoder = new CommandEncoder(device); 25 | var computePass = new ComputePass(encoder, {bindings = bg}); 26 | computePass.SetPipeline(computePipeline); 27 | computePass.Dispatch(1, 1, 1); 28 | computePass.End(); 29 | hostBuf.CopyFromBuffer(encoder, storageBuf); 30 | device.GetQueue().Submit(encoder.Finish()); 31 | 32 | var result = hostBuf.MapRead(); 33 | Test.Expect(result.x == 4); 34 | Test.Expect(result.y == 3); 35 | Test.Expect(result.z == 2); 36 | Test.Expect(result.w == 1); 37 | -------------------------------------------------------------------------------- /test/interactive/two-windows.t: -------------------------------------------------------------------------------- 1 | class Pipeline { 2 | var fragColor : *ColorOutput; 3 | } 4 | var green = float<4>(0.0, 1.0, 0.0, 1.0); 5 | var blue = float<4>(0.0, 0.0, 1.0, 1.0); 6 | var device = new Device(); 7 | var queue = device.GetQueue(); 8 | var window1 = new Window({640, 480}, {0, 0}); 9 | var window2 = new Window({640, 480}, {100, 100}); 10 | var swapChain1 = new SwapChain(device, window1); 11 | var swapChain2 = new SwapChain(device, window2); 12 | var framebuffer1 = swapChain1.GetCurrentTexture(); 13 | var framebuffer2 = swapChain2.GetCurrentTexture(); 14 | var encoder = new CommandEncoder(device); 15 | var p1 = Pipeline{ framebuffer1.CreateColorOutput(LoadOp.Clear, StoreOp.Store, green) }; 16 | var renderPass1 = new RenderPass(encoder, &p1); 17 | renderPass1.End(); 18 | var p2 = Pipeline{ framebuffer2.CreateColorOutput(LoadOp.Clear, StoreOp.Store, blue) }; 19 | var renderPass2 = new RenderPass(encoder, &p2); 20 | renderPass2.End(); 21 | device.GetQueue().Submit(encoder.Finish()); 22 | swapChain1.Present(); 23 | swapChain2.Present(); 24 | 25 | while (System.IsRunning()) System.GetNextEvent(); 26 | -------------------------------------------------------------------------------- /bindings/BUILD.gn: -------------------------------------------------------------------------------- 1 | # Copyright 2023 The Toucan Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | source_set("gen_bindings_sources") { 16 | sources = [ 17 | "dump_as_source_pass.cc", 18 | "gen_bindings.cc", 19 | ] 20 | include_dirs = [ ".." ] 21 | deps = [ 22 | "../ast:ast", 23 | ] 24 | } 25 | 26 | executable("gen_bindings") { 27 | sources = [ 28 | "gen_bindings_main.cc", 29 | ] 30 | include_dirs = [ ".." ] 31 | deps = [ 32 | ":gen_bindings_sources", 33 | "../ast:ast", 34 | "../parser:parser", 35 | ] 36 | 37 | if (is_win) { 38 | include_dirs += [ "../third_party/getopt" ] 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /test/constant-folding.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | var int4Array : [128]int<4> = { -int<4>{ -42, -21, -14, -7 } }; 4 | Test.Expect(int4Array[0].w == 7); 5 | Test.Expect(int4Array[31].z == 14); 6 | Test.Expect(int4Array[64].y == 21); 7 | Test.Expect(int4Array[127].x == 42); 8 | 9 | var shortArray : [512]short = { -42s }; 10 | Test.Expect((int) shortArray[0] == -42); 11 | Test.Expect((int) shortArray[31] == -42); 12 | Test.Expect((int) shortArray[64] == -42); 13 | Test.Expect((int) shortArray[127] == -42); 14 | 15 | var ubyteArray : [1024]ubyte = { -42ub }; 16 | Test.Expect((int) ubyteArray[0] == -42); 17 | Test.Expect((int) ubyteArray[511] == -42); 18 | Test.Expect((int) ubyteArray[768] == -42); 19 | Test.Expect((int) ubyteArray[1023] == -42); 20 | 21 | var byteArray : [1024]ubyte = { -42b }; 22 | Test.Expect((int) byteArray[0] == -42); 23 | Test.Expect((int) byteArray[511] == -42); 24 | Test.Expect((int) byteArray[768] == -42); 25 | Test.Expect((int) byteArray[1023] == -42); 26 | 27 | var boolArray : [1024]bool = { true }; 28 | Test.Expect(boolArray[0] == true); 29 | Test.Expect(boolArray[511] == true); 30 | Test.Expect(boolArray[768] == true); 31 | Test.Expect(boolArray[1023] == true); 32 | -------------------------------------------------------------------------------- /test/test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright 2023 The Toucan Authors 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | import glob; 18 | import os; 19 | import subprocess; 20 | import sys; 21 | files = glob.glob(os.path.relpath(os.path.join(os.path.dirname(__file__), '*.t'))); 22 | files = sorted(files) 23 | debug_or_release = 'Release' 24 | if sys.platform == 'win32': 25 | exe_path = os.path.join('out', debug_or_release, 'tj.exe'); 26 | else: 27 | exe_path = os.path.join('out', debug_or_release, 'tj'); 28 | 29 | for file in files: 30 | print('test/' + os.path.basename(file)); 31 | sys.stdout.flush(); 32 | subprocess.call([exe_path, file]); 33 | -------------------------------------------------------------------------------- /samples/android_main.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2024 The Toucan Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | using namespace Toucan; 25 | 26 | extern "C" { 27 | 28 | extern void toucan_main(); 29 | const Type* const* _type_list; 30 | } 31 | 32 | void android_main(struct android_app* app) { 33 | SetAndroidApp(app); 34 | TypeTable types; 35 | _type_list = InitTypes(&types); 36 | types.ComputeFieldOffsets(); 37 | toucan_main(); 38 | } 39 | -------------------------------------------------------------------------------- /codegen/BUILD.gn: -------------------------------------------------------------------------------- 1 | # Copyright 2023 The Toucan Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | source_set("codegen") { 16 | deps = [ 17 | "../ast:ast", 18 | ] 19 | if (target_os == "wasm") { 20 | deps += [ "//third_party/dawn/src/tint/api:api" ] 21 | configs += [ "//third_party/dawn/src/tint:tint_public_config" ] 22 | public_deps = [ "//third_party/SPIRV-Tools:spvtools_val" ] 23 | } 24 | 25 | sources = [ 26 | "codegen_llvm.cc", 27 | "codegen_spirv.cc", 28 | ] 29 | include_dirs = [ 30 | "..", 31 | "$target_gen_dir/bindings", 32 | "../third_party/SPIRV-Headers/include", 33 | ] 34 | include_dirs += llvm_include_dirs 35 | } 36 | -------------------------------------------------------------------------------- /test/interactive/triangle-with-inherited-vertex-shader.t: -------------------------------------------------------------------------------- 1 | using Vertex = float<2>; 2 | 3 | class PipelineBase { 4 | vertex main(vb : &VertexBuiltins) { vb.position = {@vertices.Get(), 0.0, 1.0}; } 5 | var vertices : *VertexInput; 6 | } 7 | 8 | class Pipeline : PipelineBase { 9 | fragment main(fb : &FragmentBuiltins) { fragColor.Set( {0.0, 1.0, 0.0, 1.0} ); } 10 | var fragColor : *ColorOutput; 11 | } 12 | 13 | var device = new Device(); 14 | var window = new Window({640, 480}); 15 | var swapChain = new SwapChain(device, window); 16 | var verts : [3]Vertex = { { 0.0, 1.0 }, {-1.0, -1.0 }, { 1.0, -1.0 } }; 17 | var vb = new vertex Buffer<[]Vertex>(device, &verts); 18 | var pipeline = new RenderPipeline(device); 19 | var encoder = new CommandEncoder(device); 20 | var vi = new VertexInput(vb); 21 | var fb = swapChain.GetCurrentTexture().CreateColorOutput(LoadOp.Clear); 22 | var renderPass = new RenderPass(encoder, { vertices = vi, fragColor = fb }); 23 | renderPass.SetPipeline(pipeline); 24 | renderPass.Draw(3, 1, 0, 0); 25 | renderPass.End(); 26 | device.GetQueue().Submit(encoder.Finish()); 27 | swapChain.Present(); 28 | while (System.IsRunning()) System.GetNextEvent(); 29 | -------------------------------------------------------------------------------- /test/interactive/shader-method-call.t: -------------------------------------------------------------------------------- 1 | using Vertex = float<2>; 2 | 3 | class Pipeline { 4 | vertex main(vb : &VertexBuiltins) { vb.position = {@position.Get(), 0.0, 1.0}; } 5 | static green() : float<4> { return float<4>(0.0, 1.0, 0.0, 1.0); } 6 | fragment main(fb : &FragmentBuiltins) { fragColor.Set(Pipeline.green()); } 7 | var position : *VertexInput; 8 | var fragColor : *ColorOutput; 9 | } 10 | 11 | var device = new Device(); 12 | var window = new Window({640, 480}); 13 | var swapChain = new SwapChain(device, window); 14 | var verts = [3]Vertex{ { 0.0, 1.0 }, {-1.0, -1.0}, { 1.0, -1.0 } }; 15 | var vb = new vertex Buffer<[]Vertex>(device, &verts); 16 | var vi = new VertexInput(vb); 17 | 18 | var pipeline = new RenderPipeline(device); 19 | var encoder = new CommandEncoder(device); 20 | var fb = swapChain.GetCurrentTexture().CreateColorOutput(LoadOp.Clear); 21 | var renderPass = new RenderPass(encoder, { position = vi, fragColor = fb }); 22 | renderPass.SetPipeline(pipeline); 23 | renderPass.Draw(3, 1, 0, 0); 24 | renderPass.End(); 25 | device.GetQueue().Submit(encoder.Finish()); 26 | swapChain.Present(); 27 | 28 | while (System.IsRunning()) System.GetNextEvent(); 29 | -------------------------------------------------------------------------------- /test/error-validate.t: -------------------------------------------------------------------------------- 1 | class BadPipelineField { 2 | vertex main(vb : &VertexBuiltins) {} 3 | fragment main(fb : &FragmentBuiltins) {} 4 | var bad : int; 5 | } 6 | 7 | class NoVertexShader { 8 | fragment main(fb : &FragmentBuiltins) {} 9 | } 10 | 11 | class NoFragmentShader { 12 | vertex main(vb : &VertexBuiltins) {} 13 | } 14 | 15 | class InheritedVertexShaderGood : NoFragmentShader { 16 | fragment main(fb : &FragmentBuiltins) {} 17 | } 18 | 19 | class InheritedFragmentShaderGood : NoVertexShader { 20 | vertex main(vb : &VertexBuiltins) {} 21 | } 22 | 23 | class NoShaders { 24 | } 25 | 26 | class NoShaders2 { 27 | } 28 | 29 | var device = new Device(); 30 | var encoder = new CommandEncoder(device); 31 | 32 | new RenderPipeline(device); 33 | new RenderPass(encoder, {}); 34 | new RenderPipeline(device); 35 | new RenderPipeline(device); 36 | new RenderPipeline(device); 37 | var a : *RenderPipeline; 38 | new RenderPipeline(device); // this should pass 39 | new RenderPipeline(device); // this should pass 40 | new RenderPass(encoder, {}); // this should pass (no shaders neeeded) 41 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | We'd love to accept your patches and contributions to Toucan. 4 | 5 | ## Before you begin 6 | 7 | ### Sign our Contributor License Agreement 8 | 9 | Contributions to this project must be accompanied by a 10 | [Contributor License Agreement](https://cla.developers.google.com/about) (CLA). 11 | You (or your employer) retain the copyright to your contribution; this simply 12 | gives us permission to use and redistribute your contributions as part of the 13 | project. 14 | 15 | If you or your current employer have already signed the Google CLA (even if it 16 | was for a different project), you probably don't need to do it again. 17 | 18 | Visit to see your current agreements or to 19 | sign a new one. 20 | 21 | ### Review our Community Guidelines 22 | 23 | This project follows 24 | [Google's Open Source Community Guidelines](https://opensource.google/conduct/). 25 | 26 | ## Contribution process 27 | 28 | ### Code Reviews 29 | 30 | All submissions, including submissions by project members, require review. We 31 | use GitHub pull requests for this purpose. Consult 32 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more 33 | information on using pull requests. 34 | -------------------------------------------------------------------------------- /test/interactive/triangle-with-vertex-helper.t: -------------------------------------------------------------------------------- 1 | using Vertex = float<2>; 2 | class Pipeline { 3 | static deviceonly helper(v : *VertexInput) : Vertex { return v.Get(); } 4 | vertex main(vb : &VertexBuiltins) { vb.position = {@Pipeline.helper(vertices), 0.0, 1.0}; } 5 | fragment main(fb : &FragmentBuiltins) { fragColor.Set( {0.0, 1.0, 0.0, 1.0} ); } 6 | var vertices : *VertexInput; 7 | var fragColor : *ColorOutput; 8 | } 9 | var device = new Device(); 10 | var window = new Window({640, 480}); 11 | var swapChain = new SwapChain(device, window); 12 | var verts : [3]Vertex = { {0.0, 1.0}, {-1.0, -1.0}, {1.0, -1.0} }; 13 | var vb = new vertex Buffer<[]Vertex>(device, &verts); 14 | var pipeline = new RenderPipeline(device); 15 | var encoder = new CommandEncoder(device); 16 | var vi = new VertexInput(vb); 17 | var fb = swapChain.GetCurrentTexture().CreateColorOutput(LoadOp.Clear); 18 | var renderPass = new RenderPass(encoder, { vertices = vi, fragColor = fb }); 19 | renderPass.SetPipeline(pipeline); 20 | renderPass.Draw(3, 1, 0, 0); 21 | renderPass.End(); 22 | device.GetQueue().Submit(encoder.Finish()); 23 | swapChain.Present(); 24 | while (System.IsRunning()) System.GetNextEvent(); 25 | -------------------------------------------------------------------------------- /parser/parser.h: -------------------------------------------------------------------------------- 1 | // Copyright 2023 The Toucan Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef _PARSER_PARSER_H 16 | namespace Toucan { 17 | class SymbolTable; 18 | class TypeTable; 19 | class NodeVector; 20 | class Stmts; 21 | }; // namespace Toucan 22 | 23 | extern FILE* yyin; 24 | extern int ParseProgram(const char* filename, 25 | Toucan::SymbolTable* symbols, 26 | Toucan::TypeTable* types, 27 | Toucan::NodeVector* nodes, 28 | const std::vector& includePaths, 29 | Toucan::Stmts** stmts); 30 | #endif 31 | -------------------------------------------------------------------------------- /test/interactive/triangle-vertex-input-parameter.t: -------------------------------------------------------------------------------- 1 | using Vertex = float<4>; 2 | var device = new Device(); 3 | var window = new Window({640, 480}); 4 | var swapChain = new SwapChain(device, window); 5 | var verts : [3]Vertex = { { 0.0, 1.0, 0.0, 1.0 }, {-1.0, -1.0, 0.0, 1.0 }, { 1.0, -1.0, 0.0, 1.0 } }; 6 | var vb = new vertex Buffer<[]Vertex>(device, &verts); 7 | class Pipeline { 8 | static deviceonly getCurrentVert(v : *VertexInput) : float<4> { return v.Get(); } 9 | vertex main(vb : &VertexBuiltins) { vb.position = this.getCurrentVert(vertices); } 10 | fragment main(fb : &FragmentBuiltins) { fragColor.Set( {0.0, 1.0, 0.0, 1.0} ); } 11 | var vertices : *VertexInput; 12 | var fragColor : *ColorOutput; 13 | } 14 | var pipeline = new RenderPipeline(device); 15 | var encoder = new CommandEncoder(device); 16 | var vi = new VertexInput(vb); 17 | var fb = swapChain.GetCurrentTexture().CreateColorOutput(LoadOp.Clear); 18 | var renderPass = new RenderPass(encoder, { vertices = vi, fragColor = fb }); 19 | renderPass.SetPipeline(pipeline); 20 | renderPass.Draw(3, 1, 0, 0); 21 | renderPass.End(); 22 | device.GetQueue().Submit(encoder.Finish()); 23 | swapChain.Present(); 24 | while (System.IsRunning()) System.GetNextEvent(); 25 | -------------------------------------------------------------------------------- /tools/make-ipa.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright 2025 The Toucan Authors 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | import argparse 18 | import os 19 | import plistlib 20 | import shutil 21 | import subprocess 22 | import tempfile 23 | 24 | argparser = argparse.ArgumentParser(description="Create an .ipa file") 25 | argparser.add_argument('--app-file') 26 | argparser.add_argument('--ipa-file') 27 | args = vars(argparser.parse_args()) 28 | 29 | app_file = args['app_file'] 30 | ipa_file = args['ipa_file'] 31 | tempdirname = tempfile.mkdtemp() 32 | payload_dir = tempdirname + "/Payload" 33 | os.mkdir(payload_dir) 34 | os.symlink(app_file, payload_dir + "/" + os.path.basename(app_file)) 35 | os.chdir(tempdirname) 36 | subprocess.check_call(["zip", "-r", ipa_file, "Payload"]) 37 | shutil.rmtree(tempdirname) 38 | -------------------------------------------------------------------------------- /samples/include/quaternion.t: -------------------------------------------------------------------------------- 1 | class Quaternion { 2 | Quaternion(x : float, y : float, z : float, w : float) { q = float<4>(x, y, z, w); } 3 | Quaternion(v : float<4>) { q = v; } 4 | Quaternion(axis : float<3>, angle : float) { 5 | var scaledAxis = axis * Math.sin(angle * 0.5); 6 | 7 | q.xyz = scaledAxis; 8 | q.w = Math.cos(angle * 0.5); 9 | } 10 | len() : float { return Math.length(q); } 11 | normalize() { q = q / this.len(); } 12 | mul(other : Quaternion) : Quaternion { 13 | var p = other.q; 14 | var r : Quaternion; 15 | 16 | r.q.x = p.w * q.x + p.x * q.w + p.y * q.z - p.z * q.y; 17 | r.q.y = p.w * q.y + p.y * q.w + p.z * q.x - p.x * q.z; 18 | r.q.z = p.w * q.z + p.z * q.w + p.x * q.y - p.y * q.x; 19 | r.q.w = p.w * q.w - p.x * q.x - p.y * q.y - p.z * q.z; 20 | 21 | return r; 22 | } 23 | toMatrix() : float<4,4> { 24 | var x = q.x; 25 | var y = q.y; 26 | var z = q.z; 27 | var w = q.w; 28 | return float<4,4>(float<4>(1.0-2.0*(y*y+z*z), 2.0*(x*y+z*w), 2.0*(x*z-y*w), 0.0), 29 | float<4>( 2.0*(x*y-z*w), 1.0-2.0*(x*x+z*z), 2.0*(y*z+x*w), 0.0), 30 | float<4>( 2.0*(x*z+y*w), 2.0*(y*z-x*w), 1.0-2.0*(x*x+y*y), 0.0), 31 | float<4>( 0.0, 0.0, 0.0, 1.0)); 32 | } 33 | var q : float<4>; 34 | } 35 | -------------------------------------------------------------------------------- /gn/ar.py: -------------------------------------------------------------------------------- 1 | # Copyright 2023 The Toucan Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import os 16 | import subprocess 17 | import sys 18 | 19 | # Equivalent to: rm -f $2 && $1 rcs $2 @$3 20 | 21 | ar, output, rspfile = sys.argv[1:] 22 | 23 | if os.path.exists(output): 24 | os.remove(output) 25 | 26 | if sys.platform != 'darwin': 27 | sys.exit(subprocess.call([ar, "rcs", output, "@" + rspfile])) 28 | 29 | # Mac ar doesn't support @rspfile syntax. 30 | objects = open(rspfile).read().split() 31 | # It also spams stderr with warnings about objects having no symbols. 32 | pipe = subprocess.Popen([ar, "rcs", output] + objects, stderr=subprocess.PIPE) 33 | _, err = pipe.communicate() 34 | for line in err.splitlines(): 35 | if b'has no symbols' not in line: 36 | sys.stderr.write(line.decode("utf-8") + '\n') 37 | sys.exit(pipe.returncode) 38 | -------------------------------------------------------------------------------- /samples/gouraud.t: -------------------------------------------------------------------------------- 1 | class Vertex { 2 | var position : float<2>; 3 | var color : float<3>; 4 | } 5 | 6 | class Pipeline { 7 | vertex main(vb : &VertexBuiltins) : float<3> { 8 | var v = vertices.Get(); 9 | vb.position = {@v.position, 0.0, 1.0}; 10 | return v.color; 11 | } 12 | fragment main(fb : &FragmentBuiltins, varyings : float<3>) { 13 | fragColor.Set({@varyings, 1.0}); 14 | } 15 | var fragColor : *ColorOutput; 16 | var vertices : *VertexInput; 17 | } 18 | 19 | var device = new Device(); 20 | var window = new Window({640, 480}); 21 | var swapChain = new SwapChain(device, window); 22 | var verts = [3]Vertex{ 23 | { position = { 0.0, 1.0 }, color = { 1.0, 0.0, 0.0 } }, 24 | { position = {-1.0, -1.0 }, color = { 0.0, 1.0, 0.0 } }, 25 | { position = { 1.0, -1.0 }, color = { 0.0, 0.0, 1.0 } } 26 | }; 27 | 28 | var vb = new vertex Buffer<[]Vertex>(device, &verts); 29 | var vi = new VertexInput(vb); 30 | var fb = swapChain.GetCurrentTexture().CreateColorOutput(LoadOp.Clear); 31 | var pipeline = new RenderPipeline(device); 32 | var encoder = new CommandEncoder(device); 33 | var renderPass = new RenderPass(encoder, { vertices = vi, fragColor = fb }); 34 | renderPass.SetPipeline(pipeline); 35 | renderPass.Draw(3, 1, 0, 0); 36 | renderPass.End(); 37 | device.GetQueue().Submit(encoder.Finish()); 38 | swapChain.Present(); 39 | while (System.IsRunning()) System.GetNextEvent(); 40 | -------------------------------------------------------------------------------- /test/compute-pass-ptr-to-element.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class ComputeBindings { 4 | var buffer : *storage Buffer<[]int>; 5 | } 6 | 7 | class Struct { 8 | var a : int; 9 | } 10 | 11 | class Compute { 12 | static set(p : &int, value : int) { 13 | p = value; 14 | } 15 | compute(1, 1,1) main(cb : &ComputeBuiltins) { 16 | var buffer = bindings.Get().buffer.MapWrite(); 17 | var i : int; 18 | var array : [1]int; 19 | var struct : Struct; 20 | this.set(&i, 7); 21 | this.set(&array[0], 21); 22 | this.set(&struct.a, 42); 23 | buffer[0] = i; 24 | buffer[1] = array[0]; 25 | buffer[2] = struct.a; 26 | } 27 | var bindings : *BindGroup; 28 | } 29 | 30 | var device = new Device(); 31 | 32 | var computePipeline = new ComputePipeline(device); 33 | 34 | var storageBuf = new storage Buffer<[]int>(device, 3); 35 | var hostBuf = new hostreadable Buffer<[]int>(device, 3); 36 | 37 | var bg = new BindGroup(device, {buffer = storageBuf}); 38 | 39 | var encoder = new CommandEncoder(device); 40 | var computePass = new ComputePass(encoder, {bindings = bg}); 41 | computePass.SetPipeline(computePipeline); 42 | computePass.Dispatch(1, 1, 1); 43 | computePass.End(); 44 | hostBuf.CopyFromBuffer(encoder, storageBuf); 45 | device.GetQueue().Submit(encoder.Finish()); 46 | 47 | Test.Expect(hostBuf.MapRead()[0] == 7); 48 | Test.Expect(hostBuf.MapRead()[1] == 21); 49 | Test.Expect(hostBuf.MapRead()[2] == 42); 50 | -------------------------------------------------------------------------------- /ast/file_location.h: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Toucan Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef _AST_FILE_LOCATION_H_ 16 | #define _AST_FILE_LOCATION_H_ 17 | 18 | #include 19 | #include 20 | 21 | namespace Toucan { 22 | 23 | struct FileLocation { 24 | FileLocation(); 25 | FileLocation(const FileLocation& other); 26 | FileLocation(std::shared_ptr f, int n); 27 | std::shared_ptr filename; 28 | int lineNum = -1; 29 | }; 30 | 31 | class ScopedFileLocation { 32 | public: 33 | ScopedFileLocation(FileLocation* p, const FileLocation& newLocation) 34 | : location_(p), previous_(*p) { 35 | *location_ = newLocation; 36 | } 37 | ~ScopedFileLocation() { *location_ = previous_; } 38 | 39 | private: 40 | FileLocation* location_; 41 | FileLocation previous_; 42 | }; 43 | 44 | } // namespace Toucan 45 | 46 | #endif // _AST_FILE_LOCATION_H_ 47 | -------------------------------------------------------------------------------- /tools/dragon-massager.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright 2025 The Toucan Authors 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | import json 18 | 19 | with open('stanford-dragon.json', 'r') as file: 20 | data = json.load(file) 21 | 22 | cells = data["cells"] 23 | positions = data["positions"] 24 | 25 | count = 0 26 | print("var dragonTriangles : [" + str(len(cells)) + "][3]uint = {"); 27 | for cell in cells: 28 | count += 1 29 | possibleComma = "," if (count < len(cells)) else "" 30 | print(" {" + str(cell[0]) + ", " + str(cell[1]) + ", " + str(cell[2]) + "}" + possibleComma) 31 | 32 | print("};"); 33 | 34 | count = 0; 35 | print("var dragonVertices : [" + str(len(positions)) + "]float<3> = {"); 36 | for position in positions: 37 | count += 1 38 | possibleComma = "," if (count < len(positions)) else "" 39 | print(" {" + str(position[0]) + ", " + str(position[1]) + ", " + str(position[2]) + "}" + possibleComma) 40 | print("};"); 41 | -------------------------------------------------------------------------------- /api/api_internal.h: -------------------------------------------------------------------------------- 1 | // Copyright 2023 The Toucan Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef _APIINTERNAL_H 16 | #define _APIINTERNAL_H 17 | 18 | #include 19 | 20 | namespace Toucan { 21 | 22 | struct Device { 23 | Device(wgpu::Device d) : device(d) {} 24 | wgpu::Device device; 25 | }; 26 | 27 | struct SwapChain { 28 | SwapChain(wgpu::Surface s, wgpu::Device d, wgpu::Extent3D e, wgpu::TextureFormat f, void* p) 29 | : surface(s), device(d), extent(e), format(f), pool(p) {} 30 | wgpu::Surface surface; 31 | wgpu::Device device; 32 | wgpu::Extent3D extent; 33 | wgpu::TextureFormat format; 34 | void* pool; 35 | }; 36 | 37 | wgpu::TextureFormat GetPreferredPixelFormat(); 38 | wgpu::TextureFormat ToDawnTextureFormat(Type* type); 39 | wgpu::Device CreateDawnDevice(wgpu::BackendType type, const wgpu::DeviceDescriptor* desc); 40 | 41 | } // namespace Toucan 42 | #endif // _APIINTERNAL_H 43 | -------------------------------------------------------------------------------- /test/texture-size.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | include "include/string.t" 3 | var device = new Device(); 4 | 5 | var texture1d = new sampleable Texture1D(device, 42, 1); 6 | Test.Expect(texture1d.GetSize() == 42); 7 | Test.Expect(texture1d.GetSize(0) == 42); 8 | 9 | var texture2d = new sampleable Texture2D(device, {4, 2}, 2); 10 | Test.Expect(Math.all(texture2d.GetSize() == uint<2>{4, 2})); 11 | Test.Expect(Math.all(texture2d.GetSize(0) == uint<2>{4, 2})); 12 | Test.Expect(Math.all(texture2d.GetSize(1) == uint<2>{2, 1})); 13 | 14 | var texture3d = new sampleable Texture3D(device, {6, 3, 5}, 2); 15 | Test.Expect(Math.all(texture3d.GetSize() == uint<3>{6, 3, 5})); 16 | Test.Expect(Math.all(texture3d.GetSize(0) == uint<3>{6, 3, 5})); 17 | Test.Expect(Math.all(texture3d.GetSize(1) == uint<3>{3, 1, 5})); 18 | 19 | var textureCube = new sampleable TextureCube(device, {2, 4}, 2); 20 | Test.Expect(Math.all(textureCube.GetSize() == uint<2>{2, 4})); 21 | Test.Expect(Math.all(textureCube.GetSize(0) == uint<2>{2, 4})); 22 | Test.Expect(Math.all(textureCube.GetSize(1) == uint<2>{1, 2})); 23 | 24 | var texture2DArray = new sampleable Texture2DArray(device, {4, 8}, 3, 2); 25 | Test.Expect(Math.all(texture2DArray.GetSize() == uint<2>{4, 8})); 26 | Test.Expect(Math.all(texture2DArray.GetSize(0) == uint<2>{4, 8})); 27 | Test.Expect(Math.all(texture2DArray.GetSize(1) == uint<2>{2, 4})); 28 | Test.Expect(Math.all(texture2DArray.GetSize(2) == uint<2>{1, 2})); 29 | Test.Expect(texture2DArray.GetNumLayers() == 3); 30 | -------------------------------------------------------------------------------- /test/compute-builtins.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class ComputeBindings { 4 | var buffer : *storage Buffer<[]int>; 5 | } 6 | 7 | class Compute { 8 | compute(1, 1, 1) main(cb : &ComputeBuiltins) { 9 | var buffer = bindings.Get().buffer.MapWrite(); 10 | var a = int<2>(0, 1); 11 | var b = int<2>(2, 1); 12 | var c = int<2>(3, 4); 13 | if (Math.all(a == a)) buffer[0] = 1; 14 | if (Math.all(a == b)) buffer[1] = 1; 15 | if (Math.any(a == b)) buffer[2] = 1; 16 | if (Math.any(a == c)) buffer[3] = 1; 17 | if (Math.any(a != a)) buffer[4] = 1; 18 | if (Math.all(a != b)) buffer[5] = 1; 19 | } 20 | var bindings : *BindGroup; 21 | } 22 | 23 | var device = new Device(); 24 | 25 | var computePipeline = new ComputePipeline(device); 26 | 27 | var storageBuf = new storage Buffer<[]int>(device, 6); 28 | var hostBuf = new hostreadable Buffer<[]int>(device, 6); 29 | 30 | var bg = new BindGroup(device, {buffer = storageBuf}); 31 | 32 | var encoder = new CommandEncoder(device); 33 | var computePass = new ComputePass(encoder, {bindings = bg}); 34 | computePass.SetPipeline(computePipeline); 35 | computePass.Dispatch(1, 1, 1); 36 | computePass.End(); 37 | hostBuf.CopyFromBuffer(encoder, storageBuf); 38 | device.GetQueue().Submit(encoder.Finish()); 39 | 40 | var result = hostBuf.MapRead(); 41 | Test.Expect(result[0] == 1); 42 | Test.Expect(result[1] == 0); 43 | Test.Expect(result[2] == 1); 44 | Test.Expect(result[3] == 0); 45 | Test.Expect(result[4] == 0); 46 | Test.Expect(result[5] == 0); 47 | -------------------------------------------------------------------------------- /test/unfilterable.t: -------------------------------------------------------------------------------- 1 | include "include/test.t" 2 | 3 | class CopyBindings { 4 | var depth : *unfilterable SampleableTexture2D; 5 | var result : *storage Buffer>; 6 | } 7 | 8 | class DrawPass { 9 | var depth : *DepthStencilOutput; 10 | } 11 | 12 | class CopyPipeline { 13 | compute(1, 1, 1) main(vb : &ComputeBuiltins) { 14 | var depth = bindings.Get().depth; 15 | var result = bindings.Get().result.Map(); 16 | result: = depth.Load(uint<2>{0u, 0u}, 0u); 17 | } 18 | var bindings : *BindGroup; 19 | } 20 | var device = new Device(); 21 | var copyPipeline = new ComputePipeline(device); 22 | var depth = new renderable sampleable Texture2D(device, uint<2>(1, 1)); 23 | var resultBuf = new storage Buffer>(device, 1); 24 | var readbackBuf = new hostreadable Buffer>(device, 1); 25 | var bindings = new BindGroup(device, { 26 | depth = depth.CreateSampleableView(), 27 | result = resultBuf 28 | }); 29 | var encoder = new CommandEncoder(device); 30 | var renderPass = new RenderPass(encoder, { 31 | depth = depth.CreateDepthStencilOutput(depthLoadOp = LoadOp.Clear, depthClearValue = 1.0) 32 | }); 33 | renderPass.End(); 34 | var copyPass = new ComputePass(encoder, { bindings = bindings }); 35 | copyPass.SetPipeline(copyPipeline); 36 | copyPass.Dispatch(1, 1, 1); 37 | copyPass.End(); 38 | readbackBuf.CopyFromBuffer(encoder, resultBuf); 39 | device.GetQueue().Submit(encoder.Finish()); 40 | var result = readbackBuf.MapRead()[0]; 41 | Test.Expect(result == 1.0); 42 | -------------------------------------------------------------------------------- /samples/include/event-handler.t: -------------------------------------------------------------------------------- 1 | class EventHandler { 2 | Rotate(diff : int<2>) { 3 | rotation += (float<2>) diff / 200.0; 4 | } 5 | Handle(event : &Event) { 6 | if (event.type == EventType.MouseDown) { 7 | mouseDown = true; 8 | } else if (event.type == EventType.MouseUp) { 9 | mouseDown = false; 10 | } else if (event.type == EventType.MouseMove) { 11 | var diff = event.position - prevPosition; 12 | if (mouseDown || (event.modifiers & EventModifiers.Control) != 0) { 13 | this.Rotate(diff); 14 | } else if ((event.modifiers & EventModifiers.Shift) != 0) { 15 | distance += (float) diff.y / 100.0; 16 | } 17 | prevPosition = event.position; 18 | } else if (event.type == EventType.TouchStart) { 19 | prevTouches = event.touches; 20 | } else if (event.type == EventType.TouchMove) { 21 | if (event.numTouches != prevNumTouches) { 22 | } else if (event.numTouches == 1) { 23 | this.Rotate(event.touches[0] - prevTouches[0]); 24 | } else if (event.numTouches == 2) { 25 | var prevDistance = Math.length((float<2>) (prevTouches[1] - prevTouches[0])); 26 | var curDistance = Math.length((float<2>) (event.touches[1] - event.touches[0])); 27 | distance *= prevDistance / curDistance; 28 | } 29 | prevTouches = event.touches; 30 | prevNumTouches = event.numTouches; 31 | } 32 | } 33 | var mouseDown : bool; 34 | var prevPosition : int<2>; 35 | var prevTouches : [10]int<2>; 36 | var prevNumTouches : int; 37 | var rotation : float<2>; 38 | var distance : float; 39 | } 40 | -------------------------------------------------------------------------------- /test/interactive/gouraud-separate-vertex-buffers.t: -------------------------------------------------------------------------------- 1 | var device = new Device(); 2 | var window = new Window({640, 480}); 3 | var swapChain = new SwapChain(device, window); 4 | 5 | var positions = [3]float<2>{ 6 | { 0.0, 1.0 }, 7 | {-1.0, -1.0 }, 8 | { 1.0, -1.0 } 9 | }; 10 | 11 | var colors = [3]float<3>{ 12 | {1.0, 0.0, 0.0}, 13 | {0.0, 1.0, 0.0}, 14 | {0.0, 0.0, 1.0} 15 | }; 16 | 17 | class Pipeline { 18 | vertex main(vb : &VertexBuiltins) : float<3> { 19 | vb.position = { @position.Get(), 0.0, 1.0 }; 20 | return color.Get(); 21 | } 22 | fragment main(fb : &FragmentBuiltins, varyings : float<3>) { 23 | fragColor.Set(float<4>(varyings.r, varyings.g, varyings.b, 1.0)); 24 | } 25 | var fragColor : *ColorOutput; 26 | var position : *VertexInput>; 27 | var color : *VertexInput>; 28 | } 29 | 30 | var pipeline = new RenderPipeline(device); 31 | var encoder = new CommandEncoder(device); 32 | var positionsVB = new vertex Buffer<[]float<2>>(device, &positions); 33 | var colorsVB = new vertex Buffer<[]float<3>>(device, &colors); 34 | var p : Pipeline; 35 | p.fragColor = swapChain.GetCurrentTexture().CreateColorOutput(LoadOp.Clear); 36 | p.position = new VertexInput>(positionsVB); 37 | p.color = new VertexInput>(colorsVB); 38 | var renderPass = new RenderPass(encoder, &p); 39 | renderPass.SetPipeline(pipeline); 40 | renderPass.Draw(3, 1, 0, 0); 41 | renderPass.End(); 42 | device.GetQueue().Submit(encoder.Finish()); 43 | swapChain.Present(); 44 | while (System.IsRunning()) System.GetNextEvent(); 45 | -------------------------------------------------------------------------------- /third_party/skia/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 Google Inc. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the 13 | distribution. 14 | 15 | * Neither the name of the copyright holder nor the names of its 16 | contributors may be used to endorse or promote products derived 17 | from this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /third_party/skia/bin/fetch-gn: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright 2016 Google Inc. 4 | # 5 | # Use of this source code is governed by a BSD-style license that can be 6 | # found in the LICENSE file. 7 | 8 | import os 9 | import platform 10 | import shutil 11 | import stat 12 | import sys 13 | import tempfile 14 | import zipfile 15 | 16 | from urllib.request import urlopen 17 | 18 | os.chdir(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, os.pardir)) 19 | 20 | gnzip = os.path.join(tempfile.mkdtemp(), 'gn.zip') 21 | with open(gnzip, 'wb') as f: 22 | OS = {'darwin': 'mac', 'linux': 'linux', 'linux2': 'linux', 'win32': 'windows'}[sys.platform] 23 | cpu = {'aarch64': 'arm64', 'amd64': 'amd64', 'arm64': 'arm64', 'x86_64': 'amd64'}[platform.machine().lower()] 24 | 25 | rev = 'b2afae122eeb6ce09c52d63f67dc53fc517dbdc8' 26 | url = 'https://chrome-infra-packages.appspot.com/dl/gn/gn/{}-{}/+/git_revision:{}'.format( 27 | OS,cpu,rev) 28 | f.write(urlopen(url).read()) 29 | 30 | gn_filename = 'gn.exe' if 'win32' in sys.platform else 'gn' 31 | with zipfile.ZipFile(gnzip, 'r') as f: 32 | f.extract(gn_filename, 'bin') 33 | 34 | gn_path = os.path.join('bin', gn_filename) 35 | 36 | os.chmod(gn_path, 37 | stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR | 38 | stat.S_IRGRP | stat.S_IXGRP | 39 | stat.S_IROTH | stat.S_IXOTH ) 40 | 41 | # We'll also copy to a path that depot_tools' GN wrapper will expect to find the binary. 42 | depot_tools_gn_dir = os.path.join('third_party', 'gn') 43 | os.makedirs(depot_tools_gn_dir, exist_ok=True) 44 | shutil.copy(gn_path, os.path.join(depot_tools_gn_dir, gn_filename)) 45 | -------------------------------------------------------------------------------- /third_party/build/libjpeg-turbo/LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (C)2009-2023 D. R. Commander. All Rights Reserved.
2 | Copyright (C)2015 Viktor Szathmáry. All Rights Reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | - Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | - Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | - Neither the name of the libjpeg-turbo Project nor the names of its 13 | contributors may be used to endorse or promote products derived from this 14 | software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS", 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE 20 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /samples/include/cube.t: -------------------------------------------------------------------------------- 1 | var cubeVerts = [24]float<3>{ 2 | // Right face 3 | { 1.0, -1.0, -1.0}, 4 | { 1.0, -1.0, 1.0}, 5 | { 1.0, 1.0, 1.0}, 6 | { 1.0, 1.0, -1.0}, 7 | 8 | // Left face 9 | {-1.0, 1.0, 1.0}, 10 | {-1.0, -1.0, 1.0}, 11 | {-1.0, -1.0, -1.0}, 12 | {-1.0, 1.0, -1.0}, 13 | 14 | // Bottom face 15 | {-1.0, -1.0, -1.0}, 16 | { 1.0, -1.0, -1.0}, 17 | { 1.0, -1.0, 1.0}, 18 | {-1.0, -1.0, 1.0}, 19 | 20 | // Top face 21 | {-1.0, 1.0, -1.0}, 22 | {-1.0, 1.0, 1.0}, 23 | { 1.0, 1.0, 1.0}, 24 | { 1.0, 1.0, -1.0}, 25 | 26 | // Back face 27 | {-1.0, -1.0, -1.0}, 28 | { 1.0, -1.0, -1.0}, 29 | { 1.0, 1.0, -1.0}, 30 | {-1.0, 1.0, -1.0}, 31 | 32 | // Front face 33 | {-1.0, -1.0, 1.0}, 34 | { 1.0, -1.0, 1.0}, 35 | { 1.0, 1.0, 1.0}, 36 | {-1.0, 1.0, 1.0} 37 | }; 38 | 39 | var cubeTexCoords = [24]float<2>( 40 | // Right face 41 | {1.0, 1.0}, 42 | {0.0, 1.0}, 43 | {0.0, 0.0}, 44 | {1.0, 0.0}, 45 | 46 | // Left face 47 | {1.0, 0.0}, 48 | {1.0, 1.0}, 49 | {0.0, 1.0}, 50 | {0.0, 0.0}, 51 | 52 | // Bottom face 53 | {0.0, 1.0}, 54 | {1.0, 1.0}, 55 | {1.0, 0.0}, 56 | {0.0, 0.0}, 57 | 58 | // Top face 59 | {0.0, 0.0}, 60 | {0.0, 1.0}, 61 | {1.0, 1.0}, 62 | {1.0, 0.0}, 63 | 64 | // Back face 65 | {1.0, 1.0}, 66 | {0.0, 1.0}, 67 | {0.0, 0.0}, 68 | {1.0, 0.0}, 69 | 70 | // Front face 71 | {0.0, 1.0}, 72 | {1.0, 1.0}, 73 | {1.0, 0.0}, 74 | {0.0, 0.0} 75 | ); 76 | 77 | var cubeIndices = [36]uint{ 78 | 0, 1, 2, 0, 2, 3, 79 | 4, 5, 6, 4, 6, 7, 80 | 8, 9, 10, 8, 10, 11, 81 | 12, 13, 14, 12, 14, 15, 82 | 16, 17, 18, 16, 18, 19, 83 | 20, 21, 22, 20, 22, 23 84 | }; 85 | -------------------------------------------------------------------------------- /test/interactive/gouraud-separate-vertex-buffers-parent-class.t: -------------------------------------------------------------------------------- 1 | var device = new Device(); 2 | var window = new Window({640, 480}); 3 | var swapChain = new SwapChain(device, window); 4 | 5 | var positions = [3]float<2>{ 6 | { 0.0, 1.0 }, 7 | {-1.0, -1.0 }, 8 | { 1.0, -1.0 } 9 | }; 10 | 11 | var colors = [3]float<3>{ 12 | {1.0, 0.0, 0.0}, 13 | {0.0, 1.0, 0.0}, 14 | {0.0, 0.0, 1.0} 15 | }; 16 | 17 | class BasePipeline { 18 | var position : *VertexInput>; 19 | } 20 | 21 | class Pipeline : BasePipeline { 22 | vertex main(vb : &VertexBuiltins) : float<3> { 23 | var v = position.Get(); 24 | vb.position = float<4>(v.x, v.y, 0.0, 1.0); 25 | return color.Get(); 26 | } 27 | fragment main(fb : &FragmentBuiltins, varyings : float<3>) { 28 | fragColor.Set(float<4>(varyings.r, varyings.g, varyings.b, 1.0)); 29 | } 30 | var fragColor : *ColorOutput; 31 | var color : *VertexInput>; 32 | } 33 | 34 | var pipeline = new RenderPipeline(device); 35 | var encoder = new CommandEncoder(device); 36 | var positionsVB = new vertex Buffer<[]float<2>>(device, &positions); 37 | var colorsVB = new vertex Buffer<[]float<3>>(device, &colors); 38 | var p : Pipeline; 39 | p.fragColor = swapChain.GetCurrentTexture().CreateColorOutput(LoadOp.Clear); 40 | p.position = new VertexInput>(positionsVB); 41 | p.color = new VertexInput>(colorsVB); 42 | var renderPass = new RenderPass(encoder, &p); 43 | renderPass.SetPipeline(pipeline); 44 | renderPass.Draw(3, 1, 0, 0); 45 | renderPass.End(); 46 | device.GetQueue().Submit(encoder.Finish()); 47 | swapChain.Present(); 48 | while (System.IsRunning()) System.GetNextEvent(); 49 | -------------------------------------------------------------------------------- /test/interactive/uniform-with-padded-array.t: -------------------------------------------------------------------------------- 1 | using Vertex = float<2>; 2 | class Uniforms { 3 | var padding : [1]float; 4 | var intPadding : int; 5 | var color : float<4>; 6 | } 7 | class Bindings { 8 | var uniforms : *uniform Buffer; 9 | } 10 | class Pipeline { 11 | vertex main(vb : &VertexBuiltins) { vb.position = {@vertices.Get(), 0.0, 1.0}; } 12 | fragment main(fb : &FragmentBuiltins) { 13 | fragColor.Set(bindings.Get().uniforms.MapRead().color); 14 | } 15 | var vertices : *VertexInput; 16 | var fragColor : *ColorOutput; 17 | var bindings : *BindGroup; 18 | } 19 | var device = new Device(); 20 | var window = new Window({640, 480}); 21 | var swapChain = new SwapChain(device, window); 22 | var verts = [3]Vertex{ {0.0, 1.0}, {-1.0, -1.0}, {1.0, -1.0} }; 23 | var vb = new vertex Buffer<[]Vertex>(device, &verts); 24 | var uniforms = new uniform Buffer(device, { color = { 0.0, 1.0, 0.0, 1.0 } }); 25 | var bg = new BindGroup(device, { uniforms }); 26 | var stagingBuffer = new hostwriteable Buffer(device); 27 | var pipeline = new RenderPipeline(device); 28 | var framebuffer = swapChain.GetCurrentTexture(); 29 | var encoder = new CommandEncoder(device); 30 | var vi = new VertexInput(vb); 31 | var fb = framebuffer.CreateColorOutput(LoadOp.Clear); 32 | var renderPass = new RenderPass(encoder, 33 | {vertices = vi, fragColor = fb, bindings = bg } 34 | ); 35 | renderPass.SetPipeline(pipeline); 36 | renderPass.Draw(3, 1, 0, 0); 37 | renderPass.End(); 38 | device.GetQueue().Submit(encoder.Finish()); 39 | swapChain.Present(); 40 | 41 | while (System.IsRunning()) System.GetNextEvent(); 42 | -------------------------------------------------------------------------------- /test/interactive/index-buffer.t: -------------------------------------------------------------------------------- 1 | class Vertex { 2 | var position : float<2>; 3 | var color : float<4>; 4 | }; 5 | 6 | class Pipeline { 7 | vertex main(vb : &VertexBuiltins) : float<4> { 8 | var v = vertices.Get(); 9 | vb.position = {@v.position, 0.0, 1.0}; 10 | return v.color; 11 | } 12 | fragment main(fb : &FragmentBuiltins, v : float<4>) { fragColor.Set(v); } 13 | var vertices : *VertexInput; 14 | var indices : *index Buffer<[]uint>; 15 | var fragColor : *ColorOutput; 16 | } 17 | 18 | var device = new Device(); 19 | var window = new Window({640, 480}); 20 | var queue = device.GetQueue(); 21 | var swapChain = new SwapChain(device, window); 22 | var verts = [4]Vertex{ 23 | { position = {-1.0, -1.0}, color = {1.0, 1.0, 1.0, 1.0} }, 24 | { position = { 1.0, -1.0}, color = {1.0, 0.0, 0.0, 1.0} }, 25 | { position = {-1.0, 1.0}, color = {0.0, 1.0, 0.0, 1.0} }, 26 | { position = { 1.0, 1.0}, color = {0.0, 0.0, 1.0, 1.0} } 27 | }; 28 | var indices = [6]uint{ 0, 1, 2, 1, 2, 3 }; 29 | var vb = new vertex Buffer<[]Vertex>(device, &verts); 30 | var ib = new index Buffer<[]uint>(device, &indices); 31 | var pipeline = new RenderPipeline(device); 32 | var encoder = new CommandEncoder(device); 33 | var vi = new VertexInput(vb); 34 | var fb = swapChain.GetCurrentTexture().CreateColorOutput(LoadOp.Clear); 35 | var renderPass = new RenderPass(encoder, { vertices = vi, indices = ib, fragColor = fb }); 36 | renderPass.SetPipeline(pipeline); 37 | renderPass.DrawIndexed(6, 1, 0, 0, 0); 38 | renderPass.End(); 39 | device.GetQueue().Submit(encoder.Finish()); 40 | swapChain.Present(); 41 | 42 | while (System.IsRunning()) System.GetNextEvent(); 43 | -------------------------------------------------------------------------------- /test/interactive/index-buffer-short.t: -------------------------------------------------------------------------------- 1 | class Vertex { 2 | var position : float<2>; 3 | var color : float<4>; 4 | }; 5 | 6 | class Pipeline { 7 | vertex main(vb : &VertexBuiltins) : float<4> { 8 | var v = vertices.Get(); 9 | vb.position = {@v.position, 0.0, 1.0}; 10 | return v.color; 11 | } 12 | fragment main(fb : &FragmentBuiltins, v : float<4>) { fragColor.Set(v); } 13 | var vertices : *VertexInput; 14 | var indices : *index Buffer<[]ushort>; 15 | var fragColor : *ColorOutput; 16 | } 17 | 18 | var device = new Device(); 19 | var window = new Window({640, 480}); 20 | var queue = device.GetQueue(); 21 | var swapChain = new SwapChain(device, window); 22 | var verts = [4]Vertex{ 23 | { position = {-1.0, -1.0}, color = {1.0, 1.0, 1.0, 1.0} }, 24 | { position = { 1.0, -1.0}, color = {1.0, 0.0, 0.0, 1.0} }, 25 | { position = {-1.0, 1.0}, color = {0.0, 1.0, 0.0, 1.0} }, 26 | { position = { 1.0, 1.0}, color = {0.0, 0.0, 1.0, 1.0} } 27 | }; 28 | var indices = [6]ushort{ 0s, 1s, 2s, 1s, 2s, 3s }; 29 | var vb = new vertex Buffer<[]Vertex>(device, &verts); 30 | var ib = new index Buffer<[]ushort>(device, &indices); 31 | var pipeline = new RenderPipeline(device); 32 | var encoder = new CommandEncoder(device); 33 | var vi = new VertexInput(vb); 34 | var fb = swapChain.GetCurrentTexture().CreateColorOutput(LoadOp.Clear); 35 | var renderPass = new RenderPass(encoder, { vertices = vi, indices = ib, fragColor = fb }); 36 | renderPass.SetPipeline(pipeline); 37 | renderPass.DrawIndexed(6, 1, 0, 0, 0); 38 | renderPass.End(); 39 | device.GetQueue().Submit(encoder.Finish()); 40 | swapChain.Present(); 41 | 42 | while (System.IsRunning()) System.GetNextEvent(); 43 | -------------------------------------------------------------------------------- /bench/array_float.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2023 The Toucan Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | #define SIZE 1024 18 | #define COUNT 1000000 19 | 20 | #ifdef _WIN32 21 | #include 22 | double get_time_usec() { 23 | FILETIME ft; 24 | GetSystemTimeAsFileTime(&ft); 25 | LARGE_INTEGER v; 26 | v.LowPart = ft.dwLowDateTime; 27 | v.HighPart = ft.dwHighDateTime; 28 | return static_cast(v.QuadPart) / 10.0; 29 | } 30 | #else 31 | #include 32 | double get_time_usec() { 33 | struct timeval t; 34 | gettimeofday(&t, nullptr); 35 | return 1000000.0 * t.tv_sec + t.tv_usec; 36 | } 37 | #endif 38 | 39 | int main() { 40 | float a[SIZE]; 41 | double start = get_time_usec(); 42 | for (int i = 0; i < SIZE; i += 1) { 43 | a[i] = 2000000.0f; 44 | } 45 | for (int j = 0; j < COUNT; j += 1) { 46 | for (int i = 0; i < SIZE; i += 1) { 47 | a[i] = a[i] * 1.00001f + 1.0f; 48 | } 49 | } 50 | double end = get_time_usec(); 51 | printf("result is %f\n", a[3]); 52 | printf("elapsed time %f usec, %f usec per iteration\n", end - start, 53 | (end - start) / (SIZE * COUNT)); 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | - implement window resize event 2 | - implement foreach 3 | - implement Math.inverse() on CPU side 4 | - implement bounds checking 5 | - use O1 optimization in TC 6 | - implement parsing of a method call without . 7 | - finish storage textures 8 | - refactor tc & tj 9 | - implement "constant" keyword 10 | - validate return values in semantic pass 11 | - implement "using" of a class (for static methods) 12 | - constify all Visitor arguments and Accept() functions? 13 | - all pointers are implicitly readonly in shader code? 14 | - remove AutoType in favour of parse-time checking? 15 | - ensure index/vertex/uniform/storage qualifiers are only applied to Buffer 16 | - decide on Vector vs List naming: VarVector? or VarList? 17 | - implement "Is<>" and "As<>" 18 | - write shader validation pass 19 | - check bind group contents: non-empty (to satisfy WGSL) 20 | - all classes other than bind groups must be POD 21 | - no virtual functions 22 | - no allocation 23 | - no pointers other than Buffer, Texture*, TextureView* 24 | - no conditional assignment to pointer variables 25 | - convert bindings generator from C to C++ 26 | - texture formats 27 | - prevent calls into null via native methods in api.t that don't exist 28 | - implement long, ulong 29 | - Make ClassTemplate take a vector of TemplateTypes, not just Type* 30 | - or maybe just a vector of std::string? 31 | - finish destructors 32 | - implement narrowing class casts 33 | - use shared_ptr in scope->method? (just in case the parser blows up before 34 | the method parse completes) 35 | - clean up scope stuff: 36 | - make scopes optional, and remove all strings from AST? 37 | - Var's outside of VarVectors and stmts probably leaking (e.g., classes, methods) 38 | - better error message for failed method match 39 | -------------------------------------------------------------------------------- /test/interactive/uniform-with-padded-class.t: -------------------------------------------------------------------------------- 1 | using Vertex = float<2>; 2 | class Padding { 3 | var pad1 : float; 4 | } 5 | 6 | class Uniforms { 7 | var padding : Padding; 8 | var intPadding : int; 9 | var color : float<4>; 10 | } 11 | class Bindings { 12 | var uniforms : *uniform Buffer; 13 | } 14 | class Pipeline { 15 | vertex main(vb : &VertexBuiltins) { vb.position = {@vertices.Get(), 0.0, 1.0}; } 16 | fragment main(fb : &FragmentBuiltins) { 17 | fragColor.Set(bindings.Get().uniforms.MapRead().color); 18 | } 19 | var vertices : *VertexInput; 20 | var fragColor : *ColorOutput; 21 | var bindings : *BindGroup; 22 | } 23 | var device = new Device(); 24 | var window = new Window({640, 480}); 25 | var swapChain = new SwapChain(device, window); 26 | var verts = [3]Vertex{ {0.0, 1.0}, {-1.0, -1.0}, {1.0, -1.0} }; 27 | var vb = new vertex Buffer<[]Vertex>(device, &verts); 28 | var uniforms = new uniform Buffer(device, { color = { 0.0, 1.0, 0.0, 1.0 } }); 29 | var bg = new BindGroup(device, { uniforms }); 30 | var stagingBuffer = new hostwriteable Buffer(device); 31 | var pipeline = new RenderPipeline(device); 32 | var framebuffer = swapChain.GetCurrentTexture(); 33 | var encoder = new CommandEncoder(device); 34 | var vi = new VertexInput(vb); 35 | var fb = framebuffer.CreateColorOutput(LoadOp.Clear); 36 | var renderPass = new RenderPass(encoder, 37 | {vertices = vi, fragColor = fb, bindings = bg } 38 | ); 39 | renderPass.SetPipeline(pipeline); 40 | renderPass.Draw(3, 1, 0, 0); 41 | renderPass.End(); 42 | device.GetQueue().Submit(encoder.Finish()); 43 | swapChain.Present(); 44 | 45 | while (System.IsRunning()) System.GetNextEvent(); 46 | -------------------------------------------------------------------------------- /test/interactive/uniform-triangle.t: -------------------------------------------------------------------------------- 1 | using Vertex = float<2>; 2 | class Uniforms { 3 | var color : float<4>; 4 | } 5 | class Bindings { 6 | var uniforms : *uniform Buffer; 7 | } 8 | class Pipeline { 9 | vertex main(vb : &VertexBuiltins) { vb.position = {@vertices.Get(), 0.0, 1.0}; } 10 | fragment main(fb : &FragmentBuiltins) { 11 | fragColor.Set(bindings.Get().uniforms.MapRead().color); 12 | } 13 | var vertices : *VertexInput; 14 | var fragColor : *ColorOutput; 15 | var bindings : *BindGroup; 16 | } 17 | var device = new Device(); 18 | var window = new Window({640, 480}); 19 | var swapChain = new SwapChain(device, window); 20 | var verts : [3]Vertex = { { 0.0, 1.0 }, {-1.0, -1.0 }, { 1.0, -1.0 } }; 21 | var vb = new vertex Buffer<[]Vertex>(device, &verts); 22 | var uniformBuffer = new uniform Buffer(device); 23 | var bg = new BindGroup(device, { uniformBuffer }); 24 | var stagingBuffer = new hostwriteable Buffer(device); 25 | var pipeline = new RenderPipeline(device); 26 | for (var i = 0; i < 300 && System.IsRunning(); ++i) { 27 | var encoder = new CommandEncoder(device); 28 | var f = (float) i / 300.0; 29 | stagingBuffer.MapWrite().color = float<4>(1.0 - f, f, 0.0, 1.0); 30 | uniformBuffer.CopyFromBuffer(encoder, stagingBuffer); 31 | var vi = new VertexInput(vb); 32 | var fb = swapChain.GetCurrentTexture().CreateColorOutput(LoadOp.Clear); 33 | var renderPass = new RenderPass(encoder, { vertices = vi, fragColor = fb, bindings = bg }); 34 | renderPass.SetPipeline(pipeline); 35 | renderPass.Draw(3, 1, 0, 0); 36 | renderPass.End(); 37 | device.GetQueue().Submit(encoder.Finish()); 38 | swapChain.Present(); 39 | while (System.HasPendingEvents()) { 40 | System.GetNextEvent(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /bindings/gen_bindings.h: -------------------------------------------------------------------------------- 1 | // Copyright 2023 The Toucan Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef _BINDINGS_GEN_BINDINGS_H_ 16 | #define _BINDINGS_GEN_BINDINGS_H_ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #include "dump_as_source_pass.h" 23 | 24 | namespace Toucan { 25 | 26 | class ClassType; 27 | class Method; 28 | class Type; 29 | 30 | class GenBindings { 31 | public: 32 | GenBindings(std::ostream& file, 33 | std::ostream& header, 34 | bool emitSymbolsAndStatements); 35 | void Run(const TypeVector& referencedTypes); 36 | int EmitType(Type* type); 37 | 38 | private: 39 | void EmitClass(ClassType* classType); 40 | void EmitMethod(Method* method); 41 | 42 | private: 43 | SymbolTable* symbols_; 44 | TypeTable* types_; 45 | TypeVector referencedTypes_; 46 | std::list classes_; 47 | std::ostream& file_; 48 | std::ostream& header_; 49 | bool emitSymbolsAndStatements_; 50 | std::unordered_map typeMap_; 51 | int numTypes_ = 0; 52 | DumpAsSourcePass sourcePass_; 53 | }; 54 | 55 | }; // namespace Toucan 56 | #endif 57 | -------------------------------------------------------------------------------- /test/interactive/blending.t: -------------------------------------------------------------------------------- 1 | using Vertex = float<2>; 2 | class Bindings { 3 | var color : *uniform Buffer>; 4 | } 5 | 6 | class Pipeline { 7 | vertex main(vb : &VertexBuiltins) { vb.position = {@vertices.Get(), 0.0, 1.0}; } 8 | fragment main(fb : &FragmentBuiltins) { fragColor.Set(bindings.Get().color.MapRead():); } 9 | var vertices : *VertexInput; 10 | var fragColor : *ColorOutput; 11 | var bindings : *BindGroup; 12 | } 13 | var device = new Device(); 14 | var window = new Window({640, 480}); 15 | var swapChain = new SwapChain(device, window); 16 | var verts = [3]Vertex{ { 0.0, 1.0 }, {-1.0, -1.0 }, { 1.0, -1.0 } }; 17 | var vb = new vertex Buffer<[]Vertex>(device, &verts); 18 | var encoder = new CommandEncoder(device); 19 | var blendState = BlendState{ 20 | color = { srcFactor = BlendFactor.SrcAlpha, dstFactor = BlendFactor.OneMinusSrcAlpha } 21 | }; 22 | var pipeline = new RenderPipeline(device = device, blendState = &blendState); 23 | var fb = swapChain.GetCurrentTexture().CreateColorOutput(LoadOp.Clear); 24 | var redUBO = new uniform Buffer>(device, { 1.0, 0.0, 0.0, 1.0 }); 25 | var redBG = new BindGroup(device, { color = redUBO }); 26 | var translucentBlueUBO = new uniform Buffer>(device, { 0.0, 0.0, 1.0, 0.5 }); 27 | var translucentBlueBG = new BindGroup(device, { color = translucentBlueUBO }); 28 | var vi = new VertexInput(vb); 29 | var drawPass = new RenderPass(encoder, { fragColor = fb, vertices = vi }); 30 | drawPass.SetPipeline(pipeline); 31 | drawPass.Set({ bindings = redBG }); 32 | drawPass.Draw(3, 1, 0, 0); 33 | drawPass.Set({ bindings = translucentBlueBG }); 34 | drawPass.Draw(3, 1, 0, 0); 35 | drawPass.End(); 36 | device.GetQueue().Submit(encoder.Finish()); 37 | swapChain.Present(); 38 | while (System.IsRunning()) System.GetNextEvent(); 39 | -------------------------------------------------------------------------------- /test/error-validate-buffer.t: -------------------------------------------------------------------------------- 1 | var device = new Device(); 2 | new vertex Buffer(device); 3 | new vertex Buffer<[]int>(device); // should succeed 4 | new vertex Buffer<[]byte>(device); 5 | new vertex Buffer<[]ubyte>(device); 6 | new vertex Buffer<[]short>(device); 7 | new vertex Buffer<[]short<2>>(device); 8 | new vertex Buffer<[]ushort>(device); 9 | new vertex Buffer<[]ushort<2>>(device); 10 | new vertex Buffer<[]double>(device); 11 | new vertex Buffer<[]double<2>>(device); 12 | 13 | class C { 14 | var b : byte; 15 | var ub : ubyte; 16 | var s : short; 17 | var us : ushort; 18 | var d : double; 19 | } 20 | 21 | new vertex Buffer<[]C>(device); 22 | 23 | new index Buffer<[]float>(device); 24 | new index Buffer(device); 25 | new index Buffer<[3]float>(device); 26 | 27 | new uniform Buffer(device); 28 | new uniform Buffer>(device); 29 | new uniform Buffer<[3]double>(device); 30 | new uniform Buffer<[]float>(device); 31 | new uniform Buffer<*float>(device); 32 | new uniform Buffer<^float>(device); 33 | new uniform Buffer<&float>(device); 34 | new uniform Buffer(device); 35 | 36 | new storage Buffer(device); 37 | new storage Buffer>(device); 38 | new storage Buffer<[3]double>(device); 39 | new storage Buffer<*float>(device); 40 | new storage Buffer<^float>(device); 41 | new storage Buffer<&float>(device); 42 | new storage Buffer(device); 43 | 44 | new hostreadable vertex Buffer<[]uint>(device); 45 | new hostreadable index Buffer<[]uint>(device); 46 | new hostreadable storage Buffer(device); 47 | new hostreadable uniform Buffer(device); 48 | 49 | new hostwriteable vertex Buffer<[]uint>(device); 50 | new hostwriteable index Buffer<[]uint>(device); 51 | new hostwriteable storage Buffer(device); 52 | new hostwriteable uniform Buffer(device); 53 | 54 | new sampleable renderable readonly writeonly unfilterable Buffer(device); 55 | -------------------------------------------------------------------------------- /parser/BUILD.gn: -------------------------------------------------------------------------------- 1 | # Copyright 2023 The Toucan Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | action("run_bison") { 16 | script = "../tools/run.py" 17 | sources = [ "parser.yy" ] 18 | outputs = [ 19 | "$target_gen_dir/parser.tab.cc", 20 | "$target_gen_dir/parser.tab.hh", 21 | ] 22 | if (is_win) { 23 | args = [ rebase_path("//third_party/winflexbison/win_bison.exe") ] 24 | } else { 25 | args = [ "bison" ] 26 | } 27 | args += [ 28 | "-v", 29 | "-d", 30 | "-b", rebase_path(target_gen_dir, root_build_dir) + "/parser", 31 | ] + rebase_path(sources, root_build_dir) 32 | } 33 | 34 | action("run_flex") { 35 | script = "../tools/run.py" 36 | sources = [ "lexer.ll" ] 37 | outputs = [ "$target_gen_dir/lexer.cc" ] 38 | if (is_win) { 39 | args = [ rebase_path("//third_party/winflexbison/win_flex.exe") ] 40 | } else { 41 | args = [ "flex" ] 42 | } 43 | args += [ 44 | "-o" + rebase_path(target_gen_dir, root_build_dir) + "/lexer.cc", 45 | ] + rebase_path(sources, root_build_dir) 46 | } 47 | 48 | source_set("parser") { 49 | configs += [ "../gn:disable-flex-warnings" ] 50 | sources = [ 51 | "$target_gen_dir/parser.tab.cc", 52 | "$target_gen_dir/lexer.cc", 53 | ] 54 | deps = [ 55 | ":run_bison", 56 | ":run_flex", 57 | ] 58 | include_dirs = [ 59 | "..", 60 | "$target_gen_dir", 61 | ] 62 | } 63 | -------------------------------------------------------------------------------- /ast/constant_folder.h: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Toucan Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef _AST_CONSTANT_FOLDER_H_ 16 | #define _AST_CONSTANT_FOLDER_H_ 17 | 18 | #include "ast.h" 19 | 20 | namespace Toucan { 21 | 22 | class SymbolTable; 23 | 24 | class ConstantFolder : public Visitor { 25 | public: 26 | ConstantFolder(TypeTable* types, void* data); 27 | void Resolve(ASTNode* node); 28 | void Resolve(ASTNode* node, void* data); 29 | template void Store(T value); 30 | template void IntegralBinOp(BinOpNode::Op, void* lhs, void* rhs); 31 | template void FloatingPointBinOp(BinOpNode::Op, void* lhs, void* rhs); 32 | template void StoreUnaryOp(UnaryOp::Op, void* rhs); 33 | Result Visit(CastExpr* node) override; 34 | Result Visit(BinOpNode* node) override; 35 | Result Visit(BoolConstant* node) override; 36 | Result Visit(DoubleConstant* node) override; 37 | Result Visit(ExprList* node) override; 38 | Result Visit(FloatConstant* node) override; 39 | Result Visit(Initializer* node) override; 40 | Result Visit(IntConstant* node) override; 41 | Result Visit(UIntConstant* node) override; 42 | Result Visit(UnaryOp* node) override; 43 | Result Default(ASTNode* node) override; 44 | 45 | private: 46 | TypeTable* types_; 47 | void* data_; 48 | }; 49 | 50 | }; // namespace Toucan 51 | #endif 52 | -------------------------------------------------------------------------------- /test/interactive/compute.t: -------------------------------------------------------------------------------- 1 | using Vertex = float<2>; 2 | 3 | class ComputeBindings { 4 | var vertStorage : *storage Buffer<[]Vertex>; 5 | } 6 | 7 | class BumpCompute { 8 | compute(1, 1, 1) main(cb : &ComputeBuiltins) { 9 | var verts = bindings.Get().vertStorage.Map(); 10 | var pos = cb.globalInvocationId.x; 11 | verts[pos] += float<2>{0.005, 0.0}; 12 | } 13 | var bindings : *BindGroup; 14 | } 15 | 16 | class Pipeline { 17 | vertex main(vb : &VertexBuiltins) { vb.position = {@vert.Get(), 0.0, 1.0}; } 18 | fragment main(fb : &FragmentBuiltins) { fragColor.Set(float<4>(0.0, 1.0, 0.0, 1.0)); } 19 | var fragColor : *ColorOutput; 20 | var vert : *VertexInput; 21 | } 22 | 23 | var device = new Device(); 24 | var window = new Window({640, 480}); 25 | var swapChain = new SwapChain(device, window); 26 | var verts = [3]Vertex{ { 0.0, 1.0 }, {-1.0, -1.0 }, { 1.0, -1.0 } }; 27 | var vb = new vertex storage Buffer<[]Vertex>(device, &verts); 28 | 29 | var pipeline = new RenderPipeline(device); 30 | var computePipeline = new ComputePipeline(device); 31 | var storageBG = new BindGroup(device, { vb }); 32 | 33 | while (System.IsRunning()) { 34 | var encoder = new CommandEncoder(device); 35 | var computePass = new ComputePass(encoder, {bindings = storageBG}); 36 | computePass.SetPipeline(computePipeline); 37 | computePass.Dispatch(verts.length, 1, 1); 38 | computePass.End(); 39 | var fb = swapChain.GetCurrentTexture().CreateColorOutput(LoadOp.Clear); 40 | var vi = new VertexInput(vb); 41 | var renderPass = new RenderPass(encoder, {vert = vi, fragColor = fb}); 42 | renderPass.SetPipeline(pipeline); 43 | renderPass.Draw(3, 1, 0, 0); 44 | renderPass.End(); 45 | device.GetQueue().Submit(encoder.Finish()); 46 | swapChain.Present(); 47 | 48 | while (System.HasPendingEvents()) System.GetNextEvent(); 49 | } 50 | -------------------------------------------------------------------------------- /ast/api_validator.h: -------------------------------------------------------------------------------- 1 | // Copyright 2025 The Toucan Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef _AST_API_VALIDATION_PASS_H_ 16 | #define _AST_API_VALIDATION_PASS_H_ 17 | 18 | #include "file_location.h" 19 | #include "type.h" 20 | 21 | namespace Toucan { 22 | 23 | class SymbolTable; 24 | 25 | class APIValidator { 26 | public: 27 | APIValidator(); 28 | void ValidateType(Type* type, const FileLocation& fileLocation); 29 | int GetNumErrors() const { return numErrors_; } 30 | 31 | private: 32 | void ValidateVertexAttributeType(ClassType* buffer, Type* type); 33 | void ValidateVertexBufferType(ClassType* buffer, Type* type); 34 | void ValidateIndexBufferType(ClassType* buffer, Type* type); 35 | void ValidateUniformDataType(ClassType* buffer, Type* type); 36 | void ValidateStorageDataType(ClassType* buffer, Type* type); 37 | void ValidateBuffer(ClassType* classType, int qualifiers); 38 | void ValidateBindGroup(ClassType* classType); 39 | void ValidateRenderPipelineFields(ClassType* renderPipeline); 40 | void ValidateComputePipelineFields(ClassType* computePipeline); 41 | void ValidateRenderPipeline(ClassType* renderPipeline); 42 | void ValidateComputePipeline(ClassType* renderPipeline); 43 | void Error(ClassType* instance, const char* fmt, ...); 44 | 45 | private: 46 | int numErrors_ = 0; 47 | FileLocation fileLocation_; 48 | }; 49 | 50 | }; // namespace Toucan 51 | #endif 52 | -------------------------------------------------------------------------------- /test/interactive/bind-group.t: -------------------------------------------------------------------------------- 1 | using Vertex = float<2>; 2 | 3 | class Uniforms { 4 | var color : float<4>; 5 | } 6 | 7 | class ObjectData { 8 | var uniforms : *uniform Buffer; 9 | } 10 | 11 | class Pipeline { 12 | vertex main(vb : &VertexBuiltins) { vb.position = {@vertices.Get(), 0.0, 1.0}; } 13 | fragment main(fb : &FragmentBuiltins) { 14 | fragColor.Set(objectData.Get().uniforms.MapRead().color); 15 | } 16 | var vertices : *VertexInput; 17 | var fragColor : *ColorOutput; 18 | var objectData : *BindGroup; 19 | } 20 | var device = new Device(); 21 | var window = new Window({640, 480}); 22 | var swapChain = new SwapChain(device, window); 23 | var verts = [3]Vertex{ { 0.0, 1.0 }, {-1.0, -1.0 }, { 1.0, -1.0 } }; 24 | var vb = new vertex Buffer<[]Vertex>(device, &verts); 25 | var objectData = ObjectData{ new uniform Buffer(device) }; 26 | var bg = new BindGroup(device, &objectData); 27 | var stagingBuffer = new hostwriteable Buffer(device); 28 | var pipeline = new RenderPipeline(device); 29 | while (System.IsRunning()) { 30 | var encoder = new CommandEncoder(device); 31 | objectData.uniforms.CopyFromBuffer(encoder, stagingBuffer); 32 | var p = Pipeline{ 33 | vertices = new VertexInput(vb), 34 | fragColor = swapChain.GetCurrentTexture().CreateColorOutput(LoadOp.Clear), 35 | objectData = bg 36 | }; 37 | var renderPass = new RenderPass(encoder, &p); 38 | renderPass.SetPipeline(pipeline); 39 | renderPass.Draw(3, 1, 0, 0); 40 | renderPass.End(); 41 | device.GetQueue().Submit(encoder.Finish()); 42 | swapChain.Present(); 43 | while (System.HasPendingEvents()) { 44 | var event = System.GetNextEvent(); 45 | if (event.type == EventType.MouseMove) { 46 | var s = stagingBuffer.MapWrite(); 47 | s.color = float<4>((float) event.position.x / 640.0, (float) event.position.y / 480.0, 0.0, 1.0); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ast/native_class.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2023 The Toucan Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "native_class.h" 16 | 17 | #include "type.h" 18 | 19 | namespace Toucan { 20 | 21 | ClassType* NativeClass::BindGroup; 22 | ClassType* NativeClass::Buffer; 23 | ClassType* NativeClass::ColorOutput; 24 | ClassType* NativeClass::CommandBuffer; 25 | ClassType* NativeClass::CommandEncoder; 26 | ClassType* NativeClass::ComputePass; 27 | ClassType* NativeClass::ComputePipeline; 28 | ClassType* NativeClass::DepthStencilOutput; 29 | ClassType* NativeClass::Device; 30 | ClassType* NativeClass::Event; 31 | ClassType* NativeClass::Image; 32 | ClassType* NativeClass::Math; 33 | ClassType* NativeClass::Queue; 34 | ClassType* NativeClass::RenderPass; 35 | ClassType* NativeClass::RenderPipeline; 36 | ClassType* NativeClass::SampleableTexture1D; 37 | ClassType* NativeClass::SampleableTexture2D; 38 | ClassType* NativeClass::SampleableTexture2DArray; 39 | ClassType* NativeClass::SampleableTexture3D; 40 | ClassType* NativeClass::SampleableTextureCube; 41 | ClassType* NativeClass::Sampler; 42 | ClassType* NativeClass::SwapChain; 43 | ClassType* NativeClass::System; 44 | ClassType* NativeClass::Texture1D; 45 | ClassType* NativeClass::Texture2D; 46 | ClassType* NativeClass::Texture2DArray; 47 | ClassType* NativeClass::Texture3D; 48 | ClassType* NativeClass::TextureCube; 49 | ClassType* NativeClass::VertexInput; 50 | ClassType* NativeClass::Window; 51 | 52 | } // namespace Toucan 53 | -------------------------------------------------------------------------------- /ast/type_replacement_pass.h: -------------------------------------------------------------------------------- 1 | // Copyright 2023 The Toucan Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef _AST_TYPE_REPLACEMENT_PASS_H_ 16 | #define _AST_TYPE_REPLACEMENT_PASS_H_ 17 | 18 | #include 19 | 20 | #include "copy_visitor.h" 21 | 22 | namespace Toucan { 23 | 24 | class SymbolTable; 25 | 26 | class TypeReplacementPass : public CopyVisitor { 27 | public: 28 | TypeReplacementPass(NodeVector* nodes, 29 | SymbolTable* symbols, 30 | TypeTable* types, 31 | const TypeList& srcTypes, 32 | const TypeList& dstTypes, 33 | std::queue* instanceQueue); 34 | Result Error(const char* fmt, ...); 35 | Type* ResolveType(Type* type) override; 36 | TypeList* ResolveTypes(TypeList* typeList); 37 | Method* ResolveMethod(Method* method); 38 | void ResolveClassInstance(ClassTemplate* classTemplate, ClassType* instance); 39 | Result Visit(Stmts* stmts) override; 40 | Result Default(ASTNode* node) override; 41 | int NumErrors() const { return numErrors_; } 42 | 43 | private: 44 | Type* PushQualifiers(Type* type, int qualifiers); 45 | SymbolTable* symbols_; 46 | TypeTable* types_; 47 | TypeList srcTypes_; 48 | TypeList dstTypes_; 49 | std::queue* instanceQueue_; 50 | int numErrors_ = 0; 51 | }; 52 | 53 | }; // namespace Toucan 54 | #endif 55 | -------------------------------------------------------------------------------- /ast/native_class.h: -------------------------------------------------------------------------------- 1 | // Copyright 2023 The Toucan Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef NATIVE_CLASS_H_ 16 | #define NATIVE_CLASS_H_ 17 | 18 | // TODO: autogenerate this from api.t. 19 | 20 | namespace Toucan { 21 | 22 | class ClassType; 23 | 24 | class NativeClass { 25 | public: 26 | static ClassType* BindGroup; 27 | static ClassType* Buffer; 28 | static ClassType* ColorOutput; 29 | static ClassType* CommandBuffer; 30 | static ClassType* CommandEncoder; 31 | static ClassType* ComputePass; 32 | static ClassType* ComputePipeline; 33 | static ClassType* DepthStencilOutput; 34 | static ClassType* Device; 35 | static ClassType* Event; 36 | static ClassType* Image; 37 | static ClassType* Math; 38 | static ClassType* Queue; 39 | static ClassType* RenderPass; 40 | static ClassType* RenderPipeline; 41 | static ClassType* SampleableTexture1D; 42 | static ClassType* SampleableTexture2D; 43 | static ClassType* SampleableTexture2DArray; 44 | static ClassType* SampleableTexture3D; 45 | static ClassType* SampleableTextureCube; 46 | static ClassType* Sampler; 47 | static ClassType* SwapChain; 48 | static ClassType* System; 49 | static ClassType* Texture1D; 50 | static ClassType* Texture2D; 51 | static ClassType* Texture2DArray; 52 | static ClassType* Texture3D; 53 | static ClassType* TextureCube; 54 | static ClassType* VertexInput; 55 | static ClassType* Window; 56 | }; 57 | 58 | }; // namespace Toucan 59 | #endif 60 | -------------------------------------------------------------------------------- /bench/array_float_unrolled.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2023 The Toucan Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | #define SIZE 1024 18 | #define COUNT 1000000 19 | 20 | #ifdef _WIN32 21 | #include 22 | double get_time_usec() { 23 | FILETIME ft; 24 | GetSystemTimeAsFileTime(&ft); 25 | LARGE_INTEGER v; 26 | v.LowPart = ft.dwLowDateTime; 27 | v.HighPart = ft.dwHighDateTime; 28 | return static_cast(v.QuadPart) / 10.0; 29 | } 30 | #else 31 | #include 32 | double get_time_usec() { 33 | struct timeval t; 34 | gettimeofday(&t, nullptr); 35 | return 1000000.0 * t.tv_sec + t.tv_usec; 36 | } 37 | #endif 38 | 39 | int main() { 40 | float a[SIZE]; 41 | double start = get_time_usec(); 42 | for (int i = 0; i < SIZE; i += 1) { 43 | a[i] = 2000000.0f; 44 | } 45 | for (int j = 0; j < COUNT; j += 1) { 46 | for (int i = 0; i < SIZE; i += 9) { 47 | a[i] = a[i] * 1.00001f + 1.0f; 48 | a[i + 1] = a[i + 1] * 1.00001f + 1.0f; 49 | a[i + 2] = a[i + 2] * 1.00001f + 1.0f; 50 | a[i + 3] = a[i + 3] * 1.00001f + 1.0f; 51 | a[i + 4] = a[i + 4] * 1.00001f + 1.0f; 52 | a[i + 5] = a[i + 5] * 1.00001f + 1.0f; 53 | a[i + 6] = a[i + 6] * 1.00001f + 1.0f; 54 | a[i + 7] = a[i + 7] * 1.00001f + 1.0f; 55 | a[i + 8] = a[i + 8] * 1.00001f + 1.0f; 56 | } 57 | } 58 | double end = get_time_usec(); 59 | printf("result is %f\n", a[3]); 60 | printf("elapsed time %f usec, %f per iteration\n", (end - start), (end - start) / (SIZE * COUNT)); 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /bench/array_vec4f.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Toucan Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | 18 | #define SIZE 1024000 19 | #define OUTER_COUNT 1000 20 | 21 | #ifdef _WIN32 22 | #include 23 | double get_time_usec() { 24 | FILETIME ft; 25 | GetSystemTimeAsFileTime(&ft); 26 | LARGE_INTEGER v; 27 | v.LowPart = ft.dwLowDateTime; 28 | v.HighPart = ft.dwHighDateTime; 29 | return static_cast(v.QuadPart) / 10.0; 30 | } 31 | #else 32 | #include 33 | double get_time_usec() { 34 | struct timeval t; 35 | gettimeofday(&t, nullptr); 36 | return 1000000.0 * t.tv_sec + t.tv_usec; 37 | } 38 | #endif 39 | 40 | int main() { 41 | float a[SIZE] __attribute__((aligned(16))); 42 | float mulconst[4] __attribute__((aligned(16))) = {1.00001f, 1.00001f, 1.00001f, 1.00001f}; 43 | float addconst[4] __attribute__((aligned(16))) = {1.0f, 1.0f, 1.0f, 1.0f}; 44 | double start = get_time_usec(); 45 | for (int i = 0; i < SIZE; ++i) { 46 | a[i] = 2000000.0f; 47 | } 48 | __m128 mm_mulconst = _mm_load_ps(mulconst); 49 | __m128 mm_addconst = _mm_load_ps(addconst); 50 | for (int j = 0; j < OUTER_COUNT; ++j) { 51 | for (int i = 0; i < SIZE; i += 4) { 52 | __m128 v = _mm_load_ps(&a[i]); 53 | v = _mm_mul_ps(v, mm_mulconst); 54 | v = _mm_add_ps(v, mm_addconst); 55 | _mm_store_ps(&a[i], v); 56 | } 57 | } 58 | double end = get_time_usec(); 59 | printf("result is %f\n", a[3]); 60 | printf("elapsed time %f usec\n", end - start); 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /ast/symbol.h: -------------------------------------------------------------------------------- 1 | // Copyright 2023 The Toucan Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef _AST_SYMBOL_H_ 16 | #define _AST_SYMBOL_H_ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #ifndef _AST_TYPE_H 23 | #include "type.h" 24 | #endif 25 | 26 | namespace Toucan { 27 | 28 | typedef std::unordered_map VarMap; 29 | typedef std::unordered_map TypeMap; 30 | 31 | struct Scope { 32 | Scope(Scope* p) : parent(p) {} 33 | Scope* parent; 34 | ClassType* classType = nullptr; 35 | EnumType* enumType = nullptr; 36 | Method* method = nullptr; 37 | VarVector vars; 38 | VarMap varMap; 39 | TypeMap types; 40 | }; 41 | 42 | class SymbolTable { 43 | public: 44 | SymbolTable(); 45 | Var* FindVar(const std::string& identifier) const; 46 | Type* FindType(const std::string& identifier) const; 47 | Field* FindField(const std::string& identifier) const; 48 | Var* FindVarInScope(const std::string& identifier) const; 49 | Var* DefineVar(std::string identifier, Type* type); 50 | bool DefineType(std::string identifier, Type* type); 51 | Scope* PushNewScope(); 52 | void PushScope(Scope* scope); 53 | Scope* PopScope(); 54 | Scope* PeekScope(); 55 | void Dump(); 56 | 57 | private: 58 | Scope* currentScope_; 59 | std::vector> scopes_; 60 | }; 61 | 62 | }; // namespace Toucan 63 | 64 | #endif 65 | --------------------------------------------------------------------------------