summaryrefslogtreecommitdiff
path: root/Backend/GL/Type.hs
diff options
context:
space:
mode:
authorCsaba Hruska <csaba.hruska@gmail.com>2015-04-30 14:28:27 +0200
committerCsaba Hruska <csaba.hruska@gmail.com>2015-05-18 14:50:52 +0200
commit91f82aca82dc282d5630c1bddd8dc773c679cc76 (patch)
tree6060474da94e6fb8a1f46eebd0cba0c5a607cbd3 /Backend/GL/Type.hs
parent1d047c6fa195901dc149bdbe4b4d0497c9b5f9c6 (diff)
split dsl compiler and ir backend
Diffstat (limited to 'Backend/GL/Type.hs')
-rw-r--r--Backend/GL/Type.hs530
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 #-}
2module Backend.GL.Type where
3
4import Data.ByteString.Char8 (ByteString)
5import Data.IORef
6import Data.Int
7import Data.IntMap (IntMap)
8import Data.Set (Set)
9import Data.Trie (Trie)
10import Data.Vector (Vector)
11import Data.Word
12import Foreign.Ptr
13import Foreign.Storable
14
15import Graphics.Rendering.OpenGL.Raw.Core33
16
17import 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
35data Buffer -- internal type
36 = Buffer
37 { bufArrays :: Vector ArrayDesc
38 , bufGLObj :: GLuint
39 }
40 deriving (Show,Eq)
41
42data 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
67data SlotSchema
68 = SlotSchema
69 { primitive :: FetchPrimitive
70 , attributes :: Trie StreamType
71 }
72 deriving Show
73
74data PipelineSchema
75 = PipelineSchema
76 { slots :: Trie SlotSchema
77 , uniforms :: Trie InputType
78 }
79 deriving Show
80
81data GLUniform = forall a. Storable a => GLUniform !InputType !(IORef a)
82
83instance Show GLUniform where
84 show (GLUniform t _) = "GLUniform " ++ show t
85
86data OrderJob
87 = Generate
88 | Reorder
89 | Ordered
90
91data GLSlot
92 = GLSlot
93 { objectMap :: IntMap Object
94 , sortedObjects :: Vector (Int,Object)
95 , orderJob :: OrderJob
96 }
97
98data 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
110data 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
128data 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
138data GLTexture
139 = GLTexture
140 { glTextureObject :: GLuint
141 , glTextureTarget :: GLenum
142 }
143
144data 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
152data 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
166data GLSampler
167 = GLSampler
168 { samplerObject :: GLuint
169 }
170
171data GLRenderTarget
172 = GLRenderTarget
173 { framebufferObject :: GLuint
174 , framebufferDrawbuffers :: Maybe [GLenum]
175 }
176
177data 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
192instance Show (IORef GLint) where
193 show _ = "(IORef GLint)"
194
195data 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
205type SetterFun a = a -> IO ()
206
207-- user will provide scalar input data via this type
208data 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
283type 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
287data 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
298sizeOfArrayType :: ArrayType -> Int
299sizeOfArrayType ArrWord8 = 1
300sizeOfArrayType ArrWord16 = 2
301sizeOfArrayType ArrWord32 = 4
302sizeOfArrayType ArrInt8 = 1
303sizeOfArrayType ArrInt16 = 2
304sizeOfArrayType ArrInt32 = 4
305sizeOfArrayType ArrFloat = 4
306sizeOfArrayType ArrHalf = 2
307
308-- describes an array in a buffer
309data 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)
315data 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
339toStreamType :: InputType -> Maybe StreamType
340toStreamType Word = Just TWord
341toStreamType V2U = Just TV2U
342toStreamType V3U = Just TV3U
343toStreamType V4U = Just TV4U
344toStreamType Int = Just TInt
345toStreamType V2I = Just TV2I
346toStreamType V3I = Just TV3I
347toStreamType V4I = Just TV4I
348toStreamType Float = Just TFloat
349toStreamType V2F = Just TV2F
350toStreamType V3F = Just TV3F
351toStreamType V4F = Just TV4F
352toStreamType M22F = Just TM22F
353toStreamType M23F = Just TM23F
354toStreamType M24F = Just TM24F
355toStreamType M32F = Just TM32F
356toStreamType M33F = Just TM33F
357toStreamType M34F = Just TM34F
358toStreamType M42F = Just TM42F
359toStreamType M43F = Just TM43F
360toStreamType M44F = Just TM44F
361toStreamType _ = Nothing
362
363fromStreamType :: StreamType -> InputType
364fromStreamType TWord = Word
365fromStreamType TV2U = V2U
366fromStreamType TV3U = V3U
367fromStreamType TV4U = V4U
368fromStreamType TInt = Int
369fromStreamType TV2I = V2I
370fromStreamType TV3I = V3I
371fromStreamType TV4I = V4I
372fromStreamType TFloat = Float
373fromStreamType TV2F = V2F
374fromStreamType TV3F = V3F
375fromStreamType TV4F = V4F
376fromStreamType TM22F = M22F
377fromStreamType TM23F = M23F
378fromStreamType TM24F = M24F
379fromStreamType TM32F = M32F
380fromStreamType TM33F = M33F
381fromStreamType TM34F = M34F
382fromStreamType TM42F = M42F
383fromStreamType TM43F = M43F
384fromStreamType TM44F = M44F
385
386-- user can specify streams using Stream type
387-- a stream can be constant (ConstXXX) or can came from a buffer
388data 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
419streamToStreamType :: Stream a -> StreamType
420streamToStreamType 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)
445data IndexStream b
446 = IndexStream
447 { indexBuffer :: b
448 , indexArrIdx :: Int
449 , indexStart :: Int
450 , indexLength :: Int
451 }
452
453newtype TextureData
454 = TextureData
455 { textureObject :: GLuint
456 }
457 deriving Storable
458
459data 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
472type StreamSetter = Stream Buffer -> IO ()
473
474-- storable instances
475instance 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
492instance 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
511instance 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