diff options
Diffstat (limited to 'src/LambdaCube/GL/Backend.hs')
-rw-r--r-- | src/LambdaCube/GL/Backend.hs | 56 |
1 files changed, 23 insertions, 33 deletions
diff --git a/src/LambdaCube/GL/Backend.hs b/src/LambdaCube/GL/Backend.hs index 712f357..499498e 100644 --- a/src/LambdaCube/GL/Backend.hs +++ b/src/LambdaCube/GL/Backend.hs | |||
@@ -13,10 +13,10 @@ import Data.Map (Map) | |||
13 | import Data.Set (Set) | 13 | import Data.Set (Set) |
14 | import Data.Vector (Vector,(!),(//)) | 14 | import Data.Vector (Vector,(!),(//)) |
15 | import qualified Data.Foldable as F | 15 | import qualified Data.Foldable as F |
16 | import qualified Data.IntMap as IM | 16 | import qualified Data.IntMap as IntMap |
17 | import qualified Data.Map as Map | 17 | import qualified Data.Map as Map |
18 | import qualified Data.List as L | 18 | import qualified Data.List as L |
19 | import qualified Data.Set as S | 19 | import qualified Data.Set as Set |
20 | import qualified Data.Vector as V | 20 | import qualified Data.Vector as V |
21 | import qualified Data.Vector.Storable as SV | 21 | import qualified Data.Vector.Storable as SV |
22 | 22 | ||
@@ -279,7 +279,7 @@ compileProgram p = do | |||
279 | , programObject = po | 279 | , programObject = po |
280 | , inputUniforms = Map.fromList inUniforms | 280 | , inputUniforms = Map.fromList inUniforms |
281 | , inputTextures = Map.fromList inTextures | 281 | , inputTextures = Map.fromList inTextures |
282 | , inputTextureUniforms = S.fromList $ texUnis | 282 | , inputTextureUniforms = Set.fromList $ texUnis |
283 | , inputStreams = Map.fromList [(n,(idx, attrName)) | (n,idx) <- Map.toList $ attributes, let attrName = fromMaybe (error $ "missing attribute: " ++ n) $ Map.lookup n lcStreamName] | 283 | , inputStreams = Map.fromList [(n,(idx, attrName)) | (n,idx) <- Map.toList $ attributes, let attrName = fromMaybe (error $ "missing attribute: " ++ n) $ Map.lookup n lcStreamName] |
284 | } | 284 | } |
285 | 285 | ||
@@ -443,7 +443,7 @@ createStreamCommands texUnitMap topUnis attrs primitive prg = streamUniCmds ++ s | |||
443 | uniCmds = [GLSetUniform i u | (n,i) <- uniMap, let u = topUni n] | 443 | uniCmds = [GLSetUniform i u | (n,i) <- uniMap, let u = topUni n] |
444 | uniMap = Map.toList $ inputUniforms prg | 444 | uniMap = Map.toList $ inputUniforms prg |
445 | topUni n = Map.findWithDefault (error "internal error (createStreamCommands)!") n topUnis | 445 | topUni n = Map.findWithDefault (error "internal error (createStreamCommands)!") n topUnis |
446 | texUnis = S.toList $ inputTextureUniforms prg | 446 | texUnis = Set.toList $ inputTextureUniforms prg |
447 | texCmds = [ GLBindTexture (inputTypeToTextureTarget $ uniInputType u) texUnit u | 447 | texCmds = [ GLBindTexture (inputTypeToTextureTarget $ uniInputType u) texUnit u |
448 | | n <- texUnis | 448 | | n <- texUnis |
449 | , let u = topUni n | 449 | , let u = topUni n |
@@ -496,7 +496,7 @@ allocRenderer p = do | |||
496 | prgs <- V.mapM compileProgram $ programs p | 496 | prgs <- V.mapM compileProgram $ programs p |
497 | -- texture unit mapping ioref trie | 497 | -- texture unit mapping ioref trie |
498 | -- texUnitMapRefs :: Map UniformName (IORef TextureUnit) | 498 | -- texUnitMapRefs :: Map UniformName (IORef TextureUnit) |
499 | texUnitMapRefs <- Map.fromList <$> mapM (\k -> (k,) <$> newIORef 0) (S.toList $ S.fromList $ concat $ V.toList $ V.map (Map.keys . programInTextures) $ programs p) | 499 | texUnitMapRefs <- Map.fromList <$> mapM (\k -> (k,) <$> newIORef 0) (Set.toList $ Set.fromList $ concat $ V.toList $ V.map (Map.keys . programInTextures) $ programs p) |
500 | let st = execState (mapM_ (compileCommand texUnitMapRefs smps texs trgs prgs) (V.toList $ commands p)) initCGState | 500 | let st = execState (mapM_ (compileCommand texUnitMapRefs smps texs trgs prgs) (V.toList $ commands p)) initCGState |
501 | input <- newIORef Nothing | 501 | input <- newIORef Nothing |
502 | -- default Vertex Array Object | 502 | -- default Vertex Array Object |
@@ -602,7 +602,7 @@ setStorage' p@GLRenderer{..} input' = do | |||
602 | modifyIORef (pipelines icInput) $ \v -> v // [(icId,Nothing)] | 602 | modifyIORef (pipelines icInput) $ \v -> v // [(icId,Nothing)] |
603 | V.forM_ icSlotMapPipelineToInput $ \slotIdx -> do | 603 | V.forM_ icSlotMapPipelineToInput $ \slotIdx -> do |
604 | slot <- readIORef (slotRefs ! slotIdx) | 604 | slot <- readIORef (slotRefs ! slotIdx) |
605 | forM_ (IM.elems $ objectMap slot) $ \obj -> do | 605 | forM_ (objectMap slot) $ \obj -> do |
606 | modifyIORef (objCommands obj) $ \v -> v // [(icId,V.empty)] | 606 | modifyIORef (objCommands obj) $ \v -> v // [(icId,V.empty)] |
607 | {- | 607 | {- |
608 | addition: | 608 | addition: |
@@ -649,7 +649,7 @@ setStorage' p@GLRenderer{..} input' = do | |||
649 | Just l -> V.concat [v,V.replicate l V.empty] | 649 | Just l -> V.concat [v,V.replicate l V.empty] |
650 | V.forM_ (V.zip pToI glSlotPrograms) $ \(slotIdx,prgs) -> do | 650 | V.forM_ (V.zip pToI glSlotPrograms) $ \(slotIdx,prgs) -> do |
651 | slot <- readIORef $ slotV ! slotIdx | 651 | slot <- readIORef $ slotV ! slotIdx |
652 | forM_ (IM.elems $ objectMap slot) $ \obj -> do | 652 | forM_ (objectMap slot) $ \obj -> do |
653 | let cmdV = emptyV // [(prgIdx,createObjectCommands glTexUnitMapping topUnis obj (progV ! prgIdx)) | prgIdx <- prgs] | 653 | let cmdV = emptyV // [(prgIdx,createObjectCommands glTexUnitMapping topUnis obj (progV ! prgIdx)) | prgIdx <- prgs] |
654 | modifyIORef (objCommands obj) $ \v -> extend v // [(idx,cmdV)] | 654 | modifyIORef (objCommands obj) $ \v -> extend v // [(idx,cmdV)] |
655 | -- generate stream commands | 655 | -- generate stream commands |
@@ -817,21 +817,19 @@ renderFrame GLRenderer{..} = do | |||
817 | 817 | ||
818 | data CGState | 818 | data CGState |
819 | = CGState | 819 | = CGState |
820 | { textureBinding :: IntMap GLTexture | 820 | { drawCommands :: [GLCommand] |
821 | , drawCommands :: [GLCommand] | ||
822 | -- draw context data | 821 | -- draw context data |
823 | , rasterContext :: RasterContext | 822 | , rasterContext :: RasterContext |
824 | , accumulationContext :: AccumulationContext | 823 | , accumulationContext :: AccumulationContext |
825 | , renderTarget :: GLRenderTarget | 824 | , renderTarget :: GLRenderTarget |
826 | , currentProgram :: ProgramName | 825 | , currentProgram :: ProgramName |
827 | , samplerUniformMapping :: [(GLTextureUnit,GLSamplerUniform)] | 826 | , samplerUniformMapping :: IntMap GLSamplerUniform |
828 | , textureMapping :: [(GLTextureUnit,GLTexture)] | 827 | , textureMapping :: IntMap GLTexture |
829 | , samplerMapping :: [(GLTextureUnit,GLSampler)] | 828 | , samplerMapping :: IntMap GLSampler |
830 | } | 829 | } |
831 | 830 | ||
832 | initCGState = CGState | 831 | initCGState = CGState |
833 | { textureBinding = mempty | 832 | { drawCommands = mempty |
834 | , drawCommands = mempty | ||
835 | -- draw context data | 833 | -- draw context data |
836 | , rasterContext = error "compileCommand: missing RasterContext" | 834 | , rasterContext = error "compileCommand: missing RasterContext" |
837 | , accumulationContext = error "compileCommand: missing AccumulationContext" | 835 | , accumulationContext = error "compileCommand: missing AccumulationContext" |
@@ -847,40 +845,32 @@ type CG a = State CGState a | |||
847 | emit :: GLCommand -> CG () | 845 | emit :: GLCommand -> CG () |
848 | emit cmd = modify $ \s -> s {drawCommands = cmd : drawCommands s} | 846 | emit cmd = modify $ \s -> s {drawCommands = cmd : drawCommands s} |
849 | 847 | ||
850 | drawContext programs = | 848 | drawContext programs = do |
849 | GLProgram{..} <- (programs !) <$> gets currentProgram | ||
850 | let f = take (Set.size inputTextureUniforms) . IntMap.toList | ||
851 | GLDrawContext <$> gets rasterContext | 851 | GLDrawContext <$> gets rasterContext |
852 | <*> gets accumulationContext | 852 | <*> gets accumulationContext |
853 | <*> gets renderTarget | 853 | <*> gets renderTarget |
854 | <*> gets (programObject . (programs !) . currentProgram) | 854 | <*> pure programObject |
855 | <*> gets textureMapping | 855 | <*> gets (f . textureMapping) |
856 | <*> gets samplerMapping | 856 | <*> gets (f . samplerMapping) |
857 | <*> gets samplerUniformMapping | 857 | <*> gets (f . samplerUniformMapping) |
858 | 858 | ||
859 | compileCommand :: Map String (IORef GLint) -> Vector GLSampler -> Vector GLTexture -> Vector GLRenderTarget -> Vector GLProgram -> Command -> CG () | 859 | compileCommand :: Map String (IORef GLint) -> Vector GLSampler -> Vector GLTexture -> Vector GLRenderTarget -> Vector GLProgram -> Command -> CG () |
860 | compileCommand texUnitMap samplers textures targets programs cmd = case cmd of | 860 | compileCommand texUnitMap samplers textures targets programs cmd = case cmd of |
861 | SetRasterContext rCtx -> modify $ \s -> s {rasterContext = rCtx} | 861 | SetRasterContext rCtx -> modify $ \s -> s {rasterContext = rCtx} |
862 | SetAccumulationContext aCtx -> modify $ \s -> s {accumulationContext = aCtx} | 862 | SetAccumulationContext aCtx -> modify $ \s -> s {accumulationContext = aCtx} |
863 | SetRenderTarget rt -> modify $ \s -> s {renderTarget = targets ! rt} | 863 | SetRenderTarget rt -> modify $ \s -> s {renderTarget = targets ! rt} |
864 | SetProgram p -> modify $ \s -> s | 864 | SetProgram p -> modify $ \s -> s {currentProgram = p} |
865 | { currentProgram = p | ||
866 | , samplerUniformMapping = mempty | ||
867 | , textureMapping = mempty | ||
868 | , samplerMapping = mempty | ||
869 | } | ||
870 | SetSamplerUniform n tu -> do | 865 | SetSamplerUniform n tu -> do |
871 | p <- currentProgram <$> get | 866 | p <- currentProgram <$> get |
872 | case Map.lookup n (inputTextures $ programs ! p) of | 867 | case Map.lookup n (inputTextures $ programs ! p) of |
873 | Nothing -> return () -- TODO: some drivers does heavy cross stage (vertex/fragment) dead code elimination; fail $ "internal error (SetSamplerUniform)! - " ++ show cmd | 868 | Nothing -> return () -- TODO: some drivers does heavy cross stage (vertex/fragment) dead code elimination; fail $ "internal error (SetSamplerUniform)! - " ++ show cmd |
874 | Just i -> case Map.lookup n texUnitMap of | 869 | Just i -> case Map.lookup n texUnitMap of |
875 | Nothing -> fail $ "internal error (SetSamplerUniform - IORef)! - " ++ show cmd | 870 | Nothing -> fail $ "internal error (SetSamplerUniform - IORef)! - " ++ show cmd |
876 | Just r -> modify $ \s -> s {samplerUniformMapping = (tu, GLSamplerUniform i r) : samplerUniformMapping s} | 871 | Just r -> modify $ \s -> s {samplerUniformMapping = IntMap.insert tu (GLSamplerUniform i r) $ samplerUniformMapping s} |
877 | SetTexture tu t -> do | 872 | SetTexture tu t -> modify $ \s -> s {textureMapping = IntMap.insert tu (textures ! t) $ textureMapping s} |
878 | let tex = textures ! t | 873 | SetSampler tu i -> modify $ \s -> s {samplerMapping = IntMap.insert tu (maybe (GLSampler 0) (samplers !) i) $ samplerMapping s} |
879 | modify $ \s -> s | ||
880 | { textureBinding = IM.insert tu tex $ textureBinding s | ||
881 | , textureMapping = (tu, tex) : textureMapping s | ||
882 | } | ||
883 | SetSampler tu i -> modify $ \s -> s {samplerMapping = (tu, maybe (GLSampler 0) (samplers !) i) : samplerMapping s} | ||
884 | 874 | ||
885 | -- draw commands | 875 | -- draw commands |
886 | RenderSlot slot -> do | 876 | RenderSlot slot -> do |