diff options
author | Csaba Hruska <csaba.hruska@gmail.com> | 2015-04-30 14:28:27 +0200 |
---|---|---|
committer | Csaba Hruska <csaba.hruska@gmail.com> | 2015-05-18 14:50:52 +0200 |
commit | 91f82aca82dc282d5630c1bddd8dc773c679cc76 (patch) | |
tree | 6060474da94e6fb8a1f46eebd0cba0c5a607cbd3 /Backend/GL/Type.hs | |
parent | 1d047c6fa195901dc149bdbe4b4d0497c9b5f9c6 (diff) |
split dsl compiler and ir backend
Diffstat (limited to 'Backend/GL/Type.hs')
-rw-r--r-- | Backend/GL/Type.hs | 530 |
1 files changed, 530 insertions, 0 deletions
diff --git a/Backend/GL/Type.hs b/Backend/GL/Type.hs new file mode 100644 index 0000000..80cba6d --- /dev/null +++ b/Backend/GL/Type.hs | |||
@@ -0,0 +1,530 @@ | |||
1 | {-# LANGUAGE ExistentialQuantification, FlexibleInstances, GeneralizedNewtypeDeriving, ScopedTypeVariables #-} | ||
2 | module Backend.GL.Type where | ||
3 | |||
4 | import Data.ByteString.Char8 (ByteString) | ||
5 | import Data.IORef | ||
6 | import Data.Int | ||
7 | import Data.IntMap (IntMap) | ||
8 | import Data.Set (Set) | ||
9 | import Data.Trie (Trie) | ||
10 | import Data.Vector (Vector) | ||
11 | import Data.Word | ||
12 | import Foreign.Ptr | ||
13 | import Foreign.Storable | ||
14 | |||
15 | import Graphics.Rendering.OpenGL.Raw.Core33 | ||
16 | |||
17 | import IR | ||
18 | |||
19 | --------------- | ||
20 | -- Input API -- | ||
21 | --------------- | ||
22 | {- | ||
23 | -- Buffer | ||
24 | compileBuffer :: [Array] -> IO Buffer | ||
25 | bufferSize :: Buffer -> Int | ||
26 | arraySize :: Buffer -> Int -> Int | ||
27 | arrayType :: Buffer -> Int -> ArrayType | ||
28 | |||
29 | -- Object | ||
30 | addObject :: Renderer -> ByteString -> Primitive -> Maybe (IndexStream Buffer) -> Trie (Stream Buffer) -> [ByteString] -> IO Object | ||
31 | removeObject :: Renderer -> Object -> IO () | ||
32 | objectUniformSetter :: Object -> Trie InputSetter | ||
33 | -} | ||
34 | |||
35 | data Buffer -- internal type | ||
36 | = Buffer | ||
37 | { bufArrays :: Vector ArrayDesc | ||
38 | , bufGLObj :: GLuint | ||
39 | } | ||
40 | deriving (Show,Eq) | ||
41 | |||
42 | data ArrayDesc | ||
43 | = ArrayDesc | ||
44 | { arrType :: ArrayType | ||
45 | , arrLength :: Int -- item count | ||
46 | , arrOffset :: Int -- byte position in buffer | ||
47 | , arrSize :: Int -- size in bytes | ||
48 | } | ||
49 | deriving (Show,Eq) | ||
50 | |||
51 | {- | ||
52 | handles: | ||
53 | uniforms | ||
54 | textures | ||
55 | buffers | ||
56 | objects | ||
57 | |||
58 | GLPipelineInput can be attached to GLPipeline | ||
59 | -} | ||
60 | |||
61 | {- | ||
62 | pipeline input: | ||
63 | - independent from pipeline | ||
64 | - per object features: enable/disable visibility, set render ordering | ||
65 | -} | ||
66 | |||
67 | data SlotSchema | ||
68 | = SlotSchema | ||
69 | { primitive :: FetchPrimitive | ||
70 | , attributes :: Trie StreamType | ||
71 | } | ||
72 | deriving Show | ||
73 | |||
74 | data PipelineSchema | ||
75 | = PipelineSchema | ||
76 | { slots :: Trie SlotSchema | ||
77 | , uniforms :: Trie InputType | ||
78 | } | ||
79 | deriving Show | ||
80 | |||
81 | data GLUniform = forall a. Storable a => GLUniform !InputType !(IORef a) | ||
82 | |||
83 | instance Show GLUniform where | ||
84 | show (GLUniform t _) = "GLUniform " ++ show t | ||
85 | |||
86 | data OrderJob | ||
87 | = Generate | ||
88 | | Reorder | ||
89 | | Ordered | ||
90 | |||
91 | data GLSlot | ||
92 | = GLSlot | ||
93 | { objectMap :: IntMap Object | ||
94 | , sortedObjects :: Vector (Int,Object) | ||
95 | , orderJob :: OrderJob | ||
96 | } | ||
97 | |||
98 | data GLPipelineInput | ||
99 | = GLPipelineInput | ||
100 | { schema :: PipelineSchema | ||
101 | , slotMap :: Trie SlotName | ||
102 | , slotVector :: Vector (IORef GLSlot) | ||
103 | , objSeed :: IORef Int | ||
104 | , uniformSetter :: Trie InputSetter | ||
105 | , uniformSetup :: Trie GLUniform | ||
106 | , screenSize :: IORef (Word,Word) | ||
107 | , pipelines :: IORef (Vector (Maybe GLPipeline)) -- attached pipelines | ||
108 | } | ||
109 | |||
110 | data Object -- internal type | ||
111 | = Object | ||
112 | { objSlot :: SlotName | ||
113 | , objPrimitive :: Primitive | ||
114 | , objIndices :: Maybe (IndexStream Buffer) | ||
115 | , objAttributes :: Trie (Stream Buffer) | ||
116 | , objUniSetter :: Trie InputSetter | ||
117 | , objUniSetup :: Trie GLUniform | ||
118 | , objOrder :: IORef Int | ||
119 | , objEnabled :: IORef Bool | ||
120 | , objId :: Int | ||
121 | , objCommands :: IORef (Vector (Vector [GLObjectCommand])) -- pipeline id, program name, commands | ||
122 | } | ||
123 | |||
124 | -------------- | ||
125 | -- Pipeline -- | ||
126 | -------------- | ||
127 | |||
128 | data GLProgram | ||
129 | = GLProgram | ||
130 | { shaderObjects :: [GLuint] | ||
131 | , programObject :: GLuint | ||
132 | , inputUniforms :: Trie GLint | ||
133 | , inputTextures :: Trie GLint -- all input textures (render texture + uniform texture) | ||
134 | , inputTextureUniforms :: Set ByteString | ||
135 | , inputStreams :: Trie (GLuint,ByteString) | ||
136 | } | ||
137 | |||
138 | data GLTexture | ||
139 | = GLTexture | ||
140 | { glTextureObject :: GLuint | ||
141 | , glTextureTarget :: GLenum | ||
142 | } | ||
143 | |||
144 | data InputConnection | ||
145 | = InputConnection | ||
146 | { icId :: Int -- identifier (vector index) for attached pipeline | ||
147 | , icInput :: GLPipelineInput | ||
148 | , icSlotMapPipelineToInput :: Vector SlotName -- GLPipeline to GLPipelineInput slot name mapping | ||
149 | , icSlotMapInputToPipeline :: Vector (Maybe SlotName) -- GLPipelineInput to GLPipeline slot name mapping | ||
150 | } | ||
151 | |||
152 | data GLPipeline | ||
153 | = GLPipeline | ||
154 | { glPrograms :: Vector GLProgram | ||
155 | , glTextures :: Vector GLTexture | ||
156 | , glSamplers :: Vector GLSampler | ||
157 | , glTargets :: Vector GLRenderTarget | ||
158 | , glCommands :: [GLCommand] | ||
159 | , glSlotPrograms :: Vector [ProgramName] -- programs depend on a slot | ||
160 | , glInput :: IORef (Maybe InputConnection) | ||
161 | , glSlotNames :: Vector ByteString | ||
162 | , glVAO :: GLuint | ||
163 | , glTexUnitMapping :: Trie (IORef GLint) -- maps texture uniforms to texture units | ||
164 | } | ||
165 | |||
166 | data GLSampler | ||
167 | = GLSampler | ||
168 | { samplerObject :: GLuint | ||
169 | } | ||
170 | |||
171 | data GLRenderTarget | ||
172 | = GLRenderTarget | ||
173 | { framebufferObject :: GLuint | ||
174 | , framebufferDrawbuffers :: Maybe [GLenum] | ||
175 | } | ||
176 | |||
177 | data GLCommand | ||
178 | = GLSetRasterContext !RasterContext | ||
179 | | GLSetAccumulationContext !AccumulationContext | ||
180 | | GLSetRenderTarget !GLuint !(Maybe [GLenum]) | ||
181 | | GLSetProgram !GLuint | ||
182 | | GLSetSamplerUniform !GLint !GLint (IORef GLint) -- sampler index, texture unit, IORef stores the actual texture unit mapping | ||
183 | | GLSetTexture !GLenum !GLuint !GLuint | ||
184 | | GLSetSampler !GLuint !GLuint | ||
185 | | GLRenderSlot !SlotName !ProgramName | ||
186 | | GLClearRenderTarget [(ImageSemantic,Value)] | ||
187 | | GLGenerateMipMap !GLenum !GLenum | ||
188 | | GLSaveImage FrameBufferComponent ImageRef -- from framebuffer component to texture (image) | ||
189 | | GLLoadImage ImageRef FrameBufferComponent -- from texture (image) to framebuffer component | ||
190 | deriving Show | ||
191 | |||
192 | instance Show (IORef GLint) where | ||
193 | show _ = "(IORef GLint)" | ||
194 | |||
195 | data GLObjectCommand | ||
196 | = GLSetUniform !GLint !GLUniform | ||
197 | | GLBindTexture !GLenum !(IORef GLint) !GLUniform -- binds the texture from the gluniform to the specified texture unit and target | ||
198 | | GLSetVertexAttribArray !GLuint !GLuint !GLint !GLenum !(Ptr ()) -- index buffer size type pointer | ||
199 | | GLSetVertexAttribIArray !GLuint !GLuint !GLint !GLenum !(Ptr ()) -- index buffer size type pointer | ||
200 | | GLSetVertexAttrib !GLuint !(Stream Buffer) -- index value | ||
201 | | GLDrawArrays !GLenum !GLint !GLsizei -- mode first count | ||
202 | | GLDrawElements !GLenum !GLsizei !GLenum !GLuint !(Ptr ()) -- mode count type buffer indicesPtr | ||
203 | deriving Show | ||
204 | |||
205 | type SetterFun a = a -> IO () | ||
206 | |||
207 | -- user will provide scalar input data via this type | ||
208 | data InputSetter | ||
209 | = SBool (SetterFun Bool) | ||
210 | | SV2B (SetterFun V2B) | ||
211 | | SV3B (SetterFun V3B) | ||
212 | | SV4B (SetterFun V4B) | ||
213 | | SWord (SetterFun Word32) | ||
214 | | SV2U (SetterFun V2U) | ||
215 | | SV3U (SetterFun V3U) | ||
216 | | SV4U (SetterFun V4U) | ||
217 | | SInt (SetterFun Int32) | ||
218 | | SV2I (SetterFun V2I) | ||
219 | | SV3I (SetterFun V3I) | ||
220 | | SV4I (SetterFun V4I) | ||
221 | | SFloat (SetterFun Float) | ||
222 | | SV2F (SetterFun V2F) | ||
223 | | SV3F (SetterFun V3F) | ||
224 | | SV4F (SetterFun V4F) | ||
225 | | SM22F (SetterFun M22F) | ||
226 | | SM23F (SetterFun M23F) | ||
227 | | SM24F (SetterFun M24F) | ||
228 | | SM32F (SetterFun M32F) | ||
229 | | SM33F (SetterFun M33F) | ||
230 | | SM34F (SetterFun M34F) | ||
231 | | SM42F (SetterFun M42F) | ||
232 | | SM43F (SetterFun M43F) | ||
233 | | SM44F (SetterFun M44F) | ||
234 | -- shadow textures | ||
235 | | SSTexture1D | ||
236 | | SSTexture2D | ||
237 | | SSTextureCube | ||
238 | | SSTexture1DArray | ||
239 | | SSTexture2DArray | ||
240 | | SSTexture2DRect | ||
241 | -- float textures | ||
242 | | SFTexture1D | ||
243 | | SFTexture2D (SetterFun TextureData) | ||
244 | | SFTexture3D | ||
245 | | SFTextureCube | ||
246 | | SFTexture1DArray | ||
247 | | SFTexture2DArray | ||
248 | | SFTexture2DMS | ||
249 | | SFTexture2DMSArray | ||
250 | | SFTextureBuffer | ||
251 | | SFTexture2DRect | ||
252 | -- int textures | ||
253 | | SITexture1D | ||
254 | | SITexture2D | ||
255 | | SITexture3D | ||
256 | | SITextureCube | ||
257 | | SITexture1DArray | ||
258 | | SITexture2DArray | ||
259 | | SITexture2DMS | ||
260 | | SITexture2DMSArray | ||
261 | | SITextureBuffer | ||
262 | | SITexture2DRect | ||
263 | -- uint textures | ||
264 | | SUTexture1D | ||
265 | | SUTexture2D | ||
266 | | SUTexture3D | ||
267 | | SUTextureCube | ||
268 | | SUTexture1DArray | ||
269 | | SUTexture2DArray | ||
270 | | SUTexture2DMS | ||
271 | | SUTexture2DMSArray | ||
272 | | SUTextureBuffer | ||
273 | | SUTexture2DRect | ||
274 | |||
275 | -- buffer handling | ||
276 | {- | ||
277 | user can fills a buffer (continuous memory region) | ||
278 | each buffer have a data descriptor, what describes the | ||
279 | buffer content. e.g. a buffer can contain more arrays of stream types | ||
280 | -} | ||
281 | |||
282 | -- user will provide stream data using this setup function | ||
283 | type BufferSetter = (Ptr () -> IO ()) -> IO () | ||
284 | |||
285 | -- specifies array component type (stream type in storage side) | ||
286 | -- this type can be overridden in GPU side, e.g ArrWord8 can be seen as TFloat or TWord also | ||
287 | data ArrayType | ||
288 | = ArrWord8 | ||
289 | | ArrWord16 | ||
290 | | ArrWord32 | ||
291 | | ArrInt8 | ||
292 | | ArrInt16 | ||
293 | | ArrInt32 | ||
294 | | ArrFloat | ||
295 | | ArrHalf -- Hint: half float is not supported in haskell | ||
296 | deriving (Show,Eq,Ord) | ||
297 | |||
298 | sizeOfArrayType :: ArrayType -> Int | ||
299 | sizeOfArrayType ArrWord8 = 1 | ||
300 | sizeOfArrayType ArrWord16 = 2 | ||
301 | sizeOfArrayType ArrWord32 = 4 | ||
302 | sizeOfArrayType ArrInt8 = 1 | ||
303 | sizeOfArrayType ArrInt16 = 2 | ||
304 | sizeOfArrayType ArrInt32 = 4 | ||
305 | sizeOfArrayType ArrFloat = 4 | ||
306 | sizeOfArrayType ArrHalf = 2 | ||
307 | |||
308 | -- describes an array in a buffer | ||
309 | data Array -- array type, element count (NOT byte size!), setter | ||
310 | = Array ArrayType Int BufferSetter | ||
311 | |||
312 | -- dev hint: this should be InputType | ||
313 | -- we restrict StreamType using type class | ||
314 | -- subset of InputType, describes a stream type (in GPU side) | ||
315 | data StreamType | ||
316 | = TWord | ||
317 | | TV2U | ||
318 | | TV3U | ||
319 | | TV4U | ||
320 | | TInt | ||
321 | | TV2I | ||
322 | | TV3I | ||
323 | | TV4I | ||
324 | | TFloat | ||
325 | | TV2F | ||
326 | | TV3F | ||
327 | | TV4F | ||
328 | | TM22F | ||
329 | | TM23F | ||
330 | | TM24F | ||
331 | | TM32F | ||
332 | | TM33F | ||
333 | | TM34F | ||
334 | | TM42F | ||
335 | | TM43F | ||
336 | | TM44F | ||
337 | deriving (Show,Eq,Ord) | ||
338 | |||
339 | toStreamType :: InputType -> Maybe StreamType | ||
340 | toStreamType Word = Just TWord | ||
341 | toStreamType V2U = Just TV2U | ||
342 | toStreamType V3U = Just TV3U | ||
343 | toStreamType V4U = Just TV4U | ||
344 | toStreamType Int = Just TInt | ||
345 | toStreamType V2I = Just TV2I | ||
346 | toStreamType V3I = Just TV3I | ||
347 | toStreamType V4I = Just TV4I | ||
348 | toStreamType Float = Just TFloat | ||
349 | toStreamType V2F = Just TV2F | ||
350 | toStreamType V3F = Just TV3F | ||
351 | toStreamType V4F = Just TV4F | ||
352 | toStreamType M22F = Just TM22F | ||
353 | toStreamType M23F = Just TM23F | ||
354 | toStreamType M24F = Just TM24F | ||
355 | toStreamType M32F = Just TM32F | ||
356 | toStreamType M33F = Just TM33F | ||
357 | toStreamType M34F = Just TM34F | ||
358 | toStreamType M42F = Just TM42F | ||
359 | toStreamType M43F = Just TM43F | ||
360 | toStreamType M44F = Just TM44F | ||
361 | toStreamType _ = Nothing | ||
362 | |||
363 | fromStreamType :: StreamType -> InputType | ||
364 | fromStreamType TWord = Word | ||
365 | fromStreamType TV2U = V2U | ||
366 | fromStreamType TV3U = V3U | ||
367 | fromStreamType TV4U = V4U | ||
368 | fromStreamType TInt = Int | ||
369 | fromStreamType TV2I = V2I | ||
370 | fromStreamType TV3I = V3I | ||
371 | fromStreamType TV4I = V4I | ||
372 | fromStreamType TFloat = Float | ||
373 | fromStreamType TV2F = V2F | ||
374 | fromStreamType TV3F = V3F | ||
375 | fromStreamType TV4F = V4F | ||
376 | fromStreamType TM22F = M22F | ||
377 | fromStreamType TM23F = M23F | ||
378 | fromStreamType TM24F = M24F | ||
379 | fromStreamType TM32F = M32F | ||
380 | fromStreamType TM33F = M33F | ||
381 | fromStreamType TM34F = M34F | ||
382 | fromStreamType TM42F = M42F | ||
383 | fromStreamType TM43F = M43F | ||
384 | fromStreamType TM44F = M44F | ||
385 | |||
386 | -- user can specify streams using Stream type | ||
387 | -- a stream can be constant (ConstXXX) or can came from a buffer | ||
388 | data Stream b | ||
389 | = ConstWord Word32 | ||
390 | | ConstV2U V2U | ||
391 | | ConstV3U V3U | ||
392 | | ConstV4U V4U | ||
393 | | ConstInt Int32 | ||
394 | | ConstV2I V2I | ||
395 | | ConstV3I V3I | ||
396 | | ConstV4I V4I | ||
397 | | ConstFloat Float | ||
398 | | ConstV2F V2F | ||
399 | | ConstV3F V3F | ||
400 | | ConstV4F V4F | ||
401 | | ConstM22F M22F | ||
402 | | ConstM23F M23F | ||
403 | | ConstM24F M24F | ||
404 | | ConstM32F M32F | ||
405 | | ConstM33F M33F | ||
406 | | ConstM34F M34F | ||
407 | | ConstM42F M42F | ||
408 | | ConstM43F M43F | ||
409 | | ConstM44F M44F | ||
410 | | Stream | ||
411 | { streamType :: StreamType | ||
412 | , streamBuffer :: b | ||
413 | , streamArrIdx :: Int | ||
414 | , streamStart :: Int | ||
415 | , streamLength :: Int | ||
416 | } | ||
417 | deriving Show | ||
418 | |||
419 | streamToStreamType :: Stream a -> StreamType | ||
420 | streamToStreamType s = case s of | ||
421 | ConstWord _ -> TWord | ||
422 | ConstV2U _ -> TV2U | ||
423 | ConstV3U _ -> TV3U | ||
424 | ConstV4U _ -> TV4U | ||
425 | ConstInt _ -> TInt | ||
426 | ConstV2I _ -> TV2I | ||
427 | ConstV3I _ -> TV3I | ||
428 | ConstV4I _ -> TV4I | ||
429 | ConstFloat _ -> TFloat | ||
430 | ConstV2F _ -> TV2F | ||
431 | ConstV3F _ -> TV3F | ||
432 | ConstV4F _ -> TV4F | ||
433 | ConstM22F _ -> TM22F | ||
434 | ConstM23F _ -> TM23F | ||
435 | ConstM24F _ -> TM24F | ||
436 | ConstM32F _ -> TM32F | ||
437 | ConstM33F _ -> TM33F | ||
438 | ConstM34F _ -> TM34F | ||
439 | ConstM42F _ -> TM42F | ||
440 | ConstM43F _ -> TM43F | ||
441 | ConstM44F _ -> TM44F | ||
442 | Stream t _ _ _ _ -> t | ||
443 | |||
444 | -- stream of index values (for index buffer) | ||
445 | data IndexStream b | ||
446 | = IndexStream | ||
447 | { indexBuffer :: b | ||
448 | , indexArrIdx :: Int | ||
449 | , indexStart :: Int | ||
450 | , indexLength :: Int | ||
451 | } | ||
452 | |||
453 | newtype TextureData | ||
454 | = TextureData | ||
455 | { textureObject :: GLuint | ||
456 | } | ||
457 | deriving Storable | ||
458 | |||
459 | data Primitive | ||
460 | = TriangleStrip | ||
461 | | TriangleList | ||
462 | | TriangleFan | ||
463 | | LineStrip | ||
464 | | LineList | ||
465 | | PointList | ||
466 | | TriangleStripAdjacency | ||
467 | | TriangleListAdjacency | ||
468 | | LineStripAdjacency | ||
469 | | LineListAdjacency | ||
470 | deriving (Eq,Ord,Bounded,Enum,Show) | ||
471 | |||
472 | type StreamSetter = Stream Buffer -> IO () | ||
473 | |||
474 | -- storable instances | ||
475 | instance Storable a => Storable (V2 a) where | ||
476 | sizeOf _ = 2 * sizeOf (undefined :: a) | ||
477 | alignment _ = sizeOf (undefined :: a) | ||
478 | |||
479 | peek q = do | ||
480 | let p = castPtr q :: Ptr a | ||
481 | k = sizeOf (undefined :: a) | ||
482 | x <- peek p | ||
483 | y <- peekByteOff p k | ||
484 | return $! (V2 x y) | ||
485 | |||
486 | poke q (V2 x y) = do | ||
487 | let p = castPtr q :: Ptr a | ||
488 | k = sizeOf (undefined :: a) | ||
489 | poke p x | ||
490 | pokeByteOff p k y | ||
491 | |||
492 | instance Storable a => Storable (V3 a) where | ||
493 | sizeOf _ = 3 * sizeOf (undefined :: a) | ||
494 | alignment _ = sizeOf (undefined :: a) | ||
495 | |||
496 | peek q = do | ||
497 | let p = castPtr q :: Ptr a | ||
498 | k = sizeOf (undefined :: a) | ||
499 | x <- peek p | ||
500 | y <- peekByteOff p k | ||
501 | z <- peekByteOff p (k*2) | ||
502 | return $! (V3 x y z) | ||
503 | |||
504 | poke q (V3 x y z) = do | ||
505 | let p = castPtr q :: Ptr a | ||
506 | k = sizeOf (undefined :: a) | ||
507 | poke p x | ||
508 | pokeByteOff p k y | ||
509 | pokeByteOff p (k*2) z | ||
510 | |||
511 | instance Storable a => Storable (V4 a) where | ||
512 | sizeOf _ = 4 * sizeOf (undefined :: a) | ||
513 | alignment _ = sizeOf (undefined :: a) | ||
514 | |||
515 | peek q = do | ||
516 | let p = castPtr q :: Ptr a | ||
517 | k = sizeOf (undefined :: a) | ||
518 | x <- peek p | ||
519 | y <- peekByteOff p k | ||
520 | z <- peekByteOff p (k*2) | ||
521 | w <- peekByteOff p (k*3) | ||
522 | return $! (V4 x y z w) | ||
523 | |||
524 | poke q (V4 x y z w) = do | ||
525 | let p = castPtr q :: Ptr a | ||
526 | k = sizeOf (undefined :: a) | ||
527 | poke p x | ||
528 | pokeByteOff p k y | ||
529 | pokeByteOff p (k*2) z | ||
530 | pokeByteOff p (k*3) w | ||