-- GENERATED by C->Haskell Compiler, version 0.17.2 Crystal Seed, 24 Jan 2009 (Haskell)
-- Edit the ORIGNAL .chs file instead!


{-# LINE 1 "./Foreign/CUDA/Driver/Texture.chs" #-}
{-# LANGUAGE BangPatterns             #-}
{-# LANGUAGE ForeignFunctionInterface #-}
{-# OPTIONS_HADDOCK prune #-}
--------------------------------------------------------------------------------
-- |
-- Module    : Foreign.CUDA.Driver.Texture
-- Copyright : (c) [2009..2012] Trevor L. McDonell
-- License   : BSD
--
-- Texture management for low-level driver interface
--
--------------------------------------------------------------------------------

module Foreign.CUDA.Driver.Texture (

  -- * Texture Reference Management
  Texture(..), Format(..), AddressMode(..), FilterMode(..), ReadMode(..),
  create, destroy,
  bind, bind2D,
  getAddressMode, getFilterMode, getFormat,
  setAddressMode, setFilterMode, setFormat, setReadMode,

  -- Internal
  peekTex

) where



{-# LINE 29 "./Foreign/CUDA/Driver/Texture.chs" #-}


-- Friends
import Foreign.CUDA.Ptr
import Foreign.CUDA.Driver.Error
import Foreign.CUDA.Driver.Marshal
import Foreign.CUDA.Internal.C2HS

-- System
import Foreign
import Foreign.C
import Control.Monad

{-# DEPRECATED create, destroy "as of CUDA version 3.2" #-}


--------------------------------------------------------------------------------
-- Data Types
--------------------------------------------------------------------------------

-- |
-- A texture reference
--
newtype Texture = Texture { useTexture :: ((Ptr ()))}
  deriving (Eq, Show)

instance Storable Texture where
  sizeOf _    = sizeOf    (undefined :: ((Ptr ())))
  alignment _ = alignment (undefined :: ((Ptr ())))
  peek p      = Texture `fmap` peek (castPtr p)
  poke p t    = poke (castPtr p) (useTexture t)

-- |
-- Texture reference addressing modes
--
data AddressMode = Wrap
                 | Clamp
                 | Mirror
                 | Border
                 deriving (Eq,Show)
instance Enum AddressMode where
  fromEnum Wrap = 0
  fromEnum Clamp = 1
  fromEnum Mirror = 2
  fromEnum Border = 3

  toEnum 0 = Wrap
  toEnum 1 = Clamp
  toEnum 2 = Mirror
  toEnum 3 = Border
  toEnum unmatched = error ("AddressMode.toEnum: Cannot match " ++ show unmatched)

{-# LINE 68 "./Foreign/CUDA/Driver/Texture.chs" #-}


-- |
-- Texture reference filtering mode
--
data FilterMode = Point
                | Linear
                deriving (Eq,Show)
instance Enum FilterMode where
  fromEnum Point = 0
  fromEnum Linear = 1

  toEnum 0 = Point
  toEnum 1 = Linear
  toEnum unmatched = error ("FilterMode.toEnum: Cannot match " ++ show unmatched)

{-# LINE 75 "./Foreign/CUDA/Driver/Texture.chs" #-}


-- |
-- Texture read mode options
--
data ReadMode = ReadAsInteger
              | NormalizedCoordinates
              deriving (Eq,Show)
instance Enum ReadMode where
  fromEnum ReadAsInteger = 1
  fromEnum NormalizedCoordinates = 2

  toEnum 1 = ReadAsInteger
  toEnum 2 = NormalizedCoordinates
  toEnum unmatched = error ("ReadMode.toEnum: Cannot match " ++ show unmatched)

{-# LINE 88 "./Foreign/CUDA/Driver/Texture.chs" #-}


-- |
-- Texture data formats
--
data Format = Word8
            | Word16
            | Word32
            | Int8
            | Int16
            | Int32
            | Half
            | Float
            deriving (Eq,Show)
instance Enum Format where
  fromEnum Word8 = 1
  fromEnum Word16 = 2
  fromEnum Word32 = 3
  fromEnum Int8 = 8
  fromEnum Int16 = 9
  fromEnum Int32 = 10
  fromEnum Half = 16
  fromEnum Float = 32

  toEnum 1 = Word8
  toEnum 2 = Word16
  toEnum 3 = Word32
  toEnum 8 = Int8
  toEnum 9 = Int16
  toEnum 10 = Int32
  toEnum 16 = Half
  toEnum 32 = Float
  toEnum unmatched = error ("Format.toEnum: Cannot match " ++ show unmatched)

{-# LINE 101 "./Foreign/CUDA/Driver/Texture.chs" #-}



--------------------------------------------------------------------------------
-- Texture management
--------------------------------------------------------------------------------

-- |
-- Create a new texture reference. Once created, the application must call
-- 'setPtr' to associate the reference with allocated memory. Other texture
-- reference functions are used to specify the format and interpretation to be
-- used when the memory is read through this reference.
--
{-# INLINEABLE create #-}
create :: IO Texture
create = resultIfOk =<< cuTexRefCreate

{-# INLINE cuTexRefCreate #-}
cuTexRefCreate :: IO ((Status), (Texture))
cuTexRefCreate =
  alloca $ \a1' -> 
  cuTexRefCreate'_ a1' >>= \res ->
  let {res' = cToEnum res} in
  peekTex  a1'>>= \a1'' -> 
  return (res', a1'')

{-# LINE 120 "./Foreign/CUDA/Driver/Texture.chs" #-}



-- |
-- Destroy a texture reference
--
{-# INLINEABLE destroy #-}
destroy :: Texture -> IO ()
destroy !tex = nothingIfOk =<< cuTexRefDestroy tex

{-# INLINE cuTexRefDestroy #-}
cuTexRefDestroy :: (Texture) -> IO ((Status))
cuTexRefDestroy a1 =
  let {a1' = useTexture a1} in 
  cuTexRefDestroy'_ a1' >>= \res ->
  let {res' = cToEnum res} in
  return (res')

{-# LINE 132 "./Foreign/CUDA/Driver/Texture.chs" #-}



-- |
-- Bind a linear array address of the given size (bytes) as a texture
-- reference. Any previously bound references are unbound.
--
{-# INLINEABLE bind #-}
bind :: Texture -> DevicePtr a -> Int64 -> IO ()
bind !tex !dptr !bytes = nothingIfOk =<< cuTexRefSetAddress tex dptr bytes

{-# INLINE cuTexRefSetAddress #-}
cuTexRefSetAddress :: (Texture) -> (DevicePtr a) -> (Int64) -> IO ((Status))
cuTexRefSetAddress a2 a3 a4 =
  alloca $ \a1' -> 
  let {a2' = useTexture a2} in 
  let {a3' = useDeviceHandle a3} in 
  let {a4' = fromIntegral a4} in 
  cuTexRefSetAddress'_ a1' a2' a3' a4' >>= \res ->
  let {res' = cToEnum res} in
  return (res')

{-# LINE 148 "./Foreign/CUDA/Driver/Texture.chs" #-}



-- |
-- Bind a linear address range to the given texture reference as a
-- two-dimensional arena. Any previously bound reference is unbound. Note that
-- calls to 'setFormat' can not follow a call to 'bind2D' for the same texture
-- reference.
--
{-# INLINEABLE bind2D #-}
bind2D :: Texture -> Format -> Int -> DevicePtr a -> (Int,Int) -> Int64 -> IO ()
bind2D !tex !fmt !chn !dptr (!width,!height) !pitch =
  nothingIfOk =<< cuTexRefSetAddress2DSimple tex fmt chn dptr width height pitch

{-# INLINE cuTexRefSetAddress2DSimple #-}
cuTexRefSetAddress2DSimple :: (Texture) -> (Format) -> (Int) -> (DevicePtr a) -> (Int) -> (Int) -> (Int64) -> IO ((Status))
cuTexRefSetAddress2DSimple a1 a2 a3 a4 a5 a6 a7 =
  let {a1' = useTexture a1} in 
  let {a2' = cFromEnum a2} in 
  let {a3' = fromIntegral a3} in 
  let {a4' = useDeviceHandle a4} in 
  let {a5' = fromIntegral a5} in 
  let {a6' = fromIntegral a6} in 
  let {a7' = fromIntegral a7} in 
  cuTexRefSetAddress2DSimple'_ a1' a2' a3' a4' a5' a6' a7' >>= \res ->
  let {res' = cToEnum res} in
  return (res')

{-# LINE 170 "./Foreign/CUDA/Driver/Texture.chs" #-}



-- |
-- Get the addressing mode used by a texture reference, corresponding to the
-- given dimension (currently the only supported dimension values are 0 or 1).
--
{-# INLINEABLE getAddressMode #-}
getAddressMode :: Texture -> Int -> IO AddressMode
getAddressMode !tex !dim = resultIfOk =<< cuTexRefGetAddressMode tex dim

{-# INLINE cuTexRefGetAddressMode #-}
cuTexRefGetAddressMode :: (Texture) -> (Int) -> IO ((Status), (AddressMode))
cuTexRefGetAddressMode a2 a3 =
  alloca $ \a1' -> 
  let {a2' = useTexture a2} in 
  let {a3' = fromIntegral a3} in 
  cuTexRefGetAddressMode'_ a1' a2' a3' >>= \res ->
  let {res' = cToEnum res} in
  peekEnum  a1'>>= \a1'' -> 
  return (res', a1'')

{-# LINE 185 "./Foreign/CUDA/Driver/Texture.chs" #-}



-- |
-- Get the filtering mode used by a texture reference
--
{-# INLINEABLE getFilterMode #-}
getFilterMode :: Texture -> IO FilterMode
getFilterMode !tex = resultIfOk =<< cuTexRefGetFilterMode tex

{-# INLINE cuTexRefGetFilterMode #-}
cuTexRefGetFilterMode :: (Texture) -> IO ((Status), (FilterMode))
cuTexRefGetFilterMode a2 =
  alloca $ \a1' -> 
  let {a2' = useTexture a2} in 
  cuTexRefGetFilterMode'_ a1' a2' >>= \res ->
  let {res' = cToEnum res} in
  peekEnum  a1'>>= \a1'' -> 
  return (res', a1'')

{-# LINE 198 "./Foreign/CUDA/Driver/Texture.chs" #-}



-- |
-- Get the data format and number of channel components of the bound texture
--
{-# INLINEABLE getFormat #-}
getFormat :: Texture -> IO (Format, Int)
getFormat !tex = do
  (!status,!fmt,!dim) <- cuTexRefGetFormat tex
  resultIfOk (status,(fmt,dim))

{-# INLINE cuTexRefGetFormat #-}
cuTexRefGetFormat :: (Texture) -> IO ((Status), (Format), (Int))
cuTexRefGetFormat a3 =
  alloca $ \a1' -> 
  alloca $ \a2' -> 
  let {a3' = useTexture a3} in 
  cuTexRefGetFormat'_ a1' a2' a3' >>= \res ->
  let {res' = cToEnum res} in
  peekEnum  a1'>>= \a1'' -> 
  peekIntConv  a2'>>= \a2'' -> 
  return (res', a1'', a2'')

{-# LINE 214 "./Foreign/CUDA/Driver/Texture.chs" #-}



-- |
-- Specify the addressing mode for the given dimension of a texture reference
--
{-# INLINEABLE setAddressMode #-}
setAddressMode :: Texture -> Int -> AddressMode -> IO ()
setAddressMode !tex !dim !mode = nothingIfOk =<< cuTexRefSetAddressMode tex dim mode

{-# INLINE cuTexRefSetAddressMode #-}
cuTexRefSetAddressMode :: (Texture) -> (Int) -> (AddressMode) -> IO ((Status))
cuTexRefSetAddressMode a1 a2 a3 =
  let {a1' = useTexture a1} in 
  let {a2' = fromIntegral a2} in 
  let {a3' = cFromEnum a3} in 
  cuTexRefSetAddressMode'_ a1' a2' a3' >>= \res ->
  let {res' = cToEnum res} in
  return (res')

{-# LINE 228 "./Foreign/CUDA/Driver/Texture.chs" #-}



-- |
-- Specify the filtering mode to be used when reading memory through a texture
-- reference
--
{-# INLINEABLE setFilterMode #-}
setFilterMode :: Texture -> FilterMode -> IO ()
setFilterMode !tex !mode = nothingIfOk =<< cuTexRefSetFilterMode tex mode

{-# INLINE cuTexRefSetFilterMode #-}
cuTexRefSetFilterMode :: (Texture) -> (FilterMode) -> IO ((Status))
cuTexRefSetFilterMode a1 a2 =
  let {a1' = useTexture a1} in 
  let {a2' = cFromEnum a2} in 
  cuTexRefSetFilterMode'_ a1' a2' >>= \res ->
  let {res' = cToEnum res} in
  return (res')

{-# LINE 242 "./Foreign/CUDA/Driver/Texture.chs" #-}



-- |
-- Specify additional characteristics for reading and indexing the texture
-- reference
--
{-# INLINEABLE setReadMode #-}
setReadMode :: Texture -> ReadMode -> IO ()
setReadMode !tex !mode = nothingIfOk =<< cuTexRefSetFlags tex mode

{-# INLINE cuTexRefSetFlags #-}
cuTexRefSetFlags :: (Texture) -> (ReadMode) -> IO ((Status))
cuTexRefSetFlags a1 a2 =
  let {a1' = useTexture a1} in 
  let {a2' = cFromEnum a2} in 
  cuTexRefSetFlags'_ a1' a2' >>= \res ->
  let {res' = cToEnum res} in
  return (res')

{-# LINE 256 "./Foreign/CUDA/Driver/Texture.chs" #-}



-- |
-- Specify the format of the data and number of packed components per element to
-- be read by the texture reference
--
{-# INLINEABLE setFormat #-}
setFormat :: Texture -> Format -> Int -> IO ()
setFormat !tex !fmt !chn = nothingIfOk =<< cuTexRefSetFormat tex fmt chn

{-# INLINE cuTexRefSetFormat #-}
cuTexRefSetFormat :: (Texture) -> (Format) -> (Int) -> IO ((Status))
cuTexRefSetFormat a1 a2 a3 =
  let {a1' = useTexture a1} in 
  let {a2' = cFromEnum a2} in 
  let {a3' = fromIntegral a3} in 
  cuTexRefSetFormat'_ a1' a2' a3' >>= \res ->
  let {res' = cToEnum res} in
  return (res')

{-# LINE 271 "./Foreign/CUDA/Driver/Texture.chs" #-}



--------------------------------------------------------------------------------
-- Internal
--------------------------------------------------------------------------------

{-# INLINE peekTex #-}
peekTex :: Ptr ((Ptr ())) -> IO Texture
peekTex = liftM Texture . peek


foreign import ccall unsafe "Foreign/CUDA/Driver/Texture.chs.h cuTexRefCreate"
  cuTexRefCreate'_ :: ((Ptr (Ptr ())) -> (IO CInt))

foreign import ccall unsafe "Foreign/CUDA/Driver/Texture.chs.h cuTexRefDestroy"
  cuTexRefDestroy'_ :: ((Ptr ()) -> (IO CInt))

foreign import ccall unsafe "Foreign/CUDA/Driver/Texture.chs.h cuTexRefSetAddress"
  cuTexRefSetAddress'_ :: ((Ptr CULong) -> ((Ptr ()) -> (CULLong -> (CULong -> (IO CInt)))))

foreign import ccall unsafe "Foreign/CUDA/Driver/Texture.chs.h cuTexRefSetAddress2DSimple"
  cuTexRefSetAddress2DSimple'_ :: ((Ptr ()) -> (CInt -> (CInt -> (CULLong -> (CInt -> (CInt -> (CInt -> (IO CInt))))))))

foreign import ccall unsafe "Foreign/CUDA/Driver/Texture.chs.h cuTexRefGetAddressMode"
  cuTexRefGetAddressMode'_ :: ((Ptr CInt) -> ((Ptr ()) -> (CInt -> (IO CInt))))

foreign import ccall unsafe "Foreign/CUDA/Driver/Texture.chs.h cuTexRefGetFilterMode"
  cuTexRefGetFilterMode'_ :: ((Ptr CInt) -> ((Ptr ()) -> (IO CInt)))

foreign import ccall unsafe "Foreign/CUDA/Driver/Texture.chs.h cuTexRefGetFormat"
  cuTexRefGetFormat'_ :: ((Ptr CInt) -> ((Ptr CInt) -> ((Ptr ()) -> (IO CInt))))

foreign import ccall unsafe "Foreign/CUDA/Driver/Texture.chs.h cuTexRefSetAddressMode"
  cuTexRefSetAddressMode'_ :: ((Ptr ()) -> (CInt -> (CInt -> (IO CInt))))

foreign import ccall unsafe "Foreign/CUDA/Driver/Texture.chs.h cuTexRefSetFilterMode"
  cuTexRefSetFilterMode'_ :: ((Ptr ()) -> (CInt -> (IO CInt)))

foreign import ccall unsafe "Foreign/CUDA/Driver/Texture.chs.h cuTexRefSetFlags"
  cuTexRefSetFlags'_ :: ((Ptr ()) -> (CUInt -> (IO CInt)))

foreign import ccall unsafe "Foreign/CUDA/Driver/Texture.chs.h cuTexRefSetFormat"
  cuTexRefSetFormat'_ :: ((Ptr ()) -> (CInt -> (CInt -> (IO CInt))))