diff options
author | Csaba Hruska <csaba.hruska@gmail.com> | 2015-06-09 11:34:57 +0100 |
---|---|---|
committer | Csaba Hruska <csaba.hruska@gmail.com> | 2015-06-09 11:34:57 +0100 |
commit | 4efa8405bd9eeec3c16bd8dd92cc5e7b66f8a3ae (patch) | |
tree | b7703f8578eb35f00554e884e13216700147a0bc /Backend | |
parent | 23747de92cb2883e3a0ce97805e354ea502378fc (diff) |
support for immediate stream data
Diffstat (limited to 'Backend')
-rw-r--r-- | Backend/GL/Backend.hs | 153 | ||||
-rw-r--r-- | Backend/GL/Type.hs | 10 |
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 | |||
8 | import Data.ByteString.Char8 (ByteString,pack) | 8 | import Data.ByteString.Char8 (ByteString,pack) |
9 | import Data.IORef | 9 | import Data.IORef |
10 | import Data.IntMap (IntMap) | 10 | import Data.IntMap (IntMap) |
11 | import Data.Maybe (isNothing) | 11 | import Data.Maybe (isNothing,fromJust) |
12 | import Data.Set (Set) | 12 | import Data.Set (Set) |
13 | import Data.Trie as T | 13 | import Data.Trie as T |
14 | import Data.Trie.Convenience as T | ||
14 | import Data.Vector (Vector,(!),(//)) | 15 | import Data.Vector (Vector,(!),(//)) |
15 | import qualified Data.ByteString.Char8 as SB | 16 | import qualified Data.ByteString.Char8 as SB |
16 | import qualified Data.Foldable as F | 17 | import qualified Data.Foldable as F |
@@ -25,11 +26,13 @@ import Graphics.Rendering.OpenGL.Raw.Core33 | |||
25 | import Foreign | 26 | import Foreign |
26 | 27 | ||
27 | -- LC IR imports | 28 | -- LC IR imports |
28 | import IR as IR | 29 | import IR hiding (streamType) |
30 | import qualified IR as IR | ||
29 | 31 | ||
30 | import Backend.GL.Type | 32 | import Backend.GL.Type |
31 | import Backend.GL.Util | 33 | import Backend.GL.Util |
32 | 34 | ||
35 | import Backend.GL.Data | ||
33 | import Backend.GL.Input | 36 | import Backend.GL.Input |
34 | 37 | ||
35 | setupRasterContext :: RasterContext -> IO () | 38 | setupRasterContext :: 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 | ||
363 | compileStreamData :: StreamData -> IO GLStream | ||
364 | compileStreamData 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 | |||
426 | createStreamCommands :: Trie (IORef GLint) -> Trie GLUniform -> Trie (Stream Buffer) -> Primitive -> GLProgram -> [GLObjectCommand] | ||
427 | createStreamCommands 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 | |||
354 | allocPipeline :: Pipeline -> IO GLPipeline | 487 | allocPipeline :: Pipeline -> IO GLPipeline |
355 | allocPipeline p = do | 488 | allocPipeline 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 | ||
380 | disposePipeline :: GLPipeline -> IO () | 515 | disposePipeline :: 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 | ||
152 | data GLStream | ||
153 | = GLStream | ||
154 | { glStreamCommands :: IORef [GLObjectCommand] | ||
155 | , glStreamPrimitive :: Primitive | ||
156 | , glStreamAttributes :: Trie (Stream Buffer) | ||
157 | , glStreamProgram :: ProgramName | ||
158 | } | ||
159 | |||
152 | data GLPipeline | 160 | data 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 | ||
166 | data GLSampler | 175 | data 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) |