298663193388 — Leonard Ritter a month ago
* removed stages, added rangetype
2 files changed, 152 insertions(+), 299 deletions(-)

M lib/tukan/FIR.sc
M testing/tukdag.sc
M lib/tukan/FIR.sc +150 -297
@@ 404,6 404,8 @@ define-type "vectype"   (RIFF "VECT") Ve
     typecolor...
 define-type "vatype"    (RIFF "VA T") (tuple (types = (array AnyId)))
     typecolor...
+define-type "rangetype" (RIFF "RNGT") (tuple (type = AnyId) (range = AnyId))
+    typecolor...
 
 enum ImageFlags : u32
     none = 0:u32

          
@@ 483,245 485,9 @@ define-type "buffertype"    (RIFF "BUFT"
     and run a replace operation afterwards.
 
 let AnyIdArray = (Array AnyId)
-let RcAnyIdArray = (Rc AnyIdArray)
-
-fn... merge-arrays (a : RcAnyIdArray, b : RcAnyIdArray)
-    if (empty? b) (copy a)
-    elseif (empty? a) (copy b)
-    else
-        local imports : AnyIdArray
-        let acount aptr = ((countof a) as u32) (& (a @ 0))
-        let bcount bptr = ((countof b) as u32) (& (b @ 0))
-        loop (a b = 0:u32 0:u32)
-            if (a < acount)
-                if (b < bcount)
-                    let A B = (copy (aptr @ a)) (copy (bptr @ b))
-                    if (A == B)
-                        'append imports A
-                        repeat (a + 1) (b + 1)
-                    elseif (A < B)
-                        'append imports A
-                        repeat (a + 1) b
-                    else # (A > B)
-                        'append imports B
-                        repeat a (b + 1)
-                else
-                    'append imports (copy (aptr @ a))
-                    repeat (a + 1) b
-            elseif (b < bcount)
-                'append imports (copy (bptr @ b))
-                repeat a (b + 1)
-            else
-                break;
-        Rc.wrap (deref imports)
-
-struct StageInfo
-    # how many sample indirections have been performed?
-    sample-index : u32
-    # NoId, range, primitive or fragment
-    generator : AnyId
-    # values that need to be imported in order to evaluate
-        this expression in a shader stage
-    stage-import : RcAnyIdArray
-
-    fn __copy (self)
-        this-type
-            sample-index = self.sample-index
-            generator = self.generator
-            stage-import = (copy self.stage-import)
-
-    fn __repr (self)
-        ..
-            \ "(sample-index=" (repr self.sample-index)
-            \ " generator=" (repr self.generator)
-            \ " 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 =
-            if (self.generator == NoId)
-                copy other.generator
-            elseif (other.generator == NoId)
-                copy self.generator
-            elseif (self.generator == other.generator)
-                copy self.generator
-            else
-                error "generators of arguments do not match"
-        let stage-import =
-            if (empty? self.stage-import)
-                copy other.stage-import
-            elseif (empty? other.stage-import)
-                copy self.stage-import
-            elseif (self.stage-import == other.stage-import)
-                copy self.stage-import
-            else
-                # merge two ordered arrays
-                merge-arrays (view self.stage-import) (view other.stage-import)
-        this-type
-            sample-index = sample-index
-            generator = generator
-            stage-import = stage-import
 
 struct FIRTyper
     types : (Map AnyId AnyId)
-    stages : (Map AnyId StageInfo)
-    rootstage : StageInfo
-
-    fn setup (module)
-        # insert common types early, so we don't interfere with late insertions
-        from (methodsof module.builder) let uvec fvec
-        uvec 1
-        uvec 2
-        uvec 3
-        uvec 4
-        fvec 1
-        fvec 2
-        fvec 3
-        fvec 4
-        ;
-
-    fn stage-value (ctx module id)
-        from (methodsof module.builder) let uvec fvec
-        #report "staging" ('repr module id)
-        inline get (id)
-            try ('get ctx.stages id)
-            else
-                error
-                    .. "stage missing for: " ('repr module id)
-
-        let handle = ('handleof module id)
-        let vacount = ('vacount handle)
-        vvv bind stage
-        dispatch handle
-        case range (self)
-            let dims = self.dims
-            let sample-index =
-                fold (si = 0:u32) for i in (range vacount)
-                    max si ((get (dims @ i)) . sample-index)
-            StageInfo
-                sample-index = sample-index
-                generator = id
-                stage-import = (copy ctx.rootstage.stage-import)
-        case primitive (self)
-            let vertex = (get self.vertex)
-            StageInfo
-                sample-index = vertex.sample-index
-                generator = id
-                stage-import = (copy ctx.rootstage.stage-import)
-        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 =
-                    merge-arrays uv.stage-import (Rc.wrap (deref new-import))
-        default
-            switch ('typeidof module id)
-            pass TypeId.typeid_uconst
-            pass TypeId.typeid_fconst
-            pass TypeId.typeid_input
-            pass TypeId.typeid_output
-            pass TypeId.typeid_outputs
-            do
-                copy ctx.rootstage
-            pass TypeId.typeid_comp
-            pass TypeId.typeid_add
-            pass TypeId.typeid_sub
-            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
-            pass TypeId.typeid_utof
-            pass TypeId.typeid_fadd
-            pass TypeId.typeid_fsub
-            pass TypeId.typeid_fmul
-            pass TypeId.typeid_fdiv
-            pass TypeId.typeid_frem
-            pass TypeId.typeid_sin
-            pass TypeId.typeid_cos
-            pass TypeId.typeid_fvec2
-            pass TypeId.typeid_fvec3
-            pass TypeId.typeid_fvec4
-            pass TypeId.typeid_uvec2
-            pass TypeId.typeid_uvec3
-            pass TypeId.typeid_uvec4
-            do
-                # aggregate all arguments
-                local si =
-                    fold (si = (copy ctx.rootstage)) for srcid in ('sources handle)
-                        'combine si (get srcid) module
-                let new-imports? =
-                    if (si.generator == NoId) false
-                    else
-                        for srcid in ('sources handle)
-                            let s = (get srcid)
-                            if (s.generator == NoId)
-                                if (not ('constant? module srcid))
-                                    break true
-                        else false
-                if new-imports?
-                    local newarr : (Array AnyId)
-                    for srcid in ('sources handle)
-                        let s = (get srcid)
-                        if (s.generator == NoId)
-                            'append newarr srcid
-                    'sort newarr
-                    si.stage-import =
-                        merge-arrays si.stage-import (Rc.wrap (deref newarr))
-                deref si
-            default
-                error "failed to deduce stage"
-        #report "staged to" stage
-        'set ctx.stages id stage
-        ;
-
-    fn... stageof (ctx, module : FIR, id : AnyId)
-        try
-            return ('get ctx.stages id)
-        else;
-
-        'descend module id
-            on-enter =
-                capture (module id) {&ctx}
-                    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
-                        stage-value ctx module id
-                    except (err)
-                        error@+ err unknown-anchor
-                            .. "while deducing stage of " ('repr module id)
-        try
-            return ('get ctx.stages id)
-        else
-            trap;
 
     fn imagetypeof (self module id)
         let tid = ('typeof self module id)

          
@@ 739,15 505,29 @@ struct FIRTyper
                     " has type "
                     'repr module tid
 
+    fn rangeof (self module id)
+        let tid = ('typeof self module id)
+        let rangeid =
+            dispatch ('handleof module tid)
+            case rangetype (rtype)
+                copy rtype.range
+            default
+                error "ranged type expected"
+
+    fn typerangetype (module tid)
+        dispatch ('handleof module tid)
+        case rangetype (rtype)
+            copy rtype.range
+        default NoId
+
     fn type-value (ctx module id)
-        from (methodsof module.builder) let uvec fvec vectype
+        from (methodsof module.builder) let uvec fvec vectype rangetype
         #report "typing" ('repr module id)
         inline get (id)
             try (copy ('get ctx.types id))
             else
                 error
                     .. "type missing for: " ('repr module id)
-
         let handle = ('handleof module id)
         vvv bind type
         dispatch handle

          
@@ 760,14 540,20 @@ struct FIRTyper
                     .. "don't know how to type source: " (repr self.source)
         case load (self)
             get self.pointer
-        case sample (self)
+        #case sample (self)
             get self.source
         case sampleimagelod (self)
-            dispatch ('handleof module ('typevectype ctx module (get self.source)))
-            case vectype (self)
-                vectype self.element 4
-            default
-                error "can't deduce element type"
+            let tid = (get self.uv)
+            let rangeid = (typerangetype module tid)
+            let vect =
+                dispatch ('handleof module ('typevectype ctx module (get self.source)))
+                case vectype (self)
+                    vectype self.element 4
+                default
+                    error "can't deduce element type"
+            if (rangeid == NoId) vect
+            else
+                rangetype vect rangeid
         case clearimage (self)
             get self.target
         #case selectfragment (self)

          
@@ 797,23 583,29 @@ struct FIRTyper
                 for i entry in (enumerate wbinds u32)
                     args @ i = (get (entry @ 0))
                 'commit module
+        case range (self)
+            rangetype (uvec 3) id
         default
-            switch ('typeidof module id)
-            pass TypeId.typeid_range
+            let typeid = ('typeidof module id)
+            switch typeid
             pass TypeId.typeid_globalid
             do (uvec 3)
             pass TypeId.typeid_primitive
             do (uvec 2)
+
+            # constants
             pass TypeId.typeid_fconst
+            do (fvec 1)
+            pass TypeId.typeid_uconst
+            do (fvec 1)
+
+            # n-ary operations
             pass TypeId.typeid_utof
             pass TypeId.typeid_fadd
             pass TypeId.typeid_fsub
             pass TypeId.typeid_fmul
             pass TypeId.typeid_fdiv
             pass TypeId.typeid_sin
-            do (fvec 1)
-
-            pass TypeId.typeid_uconst
             pass TypeId.typeid_add
             pass TypeId.typeid_sub
             pass TypeId.typeid_mul

          
@@ 824,7 616,75 @@ struct FIRTyper
             pass TypeId.typeid_and
             pass TypeId.typeid_or
             pass TypeId.typeid_xor
-            do (uvec 1)
+            pass TypeId.typeid_uvec2
+            pass TypeId.typeid_uvec3
+            pass TypeId.typeid_uvec4
+            pass TypeId.typeid_fvec2
+            pass TypeId.typeid_fvec3
+            pass TypeId.typeid_fvec4
+            do
+                let count = handle.size
+                let data = handle.data
+                # try to find first range type
+                let tid =
+                    for i in (range count)
+                        let tid = (get (bitcast (data @ i) AnyId))
+                        if (('handleof module tid) . typeid == TypeId.typeid_rangetype)
+                            break tid
+                    else
+                        get (bitcast (data @ 0) AnyId)
+                let dcount =
+                    switch typeid
+                    pass TypeId.typeid_uvec2
+                    pass TypeId.typeid_fvec2
+                    do 2:u32
+                    pass TypeId.typeid_uvec3
+                    pass TypeId.typeid_fvec3
+                    do 3:u32
+                    pass TypeId.typeid_uvec4
+                    pass TypeId.typeid_fvec4
+                    do 4:u32
+                    default 1:u32
+                let vte =
+                    switch typeid
+                    pass TypeId.typeid_utof
+                    pass TypeId.typeid_fadd
+                    pass TypeId.typeid_fsub
+                    pass TypeId.typeid_fmul
+                    pass TypeId.typeid_fdiv
+                    pass TypeId.typeid_sin
+                    pass TypeId.typeid_fvec2
+                    pass TypeId.typeid_fvec3
+                    pass TypeId.typeid_fvec4
+                    do ElementType.F
+                    pass TypeId.typeid_add
+                    pass TypeId.typeid_sub
+                    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
+                    pass TypeId.typeid_uvec2
+                    pass TypeId.typeid_uvec3
+                    pass TypeId.typeid_uvec4
+                    do ElementType.U
+                    default
+                        error
+                            .. "unhandled typeid " (repr typeid)
+                dispatch ('handleof module tid)
+                case vectype (vt)
+                    vectype vte dcount
+                case rangetype (rng)
+                    dispatch ('handleof module rng.type)
+                    case vectype (vt)
+                        rangetype (vectype vte dcount) rng.range
+                    default
+                        trap;
+                default
+                    error "vector or ranged type expected"
 
             pass TypeId.typeid_outputs
             pass TypeId.typeid_output

          
@@ 834,13 694,6 @@ struct FIRTyper
             pass TypeId.typeid_wbind
             do NoId
 
-            case TypeId.typeid_uvec2 (uvec 2)
-            case TypeId.typeid_uvec3 (uvec 3)
-            case TypeId.typeid_uvec4 (uvec 4)
-            case TypeId.typeid_fvec2 (fvec 2)
-            case TypeId.typeid_fvec3 (fvec 3)
-            case TypeId.typeid_fvec4 (fvec 4)
-
             # types have no type
             pass TypeId.typeid_imagetype
             pass TypeId.typeid_samplertype

          
@@ 881,6 734,8 @@ struct FIRTyper
             if (handle.typeid == TypeId.typeid_vectype)
                 return tid
             dispatch handle
+            case rangetype (self)
+                repeat (copy self.type)
             case texturetype (self)
                 repeat (copy self.type)
             case imagetype (self)

          
@@ 1883,8 1738,6 @@ fn generate-IL (module rootid)
             drop-ctx = drop-ctx
             drop-body = drop-body
 
-    FIRTyper.setup module
-
     'descend module rootid
         on-leave =
             capture (module id) {&ctx}

          
@@ 2204,7 2057,7 @@ fn lower-FIR (module rootid)
                         'repr module ('typeof ctx.typer module source)
 
     fn gentexturetype (ctx module rangeid source)
-        let tid = ('typeof ctx.typer module source)
+        let tid = ('vectypeof ctx.typer module source)
         let imgformat =
             dispatch ('handleof module tid)
             case vectype (self)

          
@@ 2227,43 2080,50 @@ fn lower-FIR (module rootid)
                 error "image type expected"
         default;
 
-        let stage = ('stageof ctx.typer module source)
-        let rangeid = stage.generator
+        let rangeid = ('rangeof ctx.typer module source)
         let storagetype imgtype imgformat met =
             gentexturetype 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)
+        local aliases : (Map u32 AnyId)
+        local bindings : (Array AnyId)
+        local next_uniform_id = 0:u32
         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 texturetype (self)
-                    dispatch ('handleof module self.type)
-                    case imagetype (self)
-                        let sampler = ('alloc module TypeId.typeid_samplertype)
-                        @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
+        'set aliases rangeid (globalid)
+        # replace unranged values with uniforms
         let source =
             'translate module module source
-                aliases = (view importmap)
+                aliases = (view aliases)
+                on-enter-param =
+                    capture (self module id index paramid)
+                        {&aliases &bindings &ctx &next_uniform_id}
+                        try
+                            return false (copy ('get aliases paramid))
+                        else;
+                        let ty = ('typeof ctx.typer module paramid)
+                        if ((('handleof module ty) . typeid != TypeId.typeid_rangetype)
+                            and (not ('constant? module paramid)))
+                            let ty =
+                                dispatch ('handleof module ty)
+                                case texturetype (self)
+                                    dispatch ('handleof module self.type)
+                                    case imagetype (self)
+                                        let sampler = ('alloc module TypeId.typeid_samplertype)
+                                        @sampler = self
+                                        'commit module
+                                    default (copy self.type)
+                                default ty
+                            from (methodsof module.builder) let uniform load rbind
+                            let uniid = (uniform ty next_uniform_id)
+                            next_uniform_id += 1
+                            let aliasid = (load uniid)
+                            'set aliases paramid aliasid
+                            'append bindings
+                                rbind paramid uniid
+                            return false aliasid
+                        _ true NoId
         from (methodsof module.builder) let dispatch computefn
-            \ bindings wimage imagewrite load undef uvec2 comp
-            \ unpack-comp rbind wbind
+            \ wimage imagewrite load undef uvec2 comp unpack-comp rbind wbind
         let img = (wimage imgtype 0)
         let pos = (globalid)
         let uv = (uvec2 (unpack-comp pos 2))

          
@@ 2271,11 2131,6 @@ fn lower-FIR (module rootid)
         let func =
             computefn lx ly lz
                 imagewrite writevalue uv (load img)
-        local bindings : (Array AnyId)
-        'reserve bindings ((countof uniforms) + 1)
-        for src trg in (zip imports uniforms)
-            'append bindings
-                rbind src trg
         'append bindings
             wbind (undef storagetype) img
         let bcount = ((countof bindings) as u32)

          
@@ 2295,8 2150,7 @@ fn lower-FIR (module rootid)
         let vacount = ('vacount handle)
         dispatch handle
         case clear (self)
-            let stage = ('stageof ctx.typer module self.range)
-            let rangeid = (copy stage.generator)
+            let rangeid = ('rangeof ctx.typer module self.range)
             let storagetype imgtype imgformat met =
                 gentexturetype ctx module rangeid self.value
             from (methodsof module.builder) let clearimage uconst undef

          
@@ 2332,7 2186,6 @@ fn lower-FIR (module rootid)
                 error "unhandled output type"
         default ('commit module handle)
 
-    FIRTyper.setup module
     'translate module module rootid
         on-leave =
             capture (module handle oldmodule id) {&ctx}

          
M testing/tukdag.sc +2 -2
@@ 287,7 287,7 @@ inline graphviz ()
         'showdot module ('rootid module)
             module-dir .. "/tukdag"
 
-let prog = (gen-level1-test-geometry)
+#let prog = (gen-level1-test-geometry)
 #let prog = (gen-level1-test)
 #let prog =
     do

          
@@ 296,7 296,7 @@ let prog = (gen-level1-test-geometry)
         'dump module prog
         print "lowering..."
         'lower module prog
-#let prog =
+let prog =
     do
         let prog = (gen-level2-test)
         let prog = (cleanup prog)