summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCsaba Hruska <csaba.hruska@gmail.com>2015-06-09 11:34:57 +0100
committerCsaba Hruska <csaba.hruska@gmail.com>2015-06-09 11:34:57 +0100
commit4efa8405bd9eeec3c16bd8dd92cc5e7b66f8a3ae (patch)
treeb7703f8578eb35f00554e884e13216700147a0bc
parent23747de92cb2883e3a0ce97805e354ea502378fc (diff)
support for immediate stream data
-rw-r--r--Backend/GL/Backend.hs153
-rw-r--r--Backend/GL/Type.hs10
2 files changed, 158 insertions, 5 deletions
diff --git a/Backend/GL/Backend.hs b/Backend/GL/Backend.hs
index eed33eb..b0739a5 100644
--- a/Backend/GL/Backend.hs
+++ b/Backend/GL/Backend.hs
@@ -8,9 +8,10 @@ import Data.Bits
8import Data.ByteString.Char8 (ByteString,pack) 8import Data.ByteString.Char8 (ByteString,pack)
9import Data.IORef 9import Data.IORef
10import Data.IntMap (IntMap) 10import Data.IntMap (IntMap)
11import Data.Maybe (isNothing) 11import Data.Maybe (isNothing,fromJust)
12import Data.Set (Set) 12import Data.Set (Set)
13import Data.Trie as T 13import Data.Trie as T
14import Data.Trie.Convenience as T
14import Data.Vector (Vector,(!),(//)) 15import Data.Vector (Vector,(!),(//))
15import qualified Data.ByteString.Char8 as SB 16import qualified Data.ByteString.Char8 as SB
16import qualified Data.Foldable as F 17import qualified Data.Foldable as F
@@ -25,11 +26,13 @@ import Graphics.Rendering.OpenGL.Raw.Core33
25import Foreign 26import Foreign
26 27
27-- LC IR imports 28-- LC IR imports
28import IR as IR 29import IR hiding (streamType)
30import qualified IR as IR
29 31
30import Backend.GL.Type 32import Backend.GL.Type
31import Backend.GL.Util 33import Backend.GL.Util
32 34
35import Backend.GL.Data
33import Backend.GL.Input 36import Backend.GL.Input
34 37
35setupRasterContext :: RasterContext -> IO () 38setupRasterContext :: RasterContext -> IO ()
@@ -225,11 +228,17 @@ compileProgram uniTrie p = do
225 (attributes,attributesType) <- queryStreams po 228 (attributes,attributesType) <- queryStreams po
226 print uniforms 229 print uniforms
227 print attributes 230 print attributes
228 when (uniformsType /= (toTrie $ programUniforms p) `unionL` (toTrie $ programInTextures p)) $ do 231 let lcUniforms = (toTrie $ programUniforms p) `unionL` (toTrie $ programInTextures p)
229 putStrLn $ "expected: " ++ show ((toTrie $ programUniforms p) `unionL` (toTrie $ programInTextures p)) 232 lcStreams = fmap snd (toTrie $ programStreams p)
233 check a m = and $ map go $ T.toList m
234 where go (k,b) = case T.lookup k a of
235 Nothing -> True
236 Just x -> x == b
237 unless (check lcUniforms uniformsType) $ do
238 putStrLn $ "expected: " ++ show lcUniforms
230 putStrLn $ "actual: " ++ show uniformsType 239 putStrLn $ "actual: " ++ show uniformsType
231 fail "shader program uniform input mismatch!" 240 fail "shader program uniform input mismatch!"
232 when (attributesType /= fmap snd (toTrie $ programStreams p)) $ fail $ "shader program stream input mismatch! " ++ show (attributesType,fmap snd (toTrie $ programStreams p)) 241 unless (check lcStreams attributesType) $ fail $ "shader program stream input mismatch! " ++ show (attributesType,lcStreams)
233 -- the public (user) pipeline and program input is encoded by the slots, therefore the programs does not distinct the render and slot textures input 242 -- the public (user) pipeline and program input is encoded by the slots, therefore the programs does not distinct the render and slot textures input
234 let inUniNames = toTrie $ programUniforms p 243 let inUniNames = toTrie $ programUniforms p
235 (inUniforms,inTextures) = L.partition (\(n,v) -> T.member n inUniNames) $ T.toList $ uniforms 244 (inUniforms,inTextures) = L.partition (\(n,v) -> T.member n inUniNames) $ T.toList $ uniforms
@@ -351,6 +360,130 @@ compileRenderTarget texs glTexs (RenderTarget targets) = do
351 , framebufferDrawbuffers = Nothing 360 , framebufferDrawbuffers = Nothing
352 } 361 }
353 362
363compileStreamData :: StreamData -> IO GLStream
364compileStreamData s = do
365 let withV w a f = w a (\p -> f $ castPtr p)
366 let compileAttr (VFloatArray v) = Array ArrFloat (length v) (withV withArray v)
367 compileAttr (VIntArray v) = Array ArrInt32 (length v) (withV withArray v)
368 compileAttr (VWordArray v) = Array ArrWord32 (length v) (withV withArray v)
369 --TODO: compileAttr (VBoolArray v) = Array ArrWord32 (length v) (withV withArray v)
370 (indexMap,arrays) = unzip [((n,i),compileAttr d) | (i,(n,d)) <- zip [0..] $ Map.toList $ streamData s]
371 getLength n = l `div` c
372 where
373 l = case Map.lookup n $ IR.streamData s of
374 Just (VFloatArray v) -> length v
375 Just (VIntArray v) -> length v
376 Just (VWordArray v) -> length v
377 _ -> error "compileStreamData - getLength"
378 c = case Map.lookup n $ IR.streamType s of
379 Just Bool -> 1
380 Just V2B -> 2
381 Just V3B -> 3
382 Just V4B -> 4
383 Just Word -> 1
384 Just V2U -> 2
385 Just V3U -> 3
386 Just V4U -> 4
387 Just Int -> 1
388 Just V2I -> 2
389 Just V3I -> 3
390 Just V4I -> 4
391 Just Float -> 1
392 Just V2F -> 2
393 Just V3F -> 3
394 Just V4F -> 4
395 Just M22F -> 4
396 Just M23F -> 6
397 Just M24F -> 8
398 Just M32F -> 6
399 Just M33F -> 9
400 Just M34F -> 12
401 Just M42F -> 8
402 Just M43F -> 12
403 Just M44F -> 16
404 _ -> error "compileStreamData - getLength element count"
405 buffer <- compileBuffer arrays
406 cmdRef <- newIORef []
407 let toStream (n,i) = (n,Stream
408 { streamType = fromJust $ toStreamType =<< Map.lookup n (IR.streamType s)
409 , streamBuffer = buffer
410 , streamArrIdx = i
411 , streamStart = 0
412 , streamLength = getLength n
413 })
414 return $ GLStream
415 { glStreamCommands = cmdRef
416 , glStreamPrimitive = case streamPrimitive s of
417 Points -> PointList
418 Lines -> LineList
419 Triangles -> TriangleList
420 LinesAdjacency -> LineListAdjacency
421 TrianglesAdjacency -> TriangleListAdjacency
422 , glStreamAttributes = toTrie $ Map.fromList $ map toStream indexMap
423 , glStreamProgram = head $ streamPrograms s
424 }
425
426createStreamCommands :: Trie (IORef GLint) -> Trie GLUniform -> Trie (Stream Buffer) -> Primitive -> GLProgram -> [GLObjectCommand]
427createStreamCommands texUnitMap topUnis attrs primitive prg = streamUniCmds ++ streamCmds ++ [drawCmd]
428 where
429 -- object draw command
430 drawCmd = GLDrawArrays prim 0 (fromIntegral count)
431 where
432 prim = primitiveToGLType primitive
433 count = head [c | Stream _ _ _ _ c <- T.elems attrs]
434
435 -- object uniform commands
436 -- texture slot setup commands
437 streamUniCmds = uniCmds ++ texCmds
438 where
439 uniCmds = [GLSetUniform i u | (n,i) <- uniMap, let u = topUni n]
440 uniMap = T.toList $ inputUniforms prg
441 topUni n = T.lookupWithDefault (error "internal error (createStreamCommands)!") n topUnis
442 texUnis = S.toList $ inputTextureUniforms prg
443 texCmds = [ GLBindTexture (inputTypeToTextureTarget $ uniInputType u) texUnit u
444 | n <- texUnis
445 , let u = topUni n
446 , let texUnit = T.lookupWithDefault (error "internal error (createStreamCommands - Texture Unit)") n texUnitMap
447 ]
448 uniInputType (GLUniform ty _) = ty
449
450 -- object attribute stream commands
451 streamCmds = [attrCmd i s | (i,name) <- T.elems attrMap, let Just s = T.lookup name attrs]
452 where
453 attrMap = inputStreams prg
454 attrCmd i s = case s of
455 Stream ty (Buffer arrs bo) arrIdx start len -> case ty of
456 TWord -> setIntAttrib 1
457 TV2U -> setIntAttrib 2
458 TV3U -> setIntAttrib 3
459 TV4U -> setIntAttrib 4
460 TInt -> setIntAttrib 1
461 TV2I -> setIntAttrib 2
462 TV3I -> setIntAttrib 3
463 TV4I -> setIntAttrib 4
464 TFloat -> setFloatAttrib 1
465 TV2F -> setFloatAttrib 2
466 TV3F -> setFloatAttrib 3
467 TV4F -> setFloatAttrib 4
468 TM22F -> setFloatAttrib 4
469 TM23F -> setFloatAttrib 6
470 TM24F -> setFloatAttrib 8
471 TM32F -> setFloatAttrib 6
472 TM33F -> setFloatAttrib 9
473 TM34F -> setFloatAttrib 12
474 TM42F -> setFloatAttrib 8
475 TM43F -> setFloatAttrib 12
476 TM44F -> setFloatAttrib 16
477 where
478 setFloatAttrib n = GLSetVertexAttribArray i bo n glType (ptr n)
479 setIntAttrib n = GLSetVertexAttribIArray i bo n glType (ptr n)
480 ArrayDesc arrType arrLen arrOffs arrSize = arrs ! arrIdx
481 glType = arrayTypeToGLType arrType
482 ptr compCnt = intPtrToPtr $! fromIntegral (arrOffs + start * fromIntegral compCnt * sizeOfArrayType arrType)
483
484 -- constant generic attribute
485 constAttr -> GLSetVertexAttrib i constAttr
486
354allocPipeline :: Pipeline -> IO GLPipeline 487allocPipeline :: Pipeline -> IO GLPipeline
355allocPipeline p = do 488allocPipeline p = do
356 let uniTrie = uniforms $ schemaFromPipeline p 489 let uniTrie = uniforms $ schemaFromPipeline p
@@ -364,6 +497,7 @@ allocPipeline p = do
364 input <- newIORef Nothing 497 input <- newIORef Nothing
365 -- default Vertex Array Object 498 -- default Vertex Array Object
366 vao <- alloca $! \pvao -> glGenVertexArrays 1 pvao >> peek pvao 499 vao <- alloca $! \pvao -> glGenVertexArrays 1 pvao >> peek pvao
500 strs <- V.mapM compileStreamData $ V.fromList $ streams p
367 return $ GLPipeline 501 return $ GLPipeline
368 { glPrograms = prgs 502 { glPrograms = prgs
369 , glTextures = texs 503 , glTextures = texs
@@ -375,6 +509,7 @@ allocPipeline p = do
375 , glSlotNames = V.map (pack . slotName) $ V.fromList $ IR.slots p 509 , glSlotNames = V.map (pack . slotName) $ V.fromList $ IR.slots p
376 , glVAO = vao 510 , glVAO = vao
377 , glTexUnitMapping = texUnitMapRefs 511 , glTexUnitMapping = texUnitMapRefs
512 , glStreams = strs
378 } 513 }
379 514
380disposePipeline :: GLPipeline -> IO () 515disposePipeline :: GLPipeline -> IO ()
@@ -503,6 +638,9 @@ setPipelineInput p input' = do
503 forM_ (IM.elems $ objectMap slot) $ \obj -> do 638 forM_ (IM.elems $ objectMap slot) $ \obj -> do
504 let cmdV = emptyV // [(prgIdx,createObjectCommands texUnitMap topUnis obj (progV ! prgIdx)) | prgIdx <- prgs] 639 let cmdV = emptyV // [(prgIdx,createObjectCommands texUnitMap topUnis obj (progV ! prgIdx)) | prgIdx <- prgs]
505 modifyIORef (objCommands obj) $ \v -> extend v // [(idx,cmdV)] 640 modifyIORef (objCommands obj) $ \v -> extend v // [(idx,cmdV)]
641 -- generate stream commands
642 V.forM_ (glStreams p) $ \s -> do
643 writeIORef (glStreamCommands s) $ createStreamCommands texUnitMap topUnis (glStreamAttributes s) (glStreamPrimitive s) (progV ! glStreamProgram s)
506{- 644{-
507 track state: 645 track state:
508 - render target 646 - render target
@@ -596,6 +734,8 @@ renderPipeline glp = do
596 GLSetTexture tu target tx -> glActiveTexture tu >> glBindTexture target tx 734 GLSetTexture tu target tx -> glActiveTexture tu >> glBindTexture target tx
597 GLClearRenderTarget vals -> clearRenderTarget vals 735 GLClearRenderTarget vals -> clearRenderTarget vals
598 GLGenerateMipMap tu target -> glActiveTexture tu >> glGenerateMipmap target 736 GLGenerateMipMap tu target -> glActiveTexture tu >> glGenerateMipmap target
737 GLRenderStream streamIdx progIdx -> do
738 renderSlot =<< readIORef (glStreamCommands $ glStreams glp ! streamIdx)
599 GLRenderSlot slotIdx progIdx -> do 739 GLRenderSlot slotIdx progIdx -> do
600 input <- readIORef (glInput glp) 740 input <- readIORef (glInput glp)
601 case input of 741 case input of
@@ -656,6 +796,9 @@ compileCommand texUnitMap samplers textures targets programs cmd = case cmd of
656 RenderSlot slot -> do 796 RenderSlot slot -> do
657 p <- currentProgram <$> get 797 p <- currentProgram <$> get
658 return $ GLRenderSlot slot p 798 return $ GLRenderSlot slot p
799 RenderStream stream -> do
800 p <- currentProgram <$> get
801 return $ GLRenderStream stream p
659 ClearRenderTarget vals -> return $ GLClearRenderTarget vals 802 ClearRenderTarget vals -> return $ GLClearRenderTarget vals
660 GenerateMipMap tu -> do 803 GenerateMipMap tu -> do
661 tb <- textureBinding <$> get 804 tb <- textureBinding <$> get
diff --git a/Backend/GL/Type.hs b/Backend/GL/Type.hs
index 80cba6d..db2ad1e 100644
--- a/Backend/GL/Type.hs
+++ b/Backend/GL/Type.hs
@@ -149,6 +149,14 @@ data InputConnection
149 , icSlotMapInputToPipeline :: Vector (Maybe SlotName) -- GLPipelineInput to GLPipeline slot name mapping 149 , icSlotMapInputToPipeline :: Vector (Maybe SlotName) -- GLPipelineInput to GLPipeline slot name mapping
150 } 150 }
151 151
152data GLStream
153 = GLStream
154 { glStreamCommands :: IORef [GLObjectCommand]
155 , glStreamPrimitive :: Primitive
156 , glStreamAttributes :: Trie (Stream Buffer)
157 , glStreamProgram :: ProgramName
158 }
159
152data GLPipeline 160data GLPipeline
153 = GLPipeline 161 = GLPipeline
154 { glPrograms :: Vector GLProgram 162 { glPrograms :: Vector GLProgram
@@ -161,6 +169,7 @@ data GLPipeline
161 , glSlotNames :: Vector ByteString 169 , glSlotNames :: Vector ByteString
162 , glVAO :: GLuint 170 , glVAO :: GLuint
163 , glTexUnitMapping :: Trie (IORef GLint) -- maps texture uniforms to texture units 171 , glTexUnitMapping :: Trie (IORef GLint) -- maps texture uniforms to texture units
172 , glStreams :: Vector GLStream
164 } 173 }
165 174
166data GLSampler 175data GLSampler
@@ -183,6 +192,7 @@ data GLCommand
183 | GLSetTexture !GLenum !GLuint !GLuint 192 | GLSetTexture !GLenum !GLuint !GLuint
184 | GLSetSampler !GLuint !GLuint 193 | GLSetSampler !GLuint !GLuint
185 | GLRenderSlot !SlotName !ProgramName 194 | GLRenderSlot !SlotName !ProgramName
195 | GLRenderStream !StreamName !ProgramName
186 | GLClearRenderTarget [(ImageSemantic,Value)] 196 | GLClearRenderTarget [(ImageSemantic,Value)]
187 | GLGenerateMipMap !GLenum !GLenum 197 | GLGenerateMipMap !GLenum !GLenum
188 | GLSaveImage FrameBufferComponent ImageRef -- from framebuffer component to texture (image) 198 | GLSaveImage FrameBufferComponent ImageRef -- from framebuffer component to texture (image)