summaryrefslogtreecommitdiff
path: root/src/LambdaCube
diff options
context:
space:
mode:
Diffstat (limited to 'src/LambdaCube')
-rw-r--r--src/LambdaCube/GL/Backend.hs83
-rw-r--r--src/LambdaCube/GL/Type.hs11
-rw-r--r--src/LambdaCube/GL/Util.hs18
3 files changed, 85 insertions, 27 deletions
diff --git a/src/LambdaCube/GL/Backend.hs b/src/LambdaCube/GL/Backend.hs
index 324b3e6..0584a34 100644
--- a/src/LambdaCube/GL/Backend.hs
+++ b/src/LambdaCube/GL/Backend.hs
@@ -126,7 +126,7 @@ setupAccumulationContext (AccumulationContext n ops) = cvt ops
126 glDepthFunc $! comparisonFunctionToGLType df 126 glDepthFunc $! comparisonFunctionToGLType df
127 glDepthMask (cvtBool dm) 127 glDepthMask (cvtBool dm)
128 cvtC 0 xs 128 cvtC 0 xs
129 cvt xs = do 129 cvt xs = do
130 glDisable GL_DEPTH_TEST 130 glDisable GL_DEPTH_TEST
131 glDisable GL_STENCIL_TEST 131 glDisable GL_STENCIL_TEST
132 cvtC 0 xs 132 cvtC 0 xs
@@ -169,8 +169,8 @@ setupAccumulationContext (AccumulationContext n ops) = cvt ops
169 cvtBool True = 1 169 cvtBool True = 1
170 cvtBool False = 0 170 cvtBool False = 0
171 171
172clearRenderTarget :: [ClearImage] -> IO () 172clearRenderTarget :: GLRenderTarget -> [ClearImage] -> IO ()
173clearRenderTarget values = do 173clearRenderTarget GLRenderTarget{..} values = do
174 let setClearValue (m,i) value = case value of 174 let setClearValue (m,i) value = case value of
175 ClearImage Depth (VFloat v) -> do 175 ClearImage Depth (VFloat v) -> do
176 glDepthMask 1 176 glDepthMask 1
@@ -180,20 +180,46 @@ clearRenderTarget values = do
180 glClearStencil $ fromIntegral v 180 glClearStencil $ fromIntegral v
181 return (m .|. GL_STENCIL_BUFFER_BIT, i) 181 return (m .|. GL_STENCIL_BUFFER_BIT, i)
182 ClearImage Color c -> do 182 ClearImage Color c -> do
183 let (r,g,b,a) = case c of
184 VFloat r -> (realToFrac r, 0, 0, 1)
185 VV2F (V2 r g) -> (realToFrac r, realToFrac g, 0, 1)
186 VV3F (V3 r g b) -> (realToFrac r, realToFrac g, realToFrac b, 1)
187 VV4F (V4 r g b a) -> (realToFrac r, realToFrac g, realToFrac b, realToFrac a)
188 _ -> (0,0,0,1)
189 glColorMask 1 1 1 1 183 glColorMask 1 1 1 1
190 glClearColor r g b a 184 if framebufferObject == 0
191 return (m .|. GL_COLOR_BUFFER_BIT, i+1) 185 then
186 clearDefaultFB >>
187 pure (m .|. GL_COLOR_BUFFER_BIT, i+1)
188 else
189 clearFBColorAttachment >>
190 pure (m, i+1)
191 where
192 clearDefaultFB = do
193 let (r,g,b,a) = case c of
194 VFloat r -> (realToFrac r, 0, 0, 1)
195 VV2F (V2 r g) -> (realToFrac r, realToFrac g, 0, 1)
196 VV3F (V3 r g b) -> (realToFrac r, realToFrac g, realToFrac b, 1)
197 VV4F (V4 r g b a) -> (realToFrac r, realToFrac g, realToFrac b, realToFrac a)
198 _ -> (0,0,0,1)
199 glClearColor r g b a
200 clearFBColorAttachment = do
201 let buf = GL_COLOR
202 case c of -- there must be some clever way to extract the generality here, I'm sure..
203 VFloat r -> with (V4 r 0 0 1) $ glClearBufferfv buf i . castPtr
204 VV2F (V2 r g) -> with (V4 r g 0 1) $ glClearBufferfv buf i . castPtr
205 VV3F (V3 r g b) -> with (V4 r g b 1) $ glClearBufferfv buf i . castPtr
206 VV4F (V4 r g b a) -> with (V4 r g b a) $ glClearBufferfv buf i . castPtr
207
208 VInt r -> with (V4 r 0 0 1) $ glClearBufferiv buf i . castPtr
209 VV2I (V2 r g) -> with (V4 r g 0 1) $ glClearBufferiv buf i . castPtr
210 VV3I (V3 r g b) -> with (V4 r g b 1) $ glClearBufferiv buf i . castPtr
211 VV4I (V4 r g b a) -> with (V4 r g b a) $ glClearBufferiv buf i . castPtr
212
213 VWord r -> with (V4 r 0 0 1) $ glClearBufferiv buf i . castPtr
214 VV2U (V2 r g) -> with (V4 r g 0 1) $ glClearBufferiv buf i . castPtr
215 VV3U (V3 r g b) -> with (V4 r g b 1) $ glClearBufferiv buf i . castPtr
216 VV4U (V4 r g b a) -> with (V4 r g b a) $ glClearBufferiv buf i . castPtr
217 _ -> error $ "internal error: unsupported color attachment format: " <> show c
218
192 _ -> error "internal error (clearRenderTarget)" 219 _ -> error "internal error (clearRenderTarget)"
193 (mask,_) <- foldM setClearValue (0,0) values 220 (mask,_) <- foldM setClearValue (0,0) values
194 glClear $ fromIntegral mask 221 glClear $ fromIntegral mask
195 222
196
197printGLStatus = checkGL >>= print 223printGLStatus = checkGL >>= print
198printFBOStatus = checkFBO >>= print 224printFBOStatus = checkFBO >>= print
199 225
@@ -283,6 +309,15 @@ compileProgram p = do
283 , inputStreams = Map.fromList [(n,(idx, attrName)) | (n,idx) <- Map.toList $ attributes, let attrName = fromMaybe (error $ "missing attribute: " ++ n) $ Map.lookup n lcStreamName] 309 , inputStreams = Map.fromList [(n,(idx, attrName)) | (n,idx) <- Map.toList $ attributes, let attrName = fromMaybe (error $ "missing attribute: " ++ n) $ Map.lookup n lcStreamName]
284 } 310 }
285 311
312renderTargetOutputs :: Vector GLTexture -> RenderTarget -> GLRenderTarget -> [GLOutput]
313renderTargetOutputs glTexs (RenderTarget targetItems) (GLRenderTarget fbo bufs) =
314 let isFB (Framebuffer _) = True
315 isFB _ = False
316 images = [img | TargetItem _ (Just img) <- V.toList targetItems]
317 in case all isFB images of
318 True -> fromMaybe [] $ (GLOutputDrawBuffer fbo <$>) <$> bufs
319 False -> (\(TextureImage texIdx _ _)-> GLOutputRenderTexture fbo $ glTexs ! texIdx) <$> images
320
286compileRenderTarget :: Vector TextureDescriptor -> Vector GLTexture -> RenderTarget -> IO GLRenderTarget 321compileRenderTarget :: Vector TextureDescriptor -> Vector GLTexture -> RenderTarget -> IO GLRenderTarget
287compileRenderTarget texs glTexs (RenderTarget targets) = do 322compileRenderTarget texs glTexs (RenderTarget targets) = do
288 let isFB (Framebuffer _) = True 323 let isFB (Framebuffer _) = True
@@ -344,7 +379,7 @@ compileRenderTarget texs glTexs (RenderTarget targets) = do
344 | n > 1 -> attachArray 379 | n > 1 -> attachArray
345 | otherwise -> attach2D 380 | otherwise -> attach2D
346 TextureBuffer _ -> fail "internalError (compileRenderTarget/TextureBuffer)!" 381 TextureBuffer _ -> fail "internalError (compileRenderTarget/TextureBuffer)!"
347 382
348 go a (TargetItem Stencil (Just img)) = do 383 go a (TargetItem Stencil (Just img)) = do
349 fail "Stencil support is not implemented yet!" 384 fail "Stencil support is not implemented yet!"
350 return a 385 return a
@@ -453,7 +488,7 @@ createStreamCommands texUnitMap topUnis attrs primitive prg = streamUniCmds ++ s
453 488
454 -- object attribute stream commands 489 -- object attribute stream commands
455 streamCmds = [attrCmd i s | (i,name) <- Map.elems attrMap, let s = fromMaybe (error $ "missing attribute: " ++ name) $ Map.lookup name attrs] 490 streamCmds = [attrCmd i s | (i,name) <- Map.elems attrMap, let s = fromMaybe (error $ "missing attribute: " ++ name) $ Map.lookup name attrs]
456 where 491 where
457 attrMap = inputStreams prg 492 attrMap = inputStreams prg
458 attrCmd i s = case s of 493 attrCmd i s = case s of
459 Stream ty (Buffer arrs bo) arrIdx start len -> case ty of 494 Stream ty (Buffer arrs bo) arrIdx start len -> case ty of
@@ -488,16 +523,25 @@ createStreamCommands texUnitMap topUnis attrs primitive prg = streamUniCmds ++ s
488 -- constant generic attribute 523 -- constant generic attribute
489 constAttr -> GLSetVertexAttrib i constAttr 524 constAttr -> GLSetVertexAttrib i constAttr
490 525
526outputIsRenderTexture :: GLOutput -> Bool
527outputIsRenderTexture GLOutputRenderTexture{..} = True
528outputIsRenderTexture _ = False
529
491allocRenderer :: Pipeline -> IO GLRenderer 530allocRenderer :: Pipeline -> IO GLRenderer
492allocRenderer p = do 531allocRenderer p = do
493 smps <- V.mapM compileSampler $ samplers p 532 smps <- V.mapM compileSampler $ samplers p
494 texs <- V.mapM compileTexture $ textures p 533 texs <- V.mapM compileTexture $ textures p
495 trgs <- V.mapM (compileRenderTarget (textures p) texs) $ targets p 534 let cmds = V.toList $ commands p
535 finalRenderTargetIdx = head [i | SetRenderTarget i <- reverse $ cmds]
536 trgs <- traverse (compileRenderTarget (textures p) texs) $ targets p
537 let finalRenderTarget = targets p ! finalRenderTargetIdx
538 finalGLRenderTarget = trgs ! finalRenderTargetIdx
539 outs = renderTargetOutputs texs finalRenderTarget finalGLRenderTarget
496 prgs <- V.mapM compileProgram $ programs p 540 prgs <- V.mapM compileProgram $ programs p
497 -- texture unit mapping ioref trie 541 -- texture unit mapping ioref trie
498 -- texUnitMapRefs :: Map UniformName (IORef TextureUnit) 542 -- texUnitMapRefs :: Map UniformName (IORef TextureUnit)
499 texUnitMapRefs <- Map.fromList <$> mapM (\k -> (k,) <$> newIORef 0) (Set.toList $ Set.fromList $ concat $ V.toList $ V.map (Map.keys . programInTextures) $ programs p) 543 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 544 let st = execState (mapM_ (compileCommand texUnitMapRefs smps texs trgs prgs) cmds) initCGState
501 input <- newIORef Nothing 545 input <- newIORef Nothing
502 -- default Vertex Array Object 546 -- default Vertex Array Object
503 vao <- alloca $! \pvao -> glGenVertexArrays 1 pvao >> peek pvao 547 vao <- alloca $! \pvao -> glGenVertexArrays 1 pvao >> peek pvao
@@ -515,6 +559,7 @@ allocRenderer p = do
515 , glCommands = reverse $ drawCommands st 559 , glCommands = reverse $ drawCommands st
516 , glSlotPrograms = V.map (V.toList . slotPrograms) $ IR.slots p 560 , glSlotPrograms = V.map (V.toList . slotPrograms) $ IR.slots p
517 , glInput = input 561 , glInput = input
562 , glOutputs = outs
518 , glSlotNames = V.map slotName $ IR.slots p 563 , glSlotNames = V.map slotName $ IR.slots p
519 , glVAO = vao 564 , glVAO = vao
520 , glTexUnitMapping = texUnitMapRefs 565 , glTexUnitMapping = texUnitMapRefs
@@ -573,7 +618,7 @@ isSubTrie eqFun universe subset = and [isMember a (Map.lookup n universe) | (n,a
573 when (sPrim /= (primitiveToFetchPrimitive prim)) $ throw $ userError $ 618 when (sPrim /= (primitiveToFetchPrimitive prim)) $ throw $ userError $
574 "Primitive mismatch for slot (" ++ show slotName ++ ") expected " ++ show sPrim ++ " but got " ++ show prim 619 "Primitive mismatch for slot (" ++ show slotName ++ ") expected " ++ show sPrim ++ " but got " ++ show prim
575 let sType = fmap streamToStreamType attribs 620 let sType = fmap streamToStreamType attribs
576 when (sType /= sAttrs) $ throw $ userError $ unlines $ 621 when (sType /= sAttrs) $ throw $ userError $ unlines $
577 [ "Attribute stream mismatch for slot (" ++ show slotName ++ ") expected " 622 [ "Attribute stream mismatch for slot (" ++ show slotName ++ ") expected "
578 , show sAttrs 623 , show sAttrs
579 , " but got " 624 , " but got "
@@ -790,7 +835,7 @@ renderFrame GLRenderer{..} = do
790 case cmd of 835 case cmd of
791 GLClearRenderTarget rt vals -> do 836 GLClearRenderTarget rt vals -> do
792 setupRenderTarget glInput rt 837 setupRenderTarget glInput rt
793 clearRenderTarget vals 838 clearRenderTarget rt vals
794 modifyIORef glDrawContextRef $ \ctx -> ctx {glRenderTarget = rt} 839 modifyIORef glDrawContextRef $ \ctx -> ctx {glRenderTarget = rt}
795 840
796 GLRenderStream ctx streamIdx progIdx -> do 841 GLRenderStream ctx streamIdx progIdx -> do
@@ -895,4 +940,4 @@ compileCommand texUnitMap samplers textures targets programs cmd = case cmd of
895 case IM.lookup tu tb of 940 case IM.lookup tu tb of
896 Nothing -> fail "internal error (GenerateMipMap)!" 941 Nothing -> fail "internal error (GenerateMipMap)!"
897 Just tex -> return $ GLGenerateMipMap (GL_TEXTURE0 + fromIntegral tu) (glTextureTarget tex) 942 Just tex -> return $ GLGenerateMipMap (GL_TEXTURE0 + fromIntegral tu) (glTextureTarget tex)
898-} \ No newline at end of file 943-}
diff --git a/src/LambdaCube/GL/Type.hs b/src/LambdaCube/GL/Type.hs
index 49491ed..bd3f827 100644
--- a/src/LambdaCube/GL/Type.hs
+++ b/src/LambdaCube/GL/Type.hs
@@ -152,6 +152,7 @@ data GLRenderer
152 , glTextures :: Vector GLTexture 152 , glTextures :: Vector GLTexture
153 , glSamplers :: Vector GLSampler 153 , glSamplers :: Vector GLSampler
154 , glTargets :: Vector GLRenderTarget 154 , glTargets :: Vector GLRenderTarget
155 , glOutputs :: [GLOutput]
155 , glCommands :: [GLCommand] 156 , glCommands :: [GLCommand]
156 , glSlotPrograms :: Vector [ProgramName] -- programs depend on a slot 157 , glSlotPrograms :: Vector [ProgramName] -- programs depend on a slot
157 , glInput :: IORef (Maybe InputConnection) 158 , glInput :: IORef (Maybe InputConnection)
@@ -177,6 +178,16 @@ data GLRenderTarget
177 , framebufferDrawbuffers :: Maybe [GLenum] 178 , framebufferDrawbuffers :: Maybe [GLenum]
178 } deriving Eq 179 } deriving Eq
179 180
181data GLOutput
182 = GLOutputDrawBuffer
183 { glOutputFBO :: GLuint
184 , glOutputDrawBuffer :: GLenum
185 }
186 | GLOutputRenderTexture
187 { glOutputFBO :: GLuint
188 , glOutputRenderTexture :: GLTexture
189 }
190
180type GLTextureUnit = Int 191type GLTextureUnit = Int
181type GLUniformBinding = GLint 192type GLUniformBinding = GLint
182 193
diff --git a/src/LambdaCube/GL/Util.hs b/src/LambdaCube/GL/Util.hs
index bba322b..b267c7f 100644
--- a/src/LambdaCube/GL/Util.hs
+++ b/src/LambdaCube/GL/Util.hs
@@ -403,6 +403,8 @@ blendingFactorToGLType a = case a of
403 SrcColor -> GL_SRC_COLOR 403 SrcColor -> GL_SRC_COLOR
404 Zero -> GL_ZERO 404 Zero -> GL_ZERO
405 405
406-- XXX: we need to extend IR.TextureDescriptor to carry component bit depth
407-- if we want to avoid making arbitrary decisions here
406textureDataTypeToGLType :: ImageSemantic -> TextureDataType -> GLenum 408textureDataTypeToGLType :: ImageSemantic -> TextureDataType -> GLenum
407textureDataTypeToGLType Color a = case a of 409textureDataTypeToGLType Color a = case a of
408 FloatT Red -> GL_R32F 410 FloatT Red -> GL_R32F
@@ -412,8 +414,8 @@ textureDataTypeToGLType Color a = case a of
412 IntT RG -> GL_RG32I 414 IntT RG -> GL_RG32I
413 WordT RG -> GL_RG32UI 415 WordT RG -> GL_RG32UI
414 FloatT RGBA -> GL_RGBA32F 416 FloatT RGBA -> GL_RGBA32F
415 IntT RGBA -> GL_RGBA32I 417 IntT RGBA -> GL_RGBA8I
416 WordT RGBA -> GL_RGBA32UI 418 WordT RGBA -> GL_RGBA8UI
417 a -> error $ "FIXME: This texture format is not yet supported" ++ show a 419 a -> error $ "FIXME: This texture format is not yet supported" ++ show a
418textureDataTypeToGLType Depth a = case a of 420textureDataTypeToGLType Depth a = case a of
419 FloatT Red -> GL_DEPTH_COMPONENT32F 421 FloatT Red -> GL_DEPTH_COMPONENT32F
@@ -425,14 +427,14 @@ textureDataTypeToGLType Stencil a = case a of
425textureDataTypeToGLArityType :: ImageSemantic -> TextureDataType -> GLenum 427textureDataTypeToGLArityType :: ImageSemantic -> TextureDataType -> GLenum
426textureDataTypeToGLArityType Color a = case a of 428textureDataTypeToGLArityType Color a = case a of
427 FloatT Red -> GL_RED 429 FloatT Red -> GL_RED
428 IntT Red -> GL_RED 430 IntT Red -> GL_RED_INTEGER
429 WordT Red -> GL_RED 431 WordT Red -> GL_RED_INTEGER
430 FloatT RG -> GL_RG 432 FloatT RG -> GL_RG
431 IntT RG -> GL_RG 433 IntT RG -> GL_RG_INTEGER
432 WordT RG -> GL_RG 434 WordT RG -> GL_RG_INTEGER
433 FloatT RGBA -> GL_RGBA 435 FloatT RGBA -> GL_RGBA
434 IntT RGBA -> GL_RGBA 436 IntT RGBA -> GL_RGBA_INTEGER
435 WordT RGBA -> GL_RGBA 437 WordT RGBA -> GL_RGBA_INTEGER
436 a -> error $ "FIXME: This texture format is not yet supported" ++ show a 438 a -> error $ "FIXME: This texture format is not yet supported" ++ show a
437textureDataTypeToGLArityType Depth a = case a of 439textureDataTypeToGLArityType Depth a = case a of
438 FloatT Red -> GL_DEPTH_COMPONENT 440 FloatT Red -> GL_DEPTH_COMPONENT