diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,7 +1,12 @@
 # Changelog for spirv-reflect-ffi
 
+## [0.2] - 2022-09-04
+
+* Fixed a mess in input/output interface variables.
+
 ## [0.1] - 2022-09-04
 
 * Initial release.
 
 [0.1]: https://gitlab.com/dpwiz/spirv-reflect/-/tree/v0.1-ffi
+[0.2]: https://gitlab.com/dpwiz/spirv-reflect/-/tree/v0.2-ffi
diff --git a/lib/Data/SpirV/Reflect/FFI/Internal.chs b/lib/Data/SpirV/Reflect/FFI/Internal.chs
--- a/lib/Data/SpirV/Reflect/FFI/Internal.chs
+++ b/lib/Data/SpirV/Reflect/FFI/Internal.chs
@@ -1,9 +1,11 @@
 {-# LANGUAGE MagicHash #-}
+{-# LANGUAGE NamedFieldPuns #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
 module Data.SpirV.Reflect.FFI.Internal where
 
 import Data.Coerce (Coercible, coerce)
+import Data.List (sortOn)
 import Data.Text (Text)
 import Data.Text qualified as Text
 import Data.Vector (Vector)
@@ -123,27 +125,28 @@
       {#sizeof SpvReflectDescriptorSet #}
       inflateDescriptorSet
 
-  inputPtr <- {#get SpvReflectShaderModule->input_variables #} sm
-  input_variables <-
-    if inputPtr == nullPtr then
-      pure mempty
-    else
-      inflateVector
-        ({#get SpvReflectShaderModule->input_variable_count #} sm)
-        (peek inputPtr)
-        {#sizeof SpvReflectInterfaceVariable #}
-        inflateInterfaceVariable
+  interface_variables <-
+    inflateVector
+      ({#get SpvReflectShaderModule->interface_variable_count #} sm)
+      ({#get SpvReflectShaderModule->interface_variables #} sm)
+      {#sizeof SpvReflectInterfaceVariable #}
+      inflateInterfaceVariable
 
-  outputPtr <- {#get SpvReflectShaderModule->output_variables #} sm
-  output_variables <-
-    if outputPtr == nullPtr then
-      pure mempty
-    else
-      inflateVector
-        ({#get SpvReflectShaderModule->output_variable_count #} sm)
-        (peek outputPtr)
-        {#sizeof SpvReflectInterfaceVariable #}
-        inflateInterfaceVariable
+  let
+    ivLocation InterfaceVariable.InterfaceVariable{location} =
+      location
+
+    pickIvs query =
+      Vector.fromList . sortOn ivLocation . filter query $
+        Vector.toList interface_variables
+
+    input_variables =
+      pickIvs $
+        (== Enums.StorageClassInput) . InterfaceVariable.storage_class
+
+    output_variables =
+      pickIvs $
+        (== Enums.StorageClassOutput) . InterfaceVariable.storage_class
 
   push_constants <-
     inflateVector
diff --git a/spirv-reflect-ffi.cabal b/spirv-reflect-ffi.cabal
--- a/spirv-reflect-ffi.cabal
+++ b/spirv-reflect-ffi.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           spirv-reflect-ffi
-version:        0.1
+version:        0.2
 synopsis:       C-library loader for spirv-reflect tool.
 category:       Graphics
 author:         IC Rainbow
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -4,7 +4,7 @@
 
 import Control.Monad (guard)
 import System.Directory (doesDirectoryExist, listDirectory)
-import System.FilePath (splitExtensions, takeFileName, (</>))
+import System.FilePath (splitExtension, takeFileName, (</>))
 import Test.Tasty (TestTree, defaultMain, testGroup)
 import Test.Tasty.HUnit (testCase)
 
@@ -25,7 +25,7 @@
       let
         files = do
           filePath <- groupContents
-          case splitExtensions filePath of
+          case splitExtension filePath of
             (name, ".spv") ->
               pure
                 ( takeFileName name
@@ -48,8 +48,9 @@
   testCase name do
     -- putStrLn $ file <> " >>>>"
     !_loaded <- FFI.load file
+    -- writeFile (file <> "_ffi.hs") (show _loaded)
     pure ()
-    -- print loaded
+    -- print _loaded
     -- putStrLn $ file <> " <<<<"
 
 pattern UPSTREAM_PATH :: FilePath
