@@ -4,6 +4,8 @@ import io.computenode.cyfra.*
44import io .computenode .cyfra .dsl .*
55import io .computenode .cyfra .dsl .Expression .E
66import io .computenode .cyfra .dsl .Value .Scalar
7+ import io .computenode .cyfra .dsl .binding .{GBinding , GBuffer , GUniform , WriteBuffer , WriteUniform }
8+ import io .computenode .cyfra .dsl .gio .GIO
79import io .computenode .cyfra .dsl .struct .GStruct .*
810import io .computenode .cyfra .dsl .struct .GStructSchema
911import io .computenode .cyfra .spirv .Context
@@ -24,6 +26,28 @@ import scala.runtime.stdLibPatches.Predef.summon
2426
2527private [cyfra] object DSLCompiler :
2628
29+ @ tailrec
30+ private def getAllExprsFlattened (pending : List [GIO [? ]], acc : List [E [? ]], visitDetached : Boolean ): List [E [? ]] =
31+ pending match
32+ case Nil => acc
33+ case GIO .Pure (v) :: tail =>
34+ getAllExprsFlattened(tail, getAllExprsFlattened(v.tree, visitDetached) ::: acc, visitDetached)
35+ case GIO .FlatMap (v, n) :: tail =>
36+ getAllExprsFlattened(v :: n :: tail, acc, visitDetached)
37+ case GIO .Repeat (n, gio) :: tail =>
38+ val nAllExprs = getAllExprsFlattened(n.tree, visitDetached)
39+ getAllExprsFlattened(gio :: tail, nAllExprs ::: acc, visitDetached)
40+ case WriteBuffer (_, index, value) :: tail =>
41+ val indexAllExprs = getAllExprsFlattened(index.tree, visitDetached)
42+ val valueAllExprs = getAllExprsFlattened(value.tree, visitDetached)
43+ getAllExprsFlattened(tail, indexAllExprs ::: valueAllExprs ::: acc, visitDetached)
44+ case WriteUniform (_, value) :: tail =>
45+ val valueAllExprs = getAllExprsFlattened(value.tree, visitDetached)
46+ getAllExprsFlattened(tail, valueAllExprs ::: acc, visitDetached)
47+ case GIO .Printf (_, args* ) :: tail =>
48+ val argsAllExprs = args.flatMap(a => getAllExprsFlattened(a.tree, visitDetached)).toList
49+ getAllExprsFlattened(tail, argsAllExprs ::: acc, visitDetached)
50+
2751 // TODO: Not traverse same fn scopes for each fn call
2852 private def getAllExprsFlattened (root : E [? ], visitDetached : Boolean ): List [E [? ]] =
2953 var blockI = 0
@@ -33,7 +57,7 @@ private[cyfra] object DSLCompiler:
3357 def getAllScopesExprsAcc (toVisit : List [E [? ]], acc : List [E [? ]] = Nil ): List [E [? ]] = toVisit match
3458 case Nil => acc
3559 case e :: tail if visited.contains(e.treeid) => getAllScopesExprsAcc(tail, acc)
36- case e :: tail =>
60+ case e :: tail => // todo i don't think this really works (tail not used???)
3761 if allScopesCache.contains(root.treeid) then return allScopesCache(root.treeid)
3862 val eScopes = e.introducedScopes
3963 val filteredScopes = if visitDetached then eScopes else eScopes.filterNot(_.isDetached)
@@ -47,33 +71,52 @@ private[cyfra] object DSLCompiler:
4771 allScopesCache(root.treeid) = result
4872 result
4973
50- def compile (tree : Value , inTypes : List [Tag [? ]], outTypes : List [Tag [? ]], uniformSchema : GStructSchema [? ]): ByteBuffer =
51- val treeExpr = tree.tree
52- val allExprs = getAllExprsFlattened(treeExpr, visitDetached = true )
74+ // So far only used for printf
75+ private def getAllStrings (pending : List [GIO [? ]], acc : Set [String ]): Set [String ] =
76+ pending match
77+ case Nil => acc
78+ case GIO .FlatMap (v, n) :: tail =>
79+ getAllStrings(v :: n :: tail, acc)
80+ case GIO .Repeat (_, gio) :: tail =>
81+ getAllStrings(gio :: tail, acc)
82+ case GIO .Printf (format, _* ) :: tail =>
83+ getAllStrings(tail, acc + format)
84+ case _ :: tail => getAllStrings(tail, acc)
85+
86+ def compile (bodyIo : GIO [? ], bindings : List [GBinding [? ]]): ByteBuffer =
87+ val allExprs = getAllExprsFlattened(List (bodyIo), Nil , visitDetached = true )
5388 val typesInCode = allExprs.map(_.tag).distinct
54- val allTypes = (typesInCode ::: inTypes ::: outTypes ).distinct
89+ val allTypes = (typesInCode ::: bindings.map(_.tag) ).distinct
5590 def scalarTypes = allTypes.filter(_.tag <:< summon[Tag [Scalar ]].tag)
5691 val (typeDefs, typedContext) = defineScalarTypes(scalarTypes, Context .initialContext)
92+ val allStrings = getAllStrings(List (bodyIo), Set .empty)
93+ val (stringDefs, ctxWithStrings) = defineStrings(allStrings.toList, typedContext)
94+ val (buffersWithIndices, uniformsWithIndices) = bindings.zipWithIndex
95+ .partition:
96+ case (_ : GBuffer [? ], _) => true
97+ case (_ : GUniform [? ], _) => false
98+ .asInstanceOf [(List [(GBuffer [? ], Int )], List [(GUniform [? ], Int )])]
99+ val uniforms = uniformsWithIndices.map(_._1)
100+ val uniformSchemas = uniforms.map(_.schema)
57101 val structsInCode =
58102 (allExprs.collect {
59103 case cs : ComposeStruct [? ] => cs.resultSchema
60104 case gf : GetField [? , ? ] => gf.resultSchema
61- } :+ uniformSchema ).distinct
62- val (structDefs, structCtx) = defineStructTypes(structsInCode, typedContext )
63- val structNames = getStructNames(structsInCode, structCtx)
64- val (decorations, uniformDefs, uniformContext) = initAndDecorateUniforms(inTypes, outTypes, structCtx )
65- val (uniformStructDecorations, uniformStructInsns, uniformStructContext) = createAndInitUniformBlock(uniformSchema , uniformContext)
66- val blockNames = getBlockNames(uniformContext, uniformSchema )
105+ } ::: uniformSchemas ).distinct
106+ val (structDefs, structCtx) = defineStructTypes(structsInCode, ctxWithStrings )
107+ val ( structNames, structNamesCtx) = getStructNames(structsInCode, structCtx)
108+ val (decorations, uniformDefs, uniformContext) = initAndDecorateBuffers(buffersWithIndices, structNamesCtx )
109+ val (uniformStructDecorations, uniformStructInsns, uniformStructContext) = createAndInitUniformBlocks(uniformsWithIndices , uniformContext)
110+ val blockNames = getBlockNames(uniformContext, uniforms )
67111 val (inputDefs, inputContext) = createInvocationId(uniformStructContext)
68112 val (constDefs, constCtx) = defineConstants(allExprs, inputContext)
69113 val (varDefs, varCtx) = defineVarNames(constCtx)
70- val resultType = tree.tree.tag
71- val (main, ctxAfterMain) = compileMain(tree, resultType, varCtx)
114+ val (main, ctxAfterMain) = compileMain(bodyIo, varCtx)
72115 val (fnTypeDefs, fnDefs, ctxWithFnDefs) = compileFunctions(ctxAfterMain)
73116 val nameDecorations = getNameDecorations(ctxWithFnDefs)
74117
75118 val code : List [Words ] =
76- SpirvProgramCompiler .headers ::: blockNames ::: nameDecorations ::: structNames ::: SpirvProgramCompiler .workgroupDecorations :::
119+ SpirvProgramCompiler .headers ::: stringDefs ::: blockNames ::: nameDecorations ::: structNames ::: SpirvProgramCompiler .workgroupDecorations :::
77120 decorations ::: uniformStructDecorations ::: typeDefs ::: structDefs ::: fnTypeDefs ::: uniformDefs ::: uniformStructInsns ::: inputDefs :::
78121 constDefs ::: varDefs ::: main ::: fnDefs
79122
0 commit comments