/
LC_C_Convert.hs
279 lines (239 loc) · 12.9 KB
/
LC_C_Convert.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
module LC_C_Convert (convertGPOutput) where
import GHC.TypeLits
import Debug.Trace
import LC_T_APIType (FlatTuple(..),Frequency(..))
import LC_T_DSLType (GPU,Tuple(..),TupleIdx(..))
import qualified LC_T_APIType as T
import qualified LC_T_DSLType as T hiding (Shadow)
import qualified LC_T_PrimFun as T
import qualified LC_T_HOAS as H
import LC_U_DeBruijn
import LC_U_APIType
import LC_G_APIType
import LC_C_PrimFun
import LC_G_Type as G
toInt :: KnownNat n => T.NatNum n -> Int
toInt (a :: T.NatNum n) = fromInteger $ natVal a
prjIdx i lyt = i--length lyt - i - 1
prjToInt :: TupleIdx t e -> Int
prjToInt ZeroTupIdx = 0
prjToInt (SuccTupIdx i) = 1 + prjToInt i
genTupLen :: GPU a => Int -> a -> Int
genTupLen i a = sum $ map tySize $ take i rt
where
rt = reverse t
Tuple t = genTy a
type Layout = [[Ty]]
genTy :: GPU a => a -> Ty
genTy = T.tupleType
convertGPOutput :: ExpC exp => H.GPOutput o -> exp
convertGPOutput (H.ImageOut a b c) = imageOut a b $ convertGP c
convertGPOutput (H.ScreenOut a) = screenOut $ convertGP a
convertGPOutput (H.MultiOut a) = multiOut $ map convertGPOutput a
-- GP
convertGP :: ExpC exp => H.Exp T.Obj t -> exp
convertGP = convertOpenGP []
convertOpenGP :: ExpC exp => Layout -> H.Exp T.Obj t -> exp
convertOpenGP = cvt
where
cvt :: ExpC exp => Layout -> H.Exp T.Obj t -> exp
cvt lyt (H.Fetch n p i) = fetch n (convertFetchPrimitive p) (T.toInputList i)
cvt lyt (H.Transform vs ps) = transform (convertFun1Vert lyt vs) (cvt lyt ps)
cvt lyt (H.Reassemble sh ps) = reassemble (convertGeometryShader lyt sh) (cvt lyt ps)
cvt lyt (H.Rasterize ctx ps) = rasterize (convertRasterContext ctx) $ cvt lyt ps
cvt lyt (H.FrameBuffer fb) = frameBuffer (convertFrameBuffer fb)
cvt lyt (H.Accumulate ctx f sh fs fb) = accumulate (convertAccumulationContext ctx) (convertFragmentFilter lyt f)
(convertFun1Frag lyt sh)
(cvt lyt fs)
(cvt lyt fb)
cvt lyt (H.PrjFrameBuffer n idx fb) = prjFrameBuffer n (prjToInt idx) $ convertGP fb
cvt lyt (H.PrjImage n idx img) = prjImage n (toInt idx) $ convertGP img
-- Vertex
convertOpenVertexOut :: ExpC exp => forall t.
Layout -- environment
-> H.VertexOut clipDistances t -- expression to be converted
-> exp
convertOpenVertexOut lyt = cvt
where
cvt :: ExpC exp => H.VertexOut clipDistances t' -> exp
cvt (H.VertexOut e1 e2 e3 ie :: H.VertexOut clipDistances t') = vertexOut (convertOpenExp lyt e1) (convertOpenExp lyt e2) (convertOpenFlatExp lyt e3) (convertOpenInterpolatedFlatExp lyt ie)
-- Fragment
convertOpenFragmentOut :: ExpC exp => forall t.
Layout -- environment
-> H.FragmentOut t -- expression to be converted
-> exp
convertOpenFragmentOut lyt = cvt
where
cvt :: ExpC exp => H.FragmentOut t' -> exp
cvt (H.FragmentOut fe :: H.FragmentOut t') = fragmentOut $ convertOpenFlatExp lyt fe
cvt (H.FragmentOutDepth e fe :: H.FragmentOut t') = fragmentOutDepth (convertOpenExp lyt e) (convertOpenFlatExp lyt fe)
cvt (H.FragmentOutRastDepth fe :: H.FragmentOut t') = fragmentOutRastDepth $ convertOpenFlatExp lyt fe
convertFragmentFilter :: (ExpC exp, GPU a)
=> Layout
-> H.FragmentFilter a
-> exp
convertFragmentFilter = cvt
where
cvt :: (ExpC exp, GPU a) => Layout -> H.FragmentFilter a -> exp
cvt lyt H.PassAll = passAll
cvt lyt (H.Filter f) = filter_ $ convertFun1Exp lyt f
-- Geometry
convertOpenGeometryOut :: ExpC exp => forall i clipDistances t.
Layout -- environment
-> H.GeometryOut i clipDistances t -- expression to be converted
-> exp
convertOpenGeometryOut lyt = cvt
where
cvt :: ExpC exp => H.GeometryOut i clipDistances t' -> exp
cvt (H.GeometryOut e1 e2 e3 e4 ie :: H.GeometryOut i clipDistances t') = geometryOut (convertOpenExp lyt e1)
(convertOpenExp lyt e2)
(convertOpenExp lyt e3)
(convertOpenFlatExp lyt e4)
(convertOpenInterpolatedFlatExp lyt ie)
convertGeometryShader :: ExpC exp
=> Layout
-> H.GeometryShader inputPrimitive outputPrimitive inputClipDistances outputClipDistances layerCount a b
-> exp
convertGeometryShader = cvt
where
cvt :: ExpC exp => Layout -> H.GeometryShader inputPrimitive outputPrimitive inputClipDistances outputClipDistances layerCount a b -> exp
cvt lyt (H.GeometryShader a b c e1 e2 e3) = geometryShader (toInt a) (convertOutputPrimitive b) c (convertFun1Exp lyt e1)
(convertFun1Exp lyt e2)
(convertFun1Geom lyt e3)
-- Common
convertOpenInterpolatedFlatExp :: ExpC exp => forall stage t.
Layout -- environment
-> H.InterpolatedFlatExp stage t -- expression to be converted
-> [exp]
convertOpenInterpolatedFlatExp lyt = cvt
where
cvt :: ExpC exp => H.InterpolatedFlatExp stage t' -> [exp]
cvt (ZT) = []
cvt (e:.xs) = cvt' e : cvt xs
cvt' :: ExpC exp => T.Interpolated (H.Exp stage) t' -> exp
cvt' (T.Flat e) = flat $ convertOpenExp lyt e
cvt' (T.Smooth e) = smooth $ convertOpenExp lyt e
cvt' (T.NoPerspective e) = noPerspective $ convertOpenExp lyt e
convertOpenFlatExp :: ExpC exp => forall stage t.
Layout -- environment
-> H.FlatExp stage t -- expression to be converted
-> [exp]
convertOpenFlatExp lyt = cvt
where
cvt :: ExpC exp => H.FlatExp stage t' -> [exp]
cvt (ZT) = []
cvt (e:.xs) = convertOpenExp lyt e : cvt xs
convertOpenExp :: ExpC exp => forall stage t.
Layout -- environment
-> H.Exp stage t -- expression to be converted
-> exp
convertOpenExp lyt = cvt
where
cvt :: ExpC exp => H.Exp stage t' -> exp
cvt (H.Tag i li :: H.Exp stage t') = var (genTy (undefined :: t')) (prjIdx i lyt) li
cvt (H.Const v :: H.Exp stage t') = const_ (genTy (undefined :: t')) (T.toValue v)
cvt (H.PrimVar v :: H.Exp stage t') = primVar (genTy (undefined :: t')) (fst $ T.toInput v)
cvt (H.Uni v :: H.Exp stage t') = uni (genTy (undefined :: t')) (fst $ T.toInput v)
cvt (H.Tup tupl :: H.Exp stage t') = tup (genTy (undefined :: t')) $ convertTuple lyt tupl
cvt (H.Prj idx (e :: H.Exp stage e') :: H.Exp stage' t') = prj (genTy (undefined :: t')) (genTupLen (prjToInt idx) (undefined :: e')) $ cvt e
cvt (H.Cond e1 e2 e3 :: H.Exp stage t') = cond (genTy (undefined :: t')) (cvt e1) (cvt e2) (cvt e3)
cvt (H.PrimApp p e :: H.Exp stage t') = primApp (genTy (undefined :: t')) (convertPrimFun p) $ cvt e
cvt (H.Sampler f em t :: H.Exp stage t') = sampler (genTy (undefined :: t')) f em $ convertTexture t
cvt (H.Loop e1 e2 e3 s :: H.Exp stage t') = loop (genTy (undefined :: t')) (convertFun1Exp lyt e1) (convertFun1Exp lyt e2) (convertFun1Exp lyt e3) (cvt s)
convertFun1Vert :: ExpC exp => forall a b clipDistances. GPU a
=> Layout
-> (H.Exp V a -> H.VertexOut clipDistances b)
-> exp
convertFun1Vert = convertFun1 convertOpenVertexOut
convertFun1Geom :: ExpC exp => (GPU a, GPU i, GPU b, GPU clipDistances)
=> Layout
-> (H.Exp G a -> H.GeometryOut i clipDistances b)
-> exp
convertFun1Geom = convertFun1 convertOpenGeometryOut
convertFun1Frag :: ExpC exp => forall a b. GPU a
=> Layout
-> (H.Exp F a -> H.FragmentOut b)
-> exp
convertFun1Frag = convertFun1 convertOpenFragmentOut
convertFun1Exp :: ExpC exp => forall stage a b. GPU a
=> Layout
-> (H.Exp stage a -> H.Exp stage b)
-> exp
convertFun1Exp = convertFun1 convertOpenExp
convertFun1 :: (GPU a, ExpC exp)
=> (Layout -> b -> exp) -> Layout -> (H.Exp stage a -> b) -> exp
convertFun1 cvt lyt (f :: H.Exp stage t' -> b) = lam (genTy (undefined :: t')) $ body $ cvt lyt' (f a)
where
lyt' = []:lyt
a = case f of
(fv :: H.Exp stage t -> t2) -> H.Tag (length lyt) (show $ genTy (undefined :: t))
convertExp :: ExpC exp
=> Layout -- array environment
-> H.Exp stage t -- expression to be converted
-> exp
convertExp lyt = convertOpenExp lyt
convertTuple :: ExpC exp
=> Layout
-> Tuple (H.Exp stage) t
-> [exp]
convertTuple _lyt NilTup = []
convertTuple lyt (es `SnocTup` e) = convertTuple lyt es ++ [convertOpenExp lyt e]
-- data type conversion
convertTexture :: ExpC exp
=> T.Texture (H.Exp T.Obj) dim arr t ar
-> exp
convertTexture (T.TextureSlot n t) = textureSlot n (convertTextureType t)
convertTexture (T.Texture t s m d) = texture (convertTextureType t) (T.toValue s) (convertMipMap m) (map convertGP d)
convertTextureDataType :: T.TextureDataType t ar -> TextureDataType
convertTextureDataType (T.Float a) = FloatT (T.toColorArity a)
convertTextureDataType (T.Int a) = IntT (T.toColorArity a)
convertTextureDataType (T.Word a) = WordT (T.toColorArity a)
convertTextureDataType T.Shadow = ShadowT
convertTextureType :: T.TextureType dim mip arr layerCount t ar -> TextureType
convertTextureType (T.Texture1D a b) = Texture1D (convertTextureDataType a) (toInt b)
convertTextureType (T.Texture2D a b) = Texture2D (convertTextureDataType a) (toInt b)
convertTextureType (T.Texture3D a) = Texture3D (convertTextureDataType a)
convertTextureType (T.TextureCube a) = TextureCube (convertTextureDataType a)
convertTextureType (T.TextureRect a) = TextureRect (convertTextureDataType a)
convertTextureType (T.Texture2DMS a b) = Texture2DMS (convertTextureDataType a) (toInt b)
convertTextureType (T.TextureBuffer a) = TextureBuffer (convertTextureDataType a)
convertMipMap :: T.MipMap t -> MipMap
convertMipMap (T.NoMip) = NoMip
convertMipMap (T.Mip a b) = Mip a b
convertMipMap (T.AutoMip a b) = AutoMip a b
convertRasterContext :: T.RasterContext p -> RasterContext
convertRasterContext (T.PointCtx a b c) = PointCtx a b c
convertRasterContext (T.LineCtx a b) = LineCtx a b
convertRasterContext (T.TriangleCtx a b c d) = TriangleCtx a b c d
convertBlending :: T.Blending c -> Blending
convertBlending T.NoBlending = NoBlending
convertBlending (T.BlendLogicOp a) = BlendLogicOp a
convertBlending (T.Blend a b c) = Blend a b c
convertFetchPrimitive :: T.FetchPrimitive a -> FetchPrimitive
convertFetchPrimitive v = case v of
T.Points -> Points
T.Lines -> Lines
T.Triangles -> Triangles
T.LinesAdjacency -> LinesAdjacency
T.TrianglesAdjacency -> TrianglesAdjacency
convertOutputPrimitive :: T.OutputPrimitive a -> OutputPrimitive
convertOutputPrimitive v = case v of
T.TrianglesOutput -> TrianglesOutput
T.LinesOutput -> LinesOutput
T.PointsOutput -> PointsOutput
convertAccumulationContext :: T.AccumulationContext b -> AccumulationContext
convertAccumulationContext (T.AccumulationContext n ops) = AccumulationContext n $ cvt ops
where
cvt :: FlatTuple T.NoConstraint T.FragmentOperation b -> [FragmentOperation]
cvt ZT = []
cvt (T.DepthOp a b:.xs) = DepthOp a b : cvt xs
cvt (T.StencilOp a b c :. xs) = StencilOp a b c : cvt xs
cvt (T.ColorOp a b :. xs) = ColorOp (convertBlending a) (T.toValue b) : cvt xs
convertFrameBuffer :: T.FrameBuffer layerCount t -> [Image]
convertFrameBuffer = cvt
where
cvt :: T.FrameBuffer layerCount t -> [Image]
cvt ZT = []
cvt (T.DepthImage a b:.xs) = DepthImage (toInt a) b : cvt xs
cvt (T.StencilImage a b:.xs) = StencilImage (toInt a) b : cvt xs
cvt (T.ColorImage a b:.xs) = ColorImage (toInt a) (T.toValue b) : cvt xs