Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The 'while' function doesn’t generate correct GLSL code #75

Open
Chatanga opened this issue Nov 3, 2020 · 2 comments
Open

The 'while' function doesn’t generate correct GLSL code #75

Chatanga opened this issue Nov 3, 2020 · 2 comments

Comments

@Chatanga
Copy link

Chatanga commented Nov 3, 2020

See for yourself:

withNewline s = s ++ "\n"

test_while :: IO ()
test_while = do
    let
        total :: VInt
        total = snd $ while
            (\(i, _) -> i <* 3)
            (\(i, n) -> (i + 1, 10 * i + n))
            (0, 1)

        decls = tellGlobalLn "// hello"

        shaderExpr = unS total >> return ()

    -- The last two values aren’t meant to be evaluated (will trip over an
    -- undefined value otherwise) since there is no previous stage here.
    (source, unis, samps, inps, _, _) <- runExprM decls shaderExpr

    assertEqual
        (concatMap withNewline
            [ "#version 450"
            , "// hello;"
            , "void main() {"
            , "int t0;"
            , "int t1;"
            , "t0 = 0;" -- i <- 0
            , "t1 = 1;" -- n <- 1
            , "bool t2 = (0<3);"
            , "bool t3 = t2;"
            , "while(t3){"
            , "int t4 = (t0+1);" -- i = i + 1
            , "t0 = t4;" -- How to move this assignment THERE?
            , "int t5 = (10*t0);" -- Bug: variable 'i' (t0) has already been incremented.
            , "int t6 = (t5+t1);" -- n = 10 * i + n
            , "t1 = t6;" -- The last assignment is already THERE.
            -- THERE
            , "bool t7 = (t4<3);"
            , "t3 = t7;"
            , "}"
            , "}"
            ])
        source

Working around this issue is easy, but the resulting code obviously doesn’t look right from the Haskell side.

@Chatanga
Copy link
Author

Chatanga commented May 7, 2021

The culprit function with a "Bug" comment near the problematic part. If someone has any idea to fix this problem (which, by design, seems specific to this only place where GPipe creates a loop), I would be happy to hear it!

while :: forall a x. (ShaderType a x) => (a -> S x Bool) -> (a -> a) -> a -> a
while c f i = fromBase x $ while_ (c . fromBase x) (toBase x . f . fromBase x) (toBase x i)
    where
        x = undefined :: x
        while_
            :: (ShaderBase (ShaderBaseType a) x -> S x Bool)
            -> (ShaderBase (ShaderBaseType a) x -> ShaderBase (ShaderBaseType a) x)
            ->  ShaderBase (ShaderBaseType a) x -> ShaderBase (ShaderBaseType a) x
        while_ bool loopF a =
            let whileM = memoizeM $ do
                    (lifted, decls) <- runWriterT $ shaderbaseDeclare (toBase x (errShaderType :: a))
                    void $ evalStateT (shaderbaseAssign a) decls
                    boolDecl <- tellAssignment STypeBool (unS $ bool a)
                    T.lift $ T.lift $ tell $ mconcat ["while(", boolDecl, "){\n" ]
                    let looped = loopF lifted

                    scopedM $ do
                        -- Bug: reassigning back to the same var (in decls) breaks the functional referential transparency.
                        void $ evalStateT (shaderbaseAssign looped) decls
                        loopedBoolStr <- unS $ bool looped
                        tellAssignment' boolDecl loopedBoolStr

                    T.lift $ T.lift $ tell "}\n"
                    return decls
            in  evalState (runReaderT (shaderbaseReturn (toBase x (errShaderType :: a))) whileM) 0

@Chatanga
Copy link
Author

Chatanga commented May 8, 2021

I've ended up with this solution to fix the issue:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant