diff options
author | Péter Diviánszky <divipp@gmail.com> | 2016-02-10 05:04:38 +0100 |
---|---|---|
committer | Péter Diviánszky <divipp@gmail.com> | 2016-02-10 05:04:38 +0100 |
commit | ad3af669aa19b3fc6efa7b075bf222e04bd7aeeb (patch) | |
tree | 13540d3e82c957962623bcc6e80cf45052990cba /src/LambdaCube/Compiler | |
parent | ce03eee527abc81ddfa1be67145380ac81dc32c8 (diff) |
refactored uniform collecting
Diffstat (limited to 'src/LambdaCube/Compiler')
-rw-r--r-- | src/LambdaCube/Compiler/CoreToIR.hs | 105 |
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 (..)) | |||
46 | import Data.Version | 46 | import Data.Version |
47 | import Paths_lambdacube_compiler (version) | 47 | import Paths_lambdacube_compiler (version) |
48 | 48 | ||
49 | (<&>) = flip (<$>) | ||
50 | |||
49 | -------------------------------------------------------------------------- | 51 | -------------------------------------------------------------------------- |
50 | 52 | ||
51 | type CG = State IR.Pipeline | 53 | type 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 | ||
259 | getRenderTextures :: Exp -> [Exp] | ||
260 | getRenderTextures e = case e of | ||
261 | Texture2D _ _ _ _ -> [e] | ||
262 | Exp e -> foldMap getRenderTextures e | ||
263 | |||
264 | data Uniform | ||
265 | = UUniform | ||
266 | | UTexture2DSlot | ||
267 | | UTexture2D Integer Integer Exp | ||
268 | deriving (Show) | ||
269 | |||
270 | type Uniforms = Map String (Uniform, (IR.InputType, String)) | ||
271 | type Uniforms' = Map String (Uniform, IR.InputType) | ||
272 | |||
273 | getUniforms :: Exp -> Uniforms | ||
274 | getUniforms 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 | |||
280 | pattern Uniform n <- Prim1 "Uniform" (EString n) | ||
281 | pattern Texture2DSlot s <- Let _ (A3 "Sampler" _ _ (A1 "Texture2DSlot" (EString s))) | ||
282 | pattern Texture2D n w h b <- Let n (A3 "Sampler" _ _ (A2 "Texture2D" (A2 "V2" (EInt w) (EInt h)) b)) | ||
283 | |||
284 | compFrameBuffer x = case x of | 261 | compFrameBuffer 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 | ||
637 | parens a = "(" <+> a <+> ")" | 616 | parens a = "(" <+> a <+> ")" |
638 | 617 | ||
639 | genGLSL :: [SName] -> Exp -> Doc | 618 | data Uniform |
619 | = UUniform | ||
620 | | UTexture2DSlot | ||
621 | | UTexture2D Integer Integer Exp | ||
622 | deriving (Show) | ||
623 | |||
624 | type Uniforms = Map String (Uniform, (IR.InputType, String)) | ||
625 | |||
626 | genGLSL :: [SName] -> Exp -> WriterT Uniforms (State [String]) Doc | ||
640 | genGLSL dns e = case e of | 627 | genGLSL 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" | |||
927 | makeTE ((_, t): vs) = I.EBind2 (I.BLam Visible) t $ makeTE vs | 922 | makeTE ((_, t): vs) = I.EBind2 (I.BLam Visible) t $ makeTE vs |
928 | 923 | ||
929 | toExp :: I.ExpType -> Exp | 924 | toExp :: I.ExpType -> Exp |
930 | toExp = flip runReader [] . flip evalStateT freshTypeVars . f_ | 925 | toExp = 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) |