module Mischief.WGPU.Framework where

import Data.ByteString (ByteString)
import Data.ByteString qualified as BS
import Foreign (with)
import Foreign.C.ConstPtr (ConstPtr (ConstPtr))
import Foreign.Ptr
import Mischief.WGPU
import Mischief.WGPU.Opaque
import Mischief.WGPU.Types.Enums
import Mischief.WGPU.Types.General

loadShaderModule :: Ptr WGPUDevice -> String -> IO (Ptr WGPUShaderModule)
loadShaderModule :: Ptr WGPUDevice -> String -> IO (Ptr WGPUShaderModule)
loadShaderModule Ptr WGPUDevice
device String
path = do
  bytes <- String -> IO ByteString
BS.readFile String
path
  loadShaderFromBytes device bytes

loadShaderFromBytes :: Ptr WGPUDevice -> ByteString -> IO (Ptr WGPUShaderModule)
loadShaderFromBytes :: Ptr WGPUDevice -> ByteString -> IO (Ptr WGPUShaderModule)
loadShaderFromBytes Ptr WGPUDevice
device ByteString
bytes = ByteString
-> (WGPUStringView -> IO (Ptr WGPUShaderModule))
-> IO (Ptr WGPUShaderModule)
forall a. ByteString -> (WGPUStringView -> IO a) -> IO a
bsAsWGPUString ByteString
bytes ((WGPUStringView -> IO (Ptr WGPUShaderModule))
 -> IO (Ptr WGPUShaderModule))
-> (WGPUStringView -> IO (Ptr WGPUShaderModule))
-> IO (Ptr WGPUShaderModule)
forall a b. (a -> b) -> a -> b
$ \WGPUStringView
shaderString -> do
  let shaderSource :: WGPUShaderSourceWGSL
shaderSource =
        WGPUShaderSourceWGSL
          { chain :: WGPUChainedStruct
chain = WGPUChainedStruct {sType :: WGPUSType
sType = WGPUSType
wGPUSType_ShaderSourceWGSL, next :: Ptr WGPUChainedStruct
next = Ptr WGPUChainedStruct
forall a. Ptr a
nullPtr},
            code :: WGPUStringView
code = WGPUStringView
shaderString
          }

  WGPUShaderSourceWGSL
-> (Ptr WGPUShaderSourceWGSL -> IO (Ptr WGPUShaderModule))
-> IO (Ptr WGPUShaderModule)
forall a b. Storable a => a -> (Ptr a -> IO b) -> IO b
with WGPUShaderSourceWGSL
shaderSource ((Ptr WGPUShaderSourceWGSL -> IO (Ptr WGPUShaderModule))
 -> IO (Ptr WGPUShaderModule))
-> (Ptr WGPUShaderSourceWGSL -> IO (Ptr WGPUShaderModule))
-> IO (Ptr WGPUShaderModule)
forall a b. (a -> b) -> a -> b
$ \Ptr WGPUShaderSourceWGSL
shaderSource -> do
    let desc :: WGPUShaderModuleDescriptor
desc =
          WGPUShaderModuleDescriptor
            { label :: WGPUStringView
label = WGPUStringView {_data :: ConstPtr CChar
_data = Ptr CChar -> ConstPtr CChar
forall a. Ptr a -> ConstPtr a
ConstPtr Ptr CChar
forall a. Ptr a
nullPtr, length :: Int
length = Int
0},
              nextInChain :: Ptr WGPUChainedStruct
nextInChain = Ptr WGPUShaderSourceWGSL -> Ptr WGPUChainedStruct
forall a b. Ptr a -> Ptr b
castPtr Ptr WGPUShaderSourceWGSL
shaderSource
            }

    WGPUShaderModuleDescriptor
-> (Ptr WGPUShaderModuleDescriptor -> IO (Ptr WGPUShaderModule))
-> IO (Ptr WGPUShaderModule)
forall a b. Storable a => a -> (Ptr a -> IO b) -> IO b
with WGPUShaderModuleDescriptor
desc ((Ptr WGPUShaderModuleDescriptor -> IO (Ptr WGPUShaderModule))
 -> IO (Ptr WGPUShaderModule))
-> (Ptr WGPUShaderModuleDescriptor -> IO (Ptr WGPUShaderModule))
-> IO (Ptr WGPUShaderModule)
forall a b. (a -> b) -> a -> b
$ \Ptr WGPUShaderModuleDescriptor
desc -> do
      Ptr WGPUDevice
-> ConstPtr WGPUShaderModuleDescriptor -> IO (Ptr WGPUShaderModule)
wgpuDeviceCreateShaderModule Ptr WGPUDevice
device (Ptr WGPUShaderModuleDescriptor
-> ConstPtr WGPUShaderModuleDescriptor
forall a. Ptr a -> ConstPtr a
ConstPtr Ptr WGPUShaderModuleDescriptor
desc)