{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RecordWildCards #-}

-- |
-- Module      : WGPU.Internal.Queue
-- Description : Queues
module WGPU.Internal.Queue
  ( -- * Types
    Queue,

    -- * Functions
    getQueue,
    queueSubmit,
  )
where

import Control.Monad.IO.Class (MonadIO, liftIO)
import Data.Vector (Vector)
import WGPU.Internal.CommandBuffer (CommandBuffer)
import WGPU.Internal.Device (Device, deviceInst, wgpuDevice)
import WGPU.Internal.Instance (Instance, wgpuHsInstance)
import WGPU.Internal.Memory (ToRaw, evalContT, raw, rawArrayPtr, showWithPtr)
import qualified WGPU.Raw.Generated.Fun as RawFun
import WGPU.Raw.Types (WGPUQueue (WGPUQueue))

-------------------------------------------------------------------------------

data Queue = Queue
  { Queue -> Instance
queueInst :: !Instance,
    Queue -> WGPUQueue
wgpuQueue :: !WGPUQueue
  }

instance Show Queue where
  show :: Queue -> String
show Queue
q =
    let Queue Instance
_ (WGPUQueue Ptr ()
ptr) = Queue
q
     in String -> Ptr () -> String
forall a. String -> Ptr a -> String
showWithPtr String
"Queue" Ptr ()
ptr

instance Eq Queue where
  == :: Queue -> Queue -> Bool
(==) Queue
q1 Queue
q2 =
    let Queue Instance
_ (WGPUQueue Ptr ()
q1_ptr) = Queue
q1
        Queue Instance
_ (WGPUQueue Ptr ()
q2_ptr) = Queue
q2
     in Ptr ()
q1_ptr Ptr () -> Ptr () -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr ()
q2_ptr

instance ToRaw Queue WGPUQueue where
  raw :: Queue -> ContT r IO WGPUQueue
raw = WGPUQueue -> ContT r IO WGPUQueue
forall (f :: * -> *) a. Applicative f => a -> f a
pure (WGPUQueue -> ContT r IO WGPUQueue)
-> (Queue -> WGPUQueue) -> Queue -> ContT r IO WGPUQueue
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Queue -> WGPUQueue
wgpuQueue

-------------------------------------------------------------------------------

-- | Get the queue for a device.
getQueue :: MonadIO m => Device -> m Queue
getQueue :: Device -> m Queue
getQueue Device
device = do
  let queueInst :: Instance
queueInst = Device -> Instance
deviceInst Device
device
  WGPUQueue
wgpuQueue <-
    WGPUHsInstance -> WGPUDevice -> m WGPUQueue
forall (m :: * -> *).
MonadIO m =>
WGPUHsInstance -> WGPUDevice -> m WGPUQueue
RawFun.wgpuDeviceGetQueue (Instance -> WGPUHsInstance
wgpuHsInstance Instance
queueInst) (Device -> WGPUDevice
wgpuDevice Device
device)
  Queue -> m Queue
forall (f :: * -> *) a. Applicative f => a -> f a
pure Queue :: Instance -> WGPUQueue -> Queue
Queue {WGPUQueue
Instance
wgpuQueue :: WGPUQueue
queueInst :: Instance
wgpuQueue :: WGPUQueue
queueInst :: Instance
..}

-- | Submit a list of command buffers to a device queue.
queueSubmit :: MonadIO m => Queue -> Vector CommandBuffer -> m ()
queueSubmit :: Queue -> Vector CommandBuffer -> m ()
queueSubmit Queue
queue Vector CommandBuffer
cbs = IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ())
-> (ContT () IO () -> IO ()) -> ContT () IO () -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ContT () IO () -> IO ()
forall (m :: * -> *) a. Monad m => ContT a m a -> m a
evalContT (ContT () IO () -> m ()) -> ContT () IO () -> m ()
forall a b. (a -> b) -> a -> b
$ do
  let inst :: Instance
inst = Queue -> Instance
queueInst Queue
queue
  let commandCount :: Word32
commandCount = Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word32)
-> (Vector CommandBuffer -> Int) -> Vector CommandBuffer -> Word32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector CommandBuffer -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (Vector CommandBuffer -> Word32) -> Vector CommandBuffer -> Word32
forall a b. (a -> b) -> a -> b
$ Vector CommandBuffer
cbs
  Ptr WGPUCommandBuffer
commandBuffer_ptr <- Vector CommandBuffer -> ContT () IO (Ptr WGPUCommandBuffer)
forall (v :: * -> *) r a b.
(ToRaw a b, Storable b, Vector v a) =>
v a -> ContT r IO (Ptr b)
rawArrayPtr Vector CommandBuffer
cbs
  WGPUHsInstance
-> WGPUQueue -> Word32 -> Ptr WGPUCommandBuffer -> ContT () IO ()
forall (m :: * -> *).
MonadIO m =>
WGPUHsInstance
-> WGPUQueue -> Word32 -> Ptr WGPUCommandBuffer -> m ()
RawFun.wgpuQueueSubmit
    (Instance -> WGPUHsInstance
wgpuHsInstance Instance
inst)
    (Queue -> WGPUQueue
wgpuQueue Queue
queue)
    Word32
commandCount
    Ptr WGPUCommandBuffer
commandBuffer_ptr