packages feed

spirv-reflect-ffi-0.1: lib/Data/SpirV/Reflect/FFI.hs

module Data.SpirV.Reflect.FFI
  ( Module
  , load
  , loadBytes
  ) where

import Control.Exception (finally)
import Control.Monad.IO.Class (MonadIO(..))
import Data.ByteString (ByteString)
import Data.ByteString qualified as ByteString
import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
import Data.SpirV.Reflect.FFI.Internal qualified as C
import Foreign (allocaBytes, castPtr)

import Data.SpirV.Reflect.Module (Module)

load :: MonadIO io => FilePath -> io Module
load path = liftIO $
  ByteString.readFile path >>= loadBytes

loadBytes :: MonadIO io => ByteString -> io Module
loadBytes bytes = liftIO do
  unsafeUseAsCStringLen bytes \(code, size) -> do
    allocaBytes C.shaderModuleSize \smPtr -> do
      res <- C.createShaderModule2
        C.SpvReflectModuleFlagNoCopy
        (fromIntegral size)
        (castPtr code)
        smPtr
      case res of
        C.SpvReflectResultSuccess ->
          C.inflateModule smPtr `finally` C.destroyShaderModule smPtr
        err ->
          error $ "spvReflectCreateShaderModule2:" <> show err