cuda-0.2: Foreign/CUDA/Runtime/Texture.chs
{-# LANGUAGE ForeignFunctionInterface #-}
--------------------------------------------------------------------------------
-- |
-- Module : Foreign.CUDA.Runtime.Texture
-- Copyright : (c) [2009..2010] Trevor L. McDonell
-- License : BSD
--
-- Texture references
--
--------------------------------------------------------------------------------
module Foreign.CUDA.Runtime.Texture
(
Texture(..), FormatKind(..), AddressMode(..), FilterMode(..), FormatDesc(..),
bind, bind2D
)
where
-- Friends
import Foreign.CUDA.Ptr
import Foreign.CUDA.Runtime.Error
import Foreign.CUDA.Internal.C2HS
import Foreign.CUDA.Internal.Offsets
-- System
import Data.Int
import Foreign
import Foreign.C
#include <cuda_runtime_api.h>
{# context lib="cudart" #}
#c
typedef struct textureReference textureReference;
typedef struct cudaChannelFormatDesc cudaChannelFormatDesc;
#endc
--------------------------------------------------------------------------------
-- Data Types
--------------------------------------------------------------------------------
-- |A texture reference
--
{# pointer *textureReference as ^ -> Texture #}
data Texture = Texture
{
normalised :: Bool, -- ^ access texture using normalised coordinates [0.0,1.0)
filtering :: FilterMode,
addressing :: (AddressMode, AddressMode, AddressMode),
format :: FormatDesc
}
deriving (Eq, Show)
-- |Texture channel format kind
--
{# enum cudaChannelFormatKind as FormatKind
{ }
with prefix="cudaChannelFormatKind" deriving (Eq, Show) #}
-- |Texture addressing mode
--
{# enum cudaTextureAddressMode as AddressMode
{ }
with prefix="cudaAddressMode" deriving (Eq, Show) #}
-- |Texture filtering mode
--
{# enum cudaTextureFilterMode as FilterMode
{ }
with prefix="cudaFilterMode" deriving (Eq, Show) #}
-- |A description of how memory read through the texture cache should be
-- interpreted, including the kind of data and the number of bits of each
-- component (x,y,z and w, respectively).
--
{# pointer *cudaChannelFormatDesc as ^ foreign -> FormatDesc nocode #}
data FormatDesc = FormatDesc
{
depth :: (Int,Int,Int,Int),
kind :: FormatKind
}
deriving (Eq, Show)
instance Storable FormatDesc where
sizeOf _ = {# sizeof cudaChannelFormatDesc #}
alignment _ = alignment (undefined :: Ptr ())
peek p = do
dx <- cIntConv `fmap` {# get cudaChannelFormatDesc.x #} p
dy <- cIntConv `fmap` {# get cudaChannelFormatDesc.y #} p
dz <- cIntConv `fmap` {# get cudaChannelFormatDesc.z #} p
dw <- cIntConv `fmap` {# get cudaChannelFormatDesc.w #} p
df <- cToEnum `fmap` {# get cudaChannelFormatDesc.f #} p
return $ FormatDesc (dx,dy,dz,dw) df
poke p (FormatDesc (x,y,z,w) k) = do
{# set cudaChannelFormatDesc.x #} p (cIntConv x)
{# set cudaChannelFormatDesc.y #} p (cIntConv y)
{# set cudaChannelFormatDesc.z #} p (cIntConv z)
{# set cudaChannelFormatDesc.w #} p (cIntConv w)
{# set cudaChannelFormatDesc.f #} p (cFromEnum k)
instance Storable Texture where
sizeOf _ = {# sizeof textureReference #}
alignment _ = alignment (undefined :: Ptr ())
peek p = do
norm <- cToBool `fmap` {# get textureReference.normalized #} p
fmt <- cToEnum `fmap` {# get textureReference.filterMode #} p
[x,y,z] <- map cToEnum `fmap` (peekArray 3 (p `plusPtr` texRefAddressModeOffset :: Ptr CInt))
dsc <- peekByteOff p texRefChannelDescOffset
return $ Texture norm fmt (x,y,z) dsc
poke p (Texture norm fmt (x,y,z) dsc) = do
{# set textureReference.normalized #} p (cFromBool norm)
{# set textureReference.filterMode #} p (cFromEnum fmt)
pokeArray (p `plusPtr` texRefAddressModeOffset :: Ptr CInt) (map cFromEnum [x,y,z])
pokeByteOff p texRefChannelDescOffset dsc
--------------------------------------------------------------------------------
-- Texture References
--------------------------------------------------------------------------------
-- |Bind the memory area associated with the device pointer to a texture
-- reference given by the named symbol. Any previously bound references are
-- unbound.
--
bind :: String -> Texture -> DevicePtr a -> Int64 -> IO ()
bind name tex dptr bytes = do
ref <- getTex name
poke ref tex
nothingIfOk =<< cudaBindTexture ref dptr (format tex) bytes
{# fun unsafe cudaBindTexture
{ alloca- `Int'
, id `TextureReference'
, dptr `DevicePtr a'
, with_* `FormatDesc'
, `Int64' } -> `Status' cToEnum #}
where dptr = useDevicePtr . castDevPtr
-- |Bind the two-dimensional memory area to the texture reference associated
-- with the given symbol. The size of the area is constrained by (width,height)
-- in texel units, and the row pitch in bytes. Any previously bound references
-- are unbound.
--
bind2D :: String -> Texture -> DevicePtr a -> (Int,Int) -> Int64 -> IO ()
bind2D name tex dptr (width,height) bytes = do
ref <- getTex name
poke ref tex
nothingIfOk =<< cudaBindTexture2D ref dptr (format tex) width height bytes
{# fun unsafe cudaBindTexture2D
{ alloca- `Int'
, id `TextureReference'
, dptr `DevicePtr a'
, with_* `FormatDesc'
, `Int'
, `Int'
, `Int64' } -> `Status' cToEnum #}
where dptr = useDevicePtr . castDevPtr
-- |Returns the texture reference associated with the given symbol
--
getTex :: String -> IO TextureReference
getTex name = resultIfOk =<< cudaGetTextureReference name
{# fun unsafe cudaGetTextureReference
{ alloca- `Ptr Texture' peek*
, withCString* `String' } -> `Status' cToEnum #}
--------------------------------------------------------------------------------
-- Internal
--------------------------------------------------------------------------------
with_ :: Storable a => a -> (Ptr a -> IO b) -> IO b
with_ = with