summaryrefslogtreecommitdiff
path: root/src/LambdaCube/Compiler
diff options
context:
space:
mode:
authorPéter Diviánszky <divipp@gmail.com>2016-02-10 05:04:38 +0100
committerPéter Diviánszky <divipp@gmail.com>2016-02-10 05:04:38 +0100
commitad3af669aa19b3fc6efa7b075bf222e04bd7aeeb (patch)
tree13540d3e82c957962623bcc6e80cf45052990cba /src/LambdaCube/Compiler
parentce03eee527abc81ddfa1be67145380ac81dc32c8 (diff)
refactored uniform collecting
Diffstat (limited to 'src/LambdaCube/Compiler')
-rw-r--r--src/LambdaCube/Compiler/CoreToIR.hs105
1 files changed, 47 insertions, 58 deletions
diff --git a/src/LambdaCube/Compiler/CoreToIR.hs b/src/LambdaCube/Compiler/CoreToIR.hs
index 1de9d040..ce15510d 100644
--- a/src/LambdaCube/Compiler/CoreToIR.hs
+++ b/src/LambdaCube/Compiler/CoreToIR.hs
@@ -46,6 +46,8 @@ import LambdaCube.Compiler.Parser (up, Up (..))
46import Data.Version 46import Data.Version
47import Paths_lambdacube_compiler (version) 47import Paths_lambdacube_compiler (version)
48 48
49(<&>) = flip (<$>)
50
49-------------------------------------------------------------------------- 51--------------------------------------------------------------------------
50 52
51type CG = State IR.Pipeline 53type CG = State IR.Pipeline
@@ -256,31 +258,6 @@ getRenderTextureCommands = foldM (\(a,b) x -> f x >>= (\(c,d) -> return (c ++ a,
256 getTextureFun (Prim1 "PrjImageColor" a) = (,) a $ \[_, x] -> x 258 getTextureFun (Prim1 "PrjImageColor" a) = (,) a $ \[_, x] -> x
257 getTextureFun (Prim1 "PrjImage" a) = (,) a $ \[x] -> x 259 getTextureFun (Prim1 "PrjImage" a) = (,) a $ \[x] -> x
258 260
259getRenderTextures :: Exp -> [Exp]
260getRenderTextures e = case e of
261 Texture2D _ _ _ _ -> [e]
262 Exp e -> foldMap getRenderTextures e
263
264data Uniform
265 = UUniform
266 | UTexture2DSlot
267 | UTexture2D Integer Integer Exp
268 deriving (Show)
269
270type Uniforms = Map String (Uniform, (IR.InputType, String))
271type Uniforms' = Map String (Uniform, IR.InputType)
272
273getUniforms :: Exp -> Uniforms
274getUniforms e = case e of
275 Uniform s -> Map.singleton s $ (,) UUniform (compInputType $ tyOf e, toGLSLType "1" $ tyOf e)
276 Texture2DSlot s -> Map.singleton s $ (,) UTexture2DSlot (IR.FTexture2D{-compInputType $ tyOf e -- TODO-}, "sampler2D")
277 Texture2D s w h b -> Map.singleton s $ (,) (UTexture2D w h b) (IR.FTexture2D, "sampler2D")
278 Exp e -> foldMap getUniforms e
279
280pattern Uniform n <- Prim1 "Uniform" (EString n)
281pattern Texture2DSlot s <- Let _ (A3 "Sampler" _ _ (A1 "Texture2DSlot" (EString s)))
282pattern Texture2D n w h b <- Let n (A3 "Sampler" _ _ (A2 "Texture2D" (A2 "V2" (EInt w) (EInt h)) b))
283
284compFrameBuffer x = case x of 261compFrameBuffer x = case x of
285 ETuple a -> concatMap compFrameBuffer a 262 ETuple a -> concatMap compFrameBuffer a
286 Prim1 "DepthImage" a -> [(IR.Depth, compValue a)] 263 Prim1 "DepthImage" a -> [(IR.Depth, compValue a)]
@@ -571,20 +548,22 @@ genGLSLs backend
571 <> ["}"] 548 <> ["}"]
572 ) 549 )
573 where 550 where
574 vertGLSL = map (genGLSL' vertIn . ELam verti) verts 551 freshTypeVars = map (("s" ++) . show) [0..]
575 ptGLSL = genGLSL' vertOut'' rp
576 filtGLSL = genGLSL' (tail vertOut'') <$> ffilter
577 fragGLSL = genGLSL' (tail vertOut'') frag
578 552
579 vertUniforms = getUniforms vert <> getUniforms rp 553 (((vertGLSL, ptGLSL), vertUniforms), ((filtGLSL, fragGLSL), fragUniforms)) = flip evalState freshTypeVars $ (,)
580 fragUniforms = getUniforms frag <> maybe mempty getUniforms ffilter 554 <$> (runWriterT $ (,)
555 <$> traverse (genGLSL' vertIn . ELam verti) verts
556 <*> genGLSL' vertOut'' rp)
557 <*> (runWriterT $ (,)
558 <$> traverse (genGLSL' (tail vertOut'')) ffilter
559 <*> genGLSL' (tail vertOut'') frag)
581 560
582 vertOut'' = "gl_Position": map (("vo" ++) . show) [1..length vertOut] 561 vertOut'' = "gl_Position": map (("vo" ++) . show) [1..length vertOut]
583 562
584 vertIn = map (("vi" ++) . show) [1..length $ getPVars verti] 563 vertIn = map (("vi" ++) . show) [1..length $ getPVars verti]
585 564
586 genGLSL' vertOut (etaRed -> ELam i@(getPVars -> ps) o) 565 genGLSL' vertOut (etaRed -> ELam i@(getPVars -> ps) o)
587 | length ps == length vertOut = show $ genGLSL (reverse vertOut) o 566 | length ps == length vertOut = show <$> genGLSL (reverse vertOut) o
588 | otherwise = error $ "makeSubst illegal input " ++ show i ++ "\n" ++ show vertOut 567 | otherwise = error $ "makeSubst illegal input " ++ show i ++ "\n" ++ show vertOut
589 568
590 noUnit TUnit = False 569 noUnit TUnit = False
@@ -636,14 +615,30 @@ getPVars = \case
636 615
637parens a = "(" <+> a <+> ")" 616parens a = "(" <+> a <+> ")"
638 617
639genGLSL :: [SName] -> Exp -> Doc 618data Uniform
619 = UUniform
620 | UTexture2DSlot
621 | UTexture2D Integer Integer Exp
622 deriving (Show)
623
624type Uniforms = Map String (Uniform, (IR.InputType, String))
625
626genGLSL :: [SName] -> Exp -> WriterT Uniforms (State [String]) Doc
640genGLSL dns e = case e of 627genGLSL dns e = case e of
641 ELit a -> text $ show a
642 Var i _ -> text $ dns !! i
643 628
644 Uniform a -> text a 629 Prim1 "Uniform" (EString s) -> do
645 Texture2DSlot n -> text n 630 tell $ Map.singleton s $ (,) UUniform (compInputType $ tyOf e, toGLSLType "1" $ tyOf e)
646 Texture2D n _ _ _ -> text n 631 pure $ text s
632 A3 "Sampler" _ _ (A1 "Texture2DSlot" (EString s)) -> do
633 tell $ Map.singleton s $ (,) UTexture2DSlot (IR.FTexture2D{-compInputType $ tyOf e -- TODO-}, "sampler2D")
634 pure $ text s
635 A3 "Sampler" _ _ (A2 "Texture2D" (A2 "V2" (EInt w) (EInt h)) b) -> do
636 s <- newName
637 tell $ Map.singleton s $ (,) (UTexture2D w h b) (IR.FTexture2D, "sampler2D")
638 pure $ text s
639
640 ELit a -> pure $ text $ show a
641 Var i _ -> pure $ text $ dns !! i
647 642
648 -- texturing 643 -- texturing
649 A3 "Sampler" _ _ _ -> error "sampler GLSL codegen is not supported" 644 A3 "Sampler" _ _ _ -> error "sampler GLSL codegen is not supported"
@@ -655,15 +650,15 @@ genGLSL dns e = case e of
655 Prim2 "primCompareInt" a b -> error $ "GLSL codegen does not support: " ++ ppShow e 650 Prim2 "primCompareInt" a b -> error $ "GLSL codegen does not support: " ++ ppShow e
656 Prim2 "primCompareWord" a b -> error $ "GLSL codegen does not support: " ++ ppShow e 651 Prim2 "primCompareWord" a b -> error $ "GLSL codegen does not support: " ++ ppShow e
657 Prim2 "primCompareFloat" a b -> error $ "GLSL codegen does not support: " ++ ppShow e 652 Prim2 "primCompareFloat" a b -> error $ "GLSL codegen does not support: " ++ ppShow e
658 Prim1 "primNegateInt" a -> text "-" <+> parens (gen a) 653 Prim1 "primNegateInt" a -> (text "-" <+>) . parens <$> (gen a)
659 Prim1 "primNegateWord" a -> error $ "WebGL 1 does not support uint types: " ++ ppShow e 654 Prim1 "primNegateWord" a -> error $ "WebGL 1 does not support uint types: " ++ ppShow e
660 Prim1 "primNegateFloat" a -> text "-" <+> parens (gen a) 655 Prim1 "primNegateFloat" a -> (text "-" <+>) . parens <$> (gen a)
661 656
662 -- vectors 657 -- vectors
663 AN n xs | n `elem` ["V2", "V3", "V4"], Just f <- vecConName $ tyOf e -> functionCall f xs 658 AN n xs | n `elem` ["V2", "V3", "V4"], Just f <- vecConName $ tyOf e -> functionCall f xs
664 -- bool 659 -- bool
665 A0 "True" -> text "true" 660 A0 "True" -> pure $ text "true"
666 A0 "False" -> text "false" 661 A0 "False" -> pure $ text "false"
667 -- matrices 662 -- matrices
668 AN "M22F" xs -> functionCall "mat2" xs 663 AN "M22F" xs -> functionCall "mat2" xs
669 AN "M23F" xs -> error "WebGL 1 does not support matrices with this dimension" 664 AN "M23F" xs -> error "WebGL 1 does not support matrices with this dimension"
@@ -675,12 +670,12 @@ genGLSL dns e = case e of
675 AN "M43F" xs -> error "WebGL 1 does not support matrices with this dimension" 670 AN "M43F" xs -> error "WebGL 1 does not support matrices with this dimension"
676 AN "M44F" xs -> functionCall "mat4" xs -- where gen = gen 671 AN "M44F" xs -> functionCall "mat4" xs -- where gen = gen
677 672
678 Prim3 "primIfThenElse" a b c -> gen a <+> "?" <+> gen b <+> ":" <+> gen c 673 Prim3 "primIfThenElse" a b c -> hsep <$> sequence [gen a, pure "?", gen b, pure ":", gen c]
679 -- TODO: Texture Lookup Functions 674 -- TODO: Texture Lookup Functions
680 SwizzProj a x -> "(" <+> gen a <+> (")." <> text x) 675 SwizzProj a x -> gen a <&> \a -> "(" <+> a <+> (")." <> text x)
681 ELam _ _ -> error "GLSL codegen for lambda function is not supported yet" 676 ELam _ _ -> error "GLSL codegen for lambda function is not supported yet"
682 Let{} -> error "GLSL codegen for let is not supported yet" 677 Let{} -> error "GLSL codegen for let is not supported yet"
683 ETuple _ -> error "GLSL codegen for tuple is not supported yet" 678 ETuple _ -> pure $ error "GLSL codegen for tuple is not supported yet"
684 679
685 -- Primitive Functions 680 -- Primitive Functions
686 PrimN "==" xs -> binOp "==" xs 681 PrimN "==" xs -> binOp "==" xs
@@ -778,9 +773,11 @@ genGLSL dns e = case e of
778 773
779 x -> error $ "GLSL codegen - unsupported expression: " ++ ppShow x 774 x -> error $ "GLSL codegen - unsupported expression: " ++ ppShow x
780 where 775 where
781 prefixOp o [a] = text o <+> parens (gen a) 776 newName = gets head <* modify tail
782 binOp o [a, b] = parens (gen a) <+> text o <+> parens (gen b) 777
783 functionCall f a = text f <+> parens (hcat $ intersperse "," $ map gen a) 778 prefixOp o [a] = (text o <+>) . parens <$> (gen a)
779 binOp o [a, b] = hsep <$> sequence [parens <$> gen a, pure $ text o, parens <$> gen b]
780 functionCall f a = (text f <+>) . parens . hcat . intersperse "," <$> mapM gen a
784 781
785 gen = genGLSL dns 782 gen = genGLSL dns
786 783
@@ -835,8 +832,6 @@ is234 = (`elem` [2,3,4])
835- type in Var 832- type in Var
836- types 833- types
837- no erasure 834- no erasure
838- String names
839- sampler let
840-} 835-}
841 836
842 837
@@ -927,15 +922,9 @@ makeTE [] = I.EGlobal (error "makeTE - no source") I.initEnv $ error "makeTE"
927makeTE ((_, t): vs) = I.EBind2 (I.BLam Visible) t $ makeTE vs 922makeTE ((_, t): vs) = I.EBind2 (I.BLam Visible) t $ makeTE vs
928 923
929toExp :: I.ExpType -> Exp 924toExp :: I.ExpType -> Exp
930toExp = flip runReader [] . flip evalStateT freshTypeVars . f_ 925toExp = flip runReader [] . f_
931 where 926 where
932 freshTypeVars = map (("s" ++) . show) [0..] 927 f_ (e, et) = f__ (e, et)
933 newName = gets head <* modify tail
934 f_ (e, et)
935 | isSampler et = newName >>= \n -> do
936 t <- f_ (et, I.TType)
937 Let n <$> f__ (e, et)
938 | otherwise = f__ (e, et)
939 f__ (e, et) = case e of 928 f__ (e, et) = case e of
940 I.Var i -> asks $ up i . fst . (!!! i) 929 I.Var i -> asks $ up i . fst . (!!! i)
941-- I.Pi b x (I.down 0 -> Just y) -> Pi b "" <$> f_ (x, I.TType) <*> f_ (y, I.TType) 930-- I.Pi b x (I.down 0 -> Just y) -> Pi b "" <$> f_ (x, I.TType) <*> f_ (y, I.TType)