c600a621b39b — Leonard Ritter a month ago
* rewrote lowering
3 files changed, 252 insertions(+), 238 deletions(-)

M lib/tukan/CADAG/init.sc
M lib/tukan/FIR.sc
M testing/tukdag.sc
M lib/tukan/CADAG/init.sc +10 -4
@@ 907,6 907,8 @@ type+ CADAG
         'insert seen 0:u32
         if (on-enter (view self) root)
             'push stack self root
+        else
+            return;
         loop ()
             let md = ('peek stack)
             let ofs = ('enum-id-offset ((copy md.typeid) as cls.TypeId) (copy md.refindex))

          
@@ 969,8 971,10 @@ type+ CADAG
         let cls = (typeof self)
         let oldcls = (typeof oldmodule)
         if (root == oldcls.NoId)
-            return root
-        local aliases : (Map u32 cls.AnyId)
+            return (copy root)
+        let aliases =
+            va-option aliases ...
+                local aliases : (Map u32 cls.AnyId)
         let on-enter =
             va-option on-enter ...
                 inline (self oldmodule id)

          
@@ 1173,12 1177,14 @@ type+ CADAG
                 sc_write "\n"
             'append stack (tupleof (subscope @ subidx) 0:u32)
             ;
-    case (self)
-        let ordered indices = ('ordered self ('rootid self))
+    case (self, rootid : Id)
+        let ordered indices = ('ordered self rootid)
         let pred = ('predecessors self ordered indices)
         let postdom = (postdominators ordered pred)
         let scope = (scopetree ordered postdom)
         this-function self ordered scope
+    case (self)
+        this-function self ('rootid self)
 
     inline... store (self, typeid : TypeId, ...)
         (store-func typeid) self ...

          
M lib/tukan/FIR.sc +236 -227
@@ 196,6 196,8 @@ define-type "selectfragment" (RIFF "SLFR
     stringcolor...
 define-type "clear" (RIFF "CLRI") (tuple (range = AnyId) (value = AnyId))
     stringcolor...
+define-type "sample" (RIFF "SAMP") (tuple (source = AnyId) (uv = AnyId))
+    stringcolor...
 
 # FIR Level 1
 ################################################################################

          
@@ 289,12 291,12 @@ define-type "draw"          (RIFF "DRAI"
         sources : AnyId
         sinks : AnyId
     mutinstrcolor...
+define-type "sampleimagelod" (RIFF "SILD") (tuple (source = AnyId) (uv = AnyId) (lod = AnyId))
+    instrcolor...
 
 # FIR Level 0
 ################################################################################
 
-define-type "sample"    (RIFF "SAMP") (tuple (source = AnyId) (uv = AnyId))
-    instrcolor...
 define-type "fvec"      (RIFF "FVEC") (tuple (count = u32))
     typecolor...
 define-type "uvec"      (RIFF "UVEC") (tuple (count = u32))

          
@@ 499,6 501,9 @@ struct StageInfo
             \ " stage-import=" (repr self.stage-import)
             \ ")"
 
+    fn imports (self)
+        imply self.stage-import AnyIdArray
+
     fn combine (self other module)
         let sample-index = (max self.sample-index other.sample-index)
         let generator =

          
@@ 545,7 550,7 @@ struct FIRTyper
 
     fn stage-value (ctx module id)
         from (methodsof module.builder) let uvec fvec
-        report "staging" ('repr module id)
+        #report "staging" ('repr module id)
         inline get (id)
             try ('get ctx.stages id)
             else

          
@@ 565,13 570,26 @@ struct FIRTyper
                 sample-index = sample-index
                 generator = id
                 stage-import = (copy ctx.rootstage.stage-import)
-        case sample (self)
+        case sampleimagelod (self)
+            let si = ('combine (get self.uv) (get self.lod) module)
+            let source = (get self.source)
+            local new-import : (Array AnyId)
+            'append new-import self.source
+            StageInfo
+                sample-index = (max si.sample-index source.sample-index)
+                generator = si.generator
+                stage-import =
+                    merge-arrays si.stage-import (Rc.wrap (deref new-import))
+        #case sample (self)
             let uv = (get self.uv)
             let source = (get self.source)
+            local new-import : (Array AnyId)
+            'append new-import self.source
             StageInfo
                 sample-index = (max uv.sample-index source.sample-index)
                 generator = uv.generator
-                stage-import = (copy uv.stage-import)
+                stage-import =
+                    merge-arrays uv.stage-import (Rc.wrap (deref new-import))
         default
             switch ('typeidof module id)
             pass TypeId.typeid_uconst

          
@@ 630,7 648,7 @@ struct FIRTyper
                 deref si
             default
                 error "failed to deduce stage"
-        report "staged to" stage
+        #report "staged to" stage
         'set ctx.stages id stage
         ;
 

          
@@ 642,7 660,13 @@ struct FIRTyper
         'descend module id
             on-enter =
                 capture (module id) {&ctx}
-                    not ('in? ctx.stages id)
+                    if ('in? ctx.stages id)
+                        return false
+                    switch (('handleof module id) . typeid)
+                    case TypeId.typeid_dispatch
+                        'set ctx.stages id (copy ctx.rootstage)
+                        return false
+                    default true
             on-leave =
                 capture on-leave (module id) {&ctx}
                     try

          
@@ 673,7 697,7 @@ struct FIRTyper
 
     fn type-value (ctx module id)
         from (methodsof module.builder) let uvec fvec
-        report "typing" ('repr module id)
+        #report "typing" ('repr module id)
         inline get (id)
             try (copy ('get ctx.types id))
             else

          
@@ 694,8 718,17 @@ struct FIRTyper
             get self.pointer
         case sample (self)
             get self.source
+        case sampleimagelod (self)
+            let typeid count = ('vectordesc ctx module (get self.source))
+            switch typeid
+            case TypeId.typeid_fvec (fvec 4)
+            case TypeId.typeid_uvec (uvec 4)
+            default
+                error "can't deduce element type"
         case clearimage (self)
             get self.target
+        case selectfragment (self)
+            get self.default
         case dispatch (self)
             let sinkhandle = ('handleof module self.sinks)
             let vacount = ('vacount sinkhandle)

          
@@ 716,12 749,15 @@ struct FIRTyper
                 trap;
         default
             switch ('typeidof module id)
-            #case TypeId.typeid_range (uvec 3)
-            case TypeId.typeid_globalid (uvec 3)
-
+            pass TypeId.typeid_range
+            pass TypeId.typeid_globalid
+            do (uvec 3)
+            pass TypeId.typeid_primitive
+            do (uvec 2)
             pass TypeId.typeid_fconst
             pass TypeId.typeid_utof
             pass TypeId.typeid_fadd
+            pass TypeId.typeid_fsub
             pass TypeId.typeid_fmul
             pass TypeId.typeid_fdiv
             pass TypeId.typeid_sin

          
@@ 733,6 769,8 @@ struct FIRTyper
             pass TypeId.typeid_mul
             pass TypeId.typeid_udiv
             pass TypeId.typeid_sdiv
+            pass TypeId.typeid_urem
+            pass TypeId.typeid_srem
             pass TypeId.typeid_and
             pass TypeId.typeid_or
             pass TypeId.typeid_xor

          
@@ 743,6 781,7 @@ struct FIRTyper
             pass TypeId.typeid_imagewrite
             pass TypeId.typeid_computefn
             pass TypeId.typeid_bindings
+            pass TypeId.typeid_overlay
             do NoId
 
             case TypeId.typeid_uvec2 (uvec 2)

          
@@ 772,6 811,7 @@ struct FIRTyper
                 else NoId
 
             # type of first value
+            pass TypeId.typeid_fragment
             pass TypeId.typeid_comp
             do
                 for srcid in ('sources handle)

          
@@ 780,10 820,45 @@ struct FIRTyper
                 else NoId
             default
                 error "failed to deduce type"
-        report "typed to" type
+        #report "typed to" type
         'set ctx.types id type
         ;
 
+    fn vectordesc-imagetype (imagetype)
+        let format = imagetype.format
+        let count = ('components format)
+        let typeid =
+            switch ('format format)
+            pass ImageFormat.U
+            pass ImageFormat.S
+            do TypeId.typeid_uvec
+            pass ImageFormat.F
+            pass ImageFormat.UNORM
+            pass ImageFormat.SNORM
+            do TypeId.typeid_fvec
+            default
+                trap;
+        return typeid count
+
+    fn vectordesc (ctx module tid)
+        let handle = ('handleof module tid)
+        dispatch handle
+        case fvec (self)
+            return TypeId.typeid_fvec (copy self.count)
+        case uvec (self)
+            return TypeId.typeid_uvec (copy self.count)
+        case imagestorage (self)
+            return (this-function ctx module (copy self.type))
+        case image (self)
+            return (vectordesc-imagetype self)
+        case sampler (self)
+            return (vectordesc-imagetype self)
+        default
+            return handle.typeid 0:u32
+
+    fn element-typeof (ctx module source)
+        return (vectordesc ctx module ('typeof ctx module source))
+
     fn... typeof (ctx, module : FIR, id : AnyId)
         try
             return (copy ('get ctx.types id))

          
@@ 1620,10 1695,10 @@ fn generate-IL (module)
             `glob
         case imagewrite (self)
             `(Image-write [(get self.target)] [(get self.offset)] [(get self.element)])
-        case sample (self)
+        case sampleimagelod (self)
             spice-quote
                 sample [(get self.source)] [(get self.uv)]
-                    Lod = 0.0
+                    Lod = [(get self.lod)]
         #case Op.WRITE
             # IMAGEWRITE attr index value : imagetype
             let a1 a2 a3 = (translate a1 a2 a3)

          
@@ 1992,62 2067,86 @@ fn lower-FIR (module rootid)
         error
             .. "cannot derive capacity from " ('repr module id)
 
-    struct GPUJob
+    struct Context
+        typer : FIRTyper
+
+    local ctx : Context
+
+    struct RangeMetrics plain
         dim : u32
-        originalsize : (tuple AnyId AnyId AnyId)
         size : (tuple AnyId AnyId AnyId)
         localsize : uvec3
         capacity : uvec3
-        uniforms : (Map AnyId AnyId)
-        next_uniform_id = 0:u32
 
-        fn __copy (self)
-            this-type
-                dim = self.dim
-                originalsize = self.originalsize
-                size = self.size
-                localsize = self.localsize
-                capacity = self.capacity
-                next_uniform_id = self.next_uniform_id
-                uniforms = (copy self.uniforms)
-
-    struct Context
-        gpujobs : (Array GPUJob)
-        gpujobmap : (Map AnyId u32)
-        typer : FIRTyper
+        fn build-dispatchsize (self module)
+            from (methodsof module.builder) let add udiv uconst uvec
+            let lx ly lz = (unpack self.localsize)
+            let dx dy dz = (unpack self.size)
+            let x =
+                udiv (add dx (uconst (lx - 1))) (uconst lx)
+            let y =
+                if (ly == 1) (uconst 1)
+                else
+                    udiv (add dy (uconst (lx - 1))) (uconst ly)
+            let z =
+                if (lz == 1) (uconst 1)
+                else
+                    udiv (add dz (uconst (lx - 1))) (uconst lz)
+            _ x y z
 
-        fn getuniform (ctx gpujob module id)
-            try (copy ('get gpujob.uniforms id))
-            else
-                let ty = ('typeof ctx.typer module id)
-                let ty =
-                    dispatch ('handleof module ty)
-                    case imagestorage (self)
-                        dispatch ('handleof module self.type)
-                        case image (self)
-                            let sampler = ('alloc module TypeId.typeid_sampler)
-                            @sampler = self
-                            'commit module
-                        default (copy self.type)
-                    default ty
-                from (methodsof module.builder) let uniform
-                let uniid = (uniform ty gpujob.next_uniform_id)
-                gpujob.next_uniform_id += 1
-                'set gpujob.uniforms id uniid
-                uniid
-    local ctx : Context
+    fn range-metrics (module id)
+        let handle = ('handleof module id)
+        let vacount = ('vacount handle)
+        dispatch handle
+        case range (self)
+            let dim = vacount
+            if ((dim < 1) | (dim > 3))
+                error "range must have 1 to 3 arguments"
+            let lx ly lz =
+                switch dim
+                case 1 (_ 64:u32 1:u32 1:u32)
+                case 2 (_ 8:u32 8:u32 1:u32)
+                case 3 (_ 4:u32 4:u32 4:u32)
+                default
+                    trap;
+            let dims = self.dims
+            let dx cx =
+                (copy (dims @ 0))
+                max lx (get-capacity module (copy (dims @ 0)))
+            let dy cy =
+                if (ly == 1) (_ NoId 1:u32)
+                else
+                    _ (copy (dims @ 1))
+                        max ly (get-capacity module (copy (dims @ 1)))
+            let dz cz =
+                if (lz == 1) (_ NoId 1:u32)
+                else
+                    _ (copy (dims @ 2))
+                        max lz (get-capacity module (copy (dims @ 2)))
+            RangeMetrics
+                dim = dim
+                size = (tupleof dx dy dz)
+                localsize = (uvec3 lx ly lz)
+                capacity = (uvec3 cx cy cz)
+        default
+            error "range expected"
 
     fn remapvector (ctx module source numcomp)
-        dispatch ('handleof module ('typeof ctx.typer module source))
-        case fvec (self)
-            let sourcecomp = (copy self.count)
-            if (sourcecomp == numcomp)
-                source
-            else
+        let typeid sourcecomp = ('element-typeof ctx.typer module source)
+        #report "remapping" ('repr module source) "from" sourcecomp "to" numcomp
+        from (methodsof module.builder) let comp
+        inline getter (const)
+            inline get (i)
+                if (i >= sourcecomp) (const 0)
+                elseif (sourcecomp == 1) source
+                else (comp i source)
+        if (sourcecomp == numcomp)
+            source
+        else
+            switch typeid
+            case TypeId.typeid_fvec
                 from (methodsof module.builder) let fvec2 fvec3 fvec4 fconst comp
-                inline get (i)
-                    if (i >= sourcecomp) (fconst 0)
-                    else (comp i source)
+                let get = (getter fconst)
                 switch numcomp
                 case 1 (get 0)
                 case 2 (fvec2 (get 0) (get 1))

          
@@ 2055,15 2154,9 @@ fn lower-FIR (module rootid)
                 case 4 (fvec4 (get 0) (get 1) (get 2) (get 3))
                 default
                     trap;
-        case uvec (self)
-            let sourcecomp = (copy self.count)
-            if (sourcecomp == numcomp)
-                source
-            else
+            case TypeId.typeid_uvec
                 from (methodsof module.builder) let uvec2 uvec3 uvec4 uconst comp
-                inline get (i)
-                    if (i >= sourcecomp) (uconst 0)
-                    else (comp i source)
+                let get = (getter uconst)
                 switch numcomp
                 case 1 (get 0)
                 case 2 (uvec2 (get 0) (get 1))

          
@@ 2071,10 2164,12 @@ fn lower-FIR (module rootid)
                 case 4 (uvec4 (get 0) (get 1) (get 2) (get 3))
                 default
                     trap;
-        default
-            error "source must be float or integer"
+            default
+                error
+                    .. "source must be float or integer, but has type "
+                        'repr module ('typeof ctx.typer module source)
 
-    fn genimagestorage (ctx module source_idx source)
+    fn genimagestorage (ctx module rangeid source)
         let tid = ('typeof ctx.typer module source)
         let imgformat =
             dispatch ('handleof module tid)

          
@@ 2084,37 2179,70 @@ fn lower-FIR (module rootid)
                 'setcomponents ImageFormat.R32U self.count
             default
                 error "source must be float or integer"
-        let gpujob = (ctx.gpujobs @ source_idx)
         from (methodsof module.builder) let image imagestorage
-        let cx cy cz = (unpack gpujob.capacity)
+        let met = (range-metrics module rangeid)
+        let cx cy cz = (unpack met.capacity)
         let imgtype = (image ImageDim.2D imgformat ImageFlags.none)
-        _ (imagestorage imgtype cx cy cz 1 0) imgtype imgformat
+        _ (imagestorage imgtype cx cy cz 1 0) imgtype imgformat met
 
     fn gendispatch (ctx module source)
-        let source_idx =
-            try (copy ('get ctx.gpujobmap source))
-            else
-                error "source must be range"
-        let storagetype imgtype imgformat =
-            genimagestorage ctx module source_idx source
-        let gpujob = (ctx.gpujobs @ source_idx)
-        from (methodsof module.builder) let dispatch computefn
-            \ bindings wimage imagewrite load undef uvec2 globalid comp
-            \ unpack-comp
-        let sx sy sz = (unpack gpujob.size)
-        let lx ly lz = (unpack gpujob.localsize)
-        let img = (wimage imgtype 0)
-        let numsources = (countof gpujob.uniforms)
+        dispatch ('handleof module ('typeof ctx.typer module source))
+        case imagestorage (imgstor)
+            dispatch ('handleof module imgstor.type)
+            case image (img)
+                return (copy source) (copy img.format)
+            default
+                error "image type expected"
+        default;
+
+        let stage = ('stageof ctx.typer module source)
+        let rangeid = stage.generator
+        let storagetype imgtype imgformat met =
+            genimagestorage ctx module rangeid source
+        let sx sy sz = ('build-dispatchsize met module)
+        let lx ly lz = (unpack met.localsize)
+        let imports = ('imports stage)
+        let numsources = (countof imports)
+        local importmap : (Map u32 AnyId)
+        local uniforms : (Array AnyId)
+        from (methodsof module.builder) let globalid
+        'set importmap rangeid (globalid)
+        # make uniforms
+        for i srcid in (enumerate imports u32)
+            let ty = ('typeof ctx.typer module (copy srcid))
+            let ty =
+                dispatch ('handleof module ty)
+                case imagestorage (self)
+                    dispatch ('handleof module self.type)
+                    case image (self)
+                        let sampler = ('alloc module TypeId.typeid_sampler)
+                        @sampler = self
+                        'commit module
+                    default (copy self.type)
+                default ty
+            from (methodsof module.builder) let uniform load
+            let uniid = (uniform ty i)
+            'set importmap srcid
+                load uniid
+            'append uniforms uniid
+        # replace values with uniforms
+        let source =
+            'translate module module source
+                aliases = (view importmap)
         let sources =
             'alloc module TypeId.typeid_bindings numsources
         local ofs = 0
         let entries = sources.entries
-        for k v in gpujob.uniforms
+        for k v in (zip imports uniforms)
             entries @ ofs =
                 tupleof k v
             ofs += 1
         let sources = ('commit module)
         let writevalue = (remapvector ctx module (copy source) 4:u32)
+        from (methodsof module.builder) let dispatch computefn
+            \ bindings wimage imagewrite load undef uvec2 comp
+            \ unpack-comp
+        let img = (wimage imgtype 0)
         let pos = (globalid)
         let uv = (uvec2 (unpack-comp pos 2))
         let source =

          
@@ 2128,164 2256,45 @@ fn lower-FIR (module rootid)
         _ source imgformat
 
     fn translate-value (ctx module handle oldmodule id)
-        vvv bind merge-gpujobs
-        inline "#hidden" (self)
-            let idx =
-                fold (idx = -1:u32) for id in ('sources handle)
-                    let argidx = ('getdefault ctx.gpujobmap id -1:u32)
-                    if (argidx != idx)
-                        if (argidx == -1:u32) idx
-                        elseif (idx != -1:u32)
-                            error "illegal mixing of ranges"
-                        else argidx
-                    else idx
-            if (idx != -1:u32)
-                let gpujob = (ctx.gpujobs @ idx)
-                # generate uniforms where required
-                for id in ('sources handle)
-                    let argidx = ('getdefault ctx.gpujobmap id -1:u32)
-                    if (argidx == -1:u32)
-                        from (methodsof module.builder) let load
-                        dispatch ('handleof module id)
-                        case fconst ()
-                        case uconst ()
-                        default
-                            let uniid =
-                                load
-                                    'getuniform ctx gpujob module id
-                            id = uniid
-            let id = ('commit module handle)
-            if (idx != -1:u32)
-                'set ctx.gpujobmap id idx
-            id
-
         let vacount = ('vacount handle)
-        vvv bind newid
         dispatch handle
-        case range (self)
-            let dim = vacount
-            if ((dim < 1) | (dim > 3))
-                error "range must have 1 to 3 arguments"
-            let lx ly lz =
-                switch dim
-                case 1 (_ 64:u32 1:u32 1:u32)
-                case 2 (_ 8:u32 8:u32 1:u32)
-                case 3 (_ 4:u32 4:u32 4:u32)
-                default
-                    trap;
-            from (methodsof module.builder) let add udiv globalid uconst uvec
-            let dims = self.dims
-            let ox x cx =
-                copy (dims @ 0)
-                udiv (add (dims @ 0) (uconst (lx - 1))) (uconst lx)
-                max lx (get-capacity module (copy (dims @ 0)))
-            let oy y cy =
-                if (ly == 1)
-                    _ (uconst 1) (uconst 1) 1:u32
-                else
-                    _
-                        copy (dims @ 1)
-                        udiv (add (dims @ 1) (uconst (lx - 1))) (uconst ly)
-                        max ly (get-capacity module (copy (dims @ 1)))
-            let oz z cz =
-                if (lz == 1)
-                    _ (uconst 1) (uconst 1) 1:u32
-                else
-                    _
-                        copy (dims @ 2)
-                        udiv (add (dims @ 2) (uconst (lx - 1))) (uconst lz)
-                        max lz (get-capacity module (copy (dims @ 2)))
-            let newid = (globalid)
-            'set ctx.gpujobmap newid ((countof ctx.gpujobs) as u32)
-            'append ctx.gpujobs
-                GPUJob
-                    dim = dim
-                    originalsize = (tupleof ox oy oz)
-                    size = (tupleof x y z)
-                    localsize = (uvec3 lx ly lz)
-                    capacity = (uvec3 cx cy cz)
-            newid
         case clear (self)
-            let idx =
-                try (copy ('get ctx.gpujobmap self.range))
-                else
-                    error "coordinate must source range"
-            let gpujob = (ctx.gpujobs @ idx)
-            let storagetype imgtype imgformat =
-                genimagestorage ctx module idx self.value
+            let stage = ('stageof ctx.typer module self.range)
+            let rangeid = (copy stage.generator)
+            let storagetype imgtype imgformat met =
+                genimagestorage ctx module rangeid self.value
             from (methodsof module.builder) let clearimage uconst undef
-            let ox oy oz = (unpack gpujob.originalsize)
+            let ox oy oz = (unpack met.size)
             let z = (uconst 0)
             let value = (remapvector ctx module
                 (copy self.value) ('components imgformat))
             clearimage value
                 z
                 \ z z z
-                \ ox oy oz
+                ox
+                if (oy == NoId) (uconst 1)
+                else oy
+                if (oz == NoId) (uconst 1)
+                else oz
                 undef storagetype
-
         case sample (self)
-            let uv_idx =
-                try (copy ('get ctx.gpujobmap self.uv))
-                else
-                    error "coordinate must source range"
             let source imgformat =
                 gendispatch ctx module self.source
-            let gpujob = (ctx.gpujobs @ uv_idx)
-            from (methodsof module.builder) let load uvec2 uvec3 fvec2 fvec3
-                \ comp
-            let uniid =
-                load
-                    'getuniform ctx gpujob module source
-            self.source = uniid
-            let newid = ('commit module handle)
+            from (methodsof module.builder) let fconst sampleimagelod
+            let newid = (sampleimagelod source self.uv (fconst 0.0))
             let numcomp = ('components imgformat)
-            let newid =
-                if (numcomp == 4) newid
-                else
-                    let fmt = ('format imgformat)
-                    switch fmt
-                    pass ImageFormat.U
-                    pass ImageFormat.S
-                    do
-                        switch numcomp
-                        case 1 (comp 0 newid)
-                        case 2 (uvec2 (comp 0 newid) (comp 1 newid))
-                        case 3 (uvec3 (comp 0 newid) (comp 1 newid) (comp 2 newid))
-                        default
-                            error "invalid number of components"
-                    pass ImageFormat.F
-                    pass ImageFormat.UNORM
-                    pass ImageFormat.SNORM
-                    do
-                        switch numcomp
-                        case 1 (comp 0 newid)
-                        case 2 (fvec2 (comp 0 newid) (comp 1 newid))
-                        case 3 (fvec3 (comp 0 newid) (comp 1 newid) (comp 2 newid))
-                        default
-                            error "invalid number of components"
-                    default
-                        trap;
-            'set ctx.gpujobmap newid uv_idx
-            return newid
+            return
+                remapvector ctx module newid numcomp
         case output (self)
             switch self.sink
             case SystemKey.Screen
-                let tid = ('typeof ctx.typer module self.value)
-                let typeid = ('headerof module tid)
-                switch typeid
-                case TypeId.typeid_imagestorage
-                    # all fine
-                default
-                    # execute dispatch
-                    self.value =
-                        (_ (gendispatch ctx module self.value) ())
+                # execute dispatch
+                self.value =
+                    (_ (gendispatch ctx module self.value) ())
                 'commit module handle
             default
                 error "unhandled output type"
-        default
-            merge-gpujobs;
-        newid
+        default ('commit module handle)
 
     FIRTyper.setup module
     'translate module module rootid

          
M testing/tukdag.sc +6 -7
@@ 159,7 159,7 @@ inline gen-level2-test ()
             clear screenrange
                 fvec3 (fconst 0) (fconst 0) (fconst 1)
 
-    #do
+    do
         let prim = (primitive PrimitiveType.TriangleStrip (uconst 4) (uconst 1))
         let vertexid = (comp 0 prim)
         let u = (utof (urem vertexid (uconst 2)))

          
@@ 181,7 181,7 @@ inline gen-level2-test ()
                     clear screenrange
                         fvec3 (uconst 0) (uconst 0) (uconst 1)
 
-    outputs
+    #outputs
         output SystemKey.Screen
             do
                 # frame time

          
@@ 223,15 223,14 @@ do
     gen-level2-test;
     cleanup;
     'dump module
-    let rootid = ('rootid module)
-    local typer : FIRTyper
-    'stageof typer module rootid
-    'lower module rootid
-print;
+    print "lowering..."
+    'lower module ('rootid module)
+print "folding constants..."
 'fold-constant-expressions module
 #cleanup;
 'dump-scope module
 #graphviz;
+print "compiling..."
 run;
 
 drop module