{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RoleAnnotations #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}

-- |
-- Description : Generically derive Storable instances for GPU memory layouts
-- Copyright   : (c) Jeremy Nuttall, 2025
-- License     : BSD-3-Clause
-- Maintainer  : jeremy@jeremy-nuttall.com
-- Stability   : experimental
--
-- Derive @Storable@ instances that respect GPU memory layout rules (@std140@,
-- @std430@, @scalar@). Works with any product type that has a 'Generic' instance.
--
-- @
-- data Uniforms = Uniforms
--   { viewProj  :: M44 Float
--   , cameraPos :: V3 Float
--   } deriving Generic
--
-- instance AlignedStorable Std140 Uniforms
-- @
--
-- Then use "Foreign.GPU.Marshal.Aligned" to get properly-padded pointers:
--
-- @
-- withPacked \@Std140 uniforms $ \\ptr -> uploadToGPU ptr
-- @
--
-- __NB:__ @vec3@ and @mat3@ types have historically had driver bugs
-- around alignment. Prefer @vec4@/@mat4@ when possible.
module Foreign.GPU.Storable.Aligned (
  -- * The AlignedStorable class
  AlignedStorable (..),

  -- * Memory layout
  MemoryLayout (..),
  SMemoryLayout (..),
  KnownMemoryLayout (..),
  memoryLayoutVal,

  -- * Storable Wrappers
  Strided (..),
  StridedVector,
  Packed (..),
  AlignedArray (..),
  mkAlignedArray,
  withAlignedArray,
  AlignedPtr (..),

  -- * Memory layout rules
  MemoryLayoutRules (..),

  -- * Generics
  GAlignedStorable (..),
)
where

import Control.Monad
import Data.Bifunctor (first)
import Data.Bits
import Data.Coerce
import Data.Foldable (traverse_)
import Data.Hashable (Hashable)
import Data.Int
import Data.Kind
import Data.Maybe (fromJust)
import Data.Proxy
import Data.Typeable (Typeable)
import qualified Data.Vector.Generic as GV
import qualified Data.Vector.Generic.Sized as SGV
import qualified Data.Vector.Storable as SV
import qualified Data.Vector.Storable.Mutable as SMV
import qualified Data.Vector.Storable.Sized as SSV
import Data.Word
import Foreign (Ptr, castPtr, copyBytes, plusPtr)
import Foreign.Storable
import GHC.Generics
import GHC.TypeLits
import Linear (M22, M23, M24, M32, M33, M34, M42, M43, M44, V2 (..), V3 (..), V4 (..))
import Numeric.Half (Half)

--------------------------------------------------------------------------------
-- Layout Rules
--------------------------------------------------------------------------------

-- | A type-level tag representing a memory layout standard.
data MemoryLayout
  = -- | `std140` is a standardized memory layout for SPIR-V interface blocks.
    -- It has strict padding and alignment rules, ensuring layout consistency across platforms.
    --
    -- For details, refer to 7.6.2.2 "Standard Uniform Block Layout" of the
    -- [OpenGL 4.6 Specification](https://registry.khronos.org/OpenGL/specs/gl/glspec46.core.pdf).
    Std140
  | -- | `std430` is a standardized memory layout, typically used for Shader Storage Buffer
    -- Objects (SSBOs). It has more relaxed alignment rules for arrays and structs
    -- than `std140`, which can result in more compact memory usage.
    --
    -- For details, please refer to the section 7.6.2.2 "Standard Uniform Block Layout" of the
    -- [OpenGL 4.6 Specification](https://registry.khronos.org/OpenGL/specs/gl/glspec46.core.pdf).
    Std430
  | -- | `scalar` block layout is a memory layout with the most relaxed alignment rules,
    -- closely matching the alignment of scalar and vector types in C.
    --
    -- For details, please refer to the
    -- [extension specification](https://github.com/KhronosGroup/GLSL/blob/main/extensions/ext/GL_EXT_scalar_block_layout.txt)
    Scalar
  deriving (Int -> MemoryLayout -> ShowS
[MemoryLayout] -> ShowS
MemoryLayout -> String
(Int -> MemoryLayout -> ShowS)
-> (MemoryLayout -> String)
-> ([MemoryLayout] -> ShowS)
-> Show MemoryLayout
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> MemoryLayout -> ShowS
showsPrec :: Int -> MemoryLayout -> ShowS
$cshow :: MemoryLayout -> String
show :: MemoryLayout -> String
$cshowList :: [MemoryLayout] -> ShowS
showList :: [MemoryLayout] -> ShowS
Show, (forall x. MemoryLayout -> Rep MemoryLayout x)
-> (forall x. Rep MemoryLayout x -> MemoryLayout)
-> Generic MemoryLayout
forall x. Rep MemoryLayout x -> MemoryLayout
forall x. MemoryLayout -> Rep MemoryLayout x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. MemoryLayout -> Rep MemoryLayout x
from :: forall x. MemoryLayout -> Rep MemoryLayout x
$cto :: forall x. Rep MemoryLayout x -> MemoryLayout
to :: forall x. Rep MemoryLayout x -> MemoryLayout
Generic, Typeable, Int -> MemoryLayout
MemoryLayout -> Int
MemoryLayout -> [MemoryLayout]
MemoryLayout -> MemoryLayout
MemoryLayout -> MemoryLayout -> [MemoryLayout]
MemoryLayout -> MemoryLayout -> MemoryLayout -> [MemoryLayout]
(MemoryLayout -> MemoryLayout)
-> (MemoryLayout -> MemoryLayout)
-> (Int -> MemoryLayout)
-> (MemoryLayout -> Int)
-> (MemoryLayout -> [MemoryLayout])
-> (MemoryLayout -> MemoryLayout -> [MemoryLayout])
-> (MemoryLayout -> MemoryLayout -> [MemoryLayout])
-> (MemoryLayout -> MemoryLayout -> MemoryLayout -> [MemoryLayout])
-> Enum MemoryLayout
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: MemoryLayout -> MemoryLayout
succ :: MemoryLayout -> MemoryLayout
$cpred :: MemoryLayout -> MemoryLayout
pred :: MemoryLayout -> MemoryLayout
$ctoEnum :: Int -> MemoryLayout
toEnum :: Int -> MemoryLayout
$cfromEnum :: MemoryLayout -> Int
fromEnum :: MemoryLayout -> Int
$cenumFrom :: MemoryLayout -> [MemoryLayout]
enumFrom :: MemoryLayout -> [MemoryLayout]
$cenumFromThen :: MemoryLayout -> MemoryLayout -> [MemoryLayout]
enumFromThen :: MemoryLayout -> MemoryLayout -> [MemoryLayout]
$cenumFromTo :: MemoryLayout -> MemoryLayout -> [MemoryLayout]
enumFromTo :: MemoryLayout -> MemoryLayout -> [MemoryLayout]
$cenumFromThenTo :: MemoryLayout -> MemoryLayout -> MemoryLayout -> [MemoryLayout]
enumFromThenTo :: MemoryLayout -> MemoryLayout -> MemoryLayout -> [MemoryLayout]
Enum, MemoryLayout
MemoryLayout -> MemoryLayout -> Bounded MemoryLayout
forall a. a -> a -> Bounded a
$cminBound :: MemoryLayout
minBound :: MemoryLayout
$cmaxBound :: MemoryLayout
maxBound :: MemoryLayout
Bounded, MemoryLayout -> MemoryLayout -> Bool
(MemoryLayout -> MemoryLayout -> Bool)
-> (MemoryLayout -> MemoryLayout -> Bool) -> Eq MemoryLayout
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MemoryLayout -> MemoryLayout -> Bool
== :: MemoryLayout -> MemoryLayout -> Bool
$c/= :: MemoryLayout -> MemoryLayout -> Bool
/= :: MemoryLayout -> MemoryLayout -> Bool
Eq, Eq MemoryLayout
Eq MemoryLayout =>
(MemoryLayout -> MemoryLayout -> Ordering)
-> (MemoryLayout -> MemoryLayout -> Bool)
-> (MemoryLayout -> MemoryLayout -> Bool)
-> (MemoryLayout -> MemoryLayout -> Bool)
-> (MemoryLayout -> MemoryLayout -> Bool)
-> (MemoryLayout -> MemoryLayout -> MemoryLayout)
-> (MemoryLayout -> MemoryLayout -> MemoryLayout)
-> Ord MemoryLayout
MemoryLayout -> MemoryLayout -> Bool
MemoryLayout -> MemoryLayout -> Ordering
MemoryLayout -> MemoryLayout -> MemoryLayout
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: MemoryLayout -> MemoryLayout -> Ordering
compare :: MemoryLayout -> MemoryLayout -> Ordering
$c< :: MemoryLayout -> MemoryLayout -> Bool
< :: MemoryLayout -> MemoryLayout -> Bool
$c<= :: MemoryLayout -> MemoryLayout -> Bool
<= :: MemoryLayout -> MemoryLayout -> Bool
$c> :: MemoryLayout -> MemoryLayout -> Bool
> :: MemoryLayout -> MemoryLayout -> Bool
$c>= :: MemoryLayout -> MemoryLayout -> Bool
>= :: MemoryLayout -> MemoryLayout -> Bool
$cmax :: MemoryLayout -> MemoryLayout -> MemoryLayout
max :: MemoryLayout -> MemoryLayout -> MemoryLayout
$cmin :: MemoryLayout -> MemoryLayout -> MemoryLayout
min :: MemoryLayout -> MemoryLayout -> MemoryLayout
Ord)

instance Hashable MemoryLayout

-- | Singled 'MemoryLayout', primarily useful for authors of higher-level libraries
-- (e.g., shader eDSLs, descriptor set builders).
data SMemoryLayout (layout :: MemoryLayout) where
  SStd140 :: SMemoryLayout Std140
  SStd430 :: SMemoryLayout Std430
  SScalar :: SMemoryLayout Scalar

-- | This class gives the 'SMemoryLayout' associated with a 'MemoryLayout'.
--
-- A very rough sketch of this use case:
--
-- > emitLayoutQualifier :: forall layout. KnownMemoryLayout layout => String
-- > emitLayoutQualifier = case memoryLayoutVal (Proxy @layout) of
-- >   Std140 -> "layout(std140)"
-- >   Std430 -> "layout(std430)"
-- >   Scalar -> "layout(scalar)"
class KnownMemoryLayout (layout :: MemoryLayout) where
  memoryLayoutSing :: SMemoryLayout layout

instance KnownMemoryLayout Std140 where
  memoryLayoutSing :: SMemoryLayout 'Std140
memoryLayoutSing = SMemoryLayout 'Std140
SStd140
  {-# INLINE memoryLayoutSing #-}

instance KnownMemoryLayout Std430 where
  memoryLayoutSing :: SMemoryLayout 'Std430
memoryLayoutSing = SMemoryLayout 'Std430
SStd430
  {-# INLINE memoryLayoutSing #-}

instance KnownMemoryLayout Scalar where
  memoryLayoutSing :: SMemoryLayout 'Scalar
memoryLayoutSing = SMemoryLayout 'Scalar
SScalar
  {-# INLINE memoryLayoutSing #-}

memoryLayoutVal :: forall layout. (KnownMemoryLayout layout) => Proxy layout -> MemoryLayout
memoryLayoutVal :: forall (layout :: MemoryLayout).
KnownMemoryLayout layout =>
Proxy layout -> MemoryLayout
memoryLayoutVal Proxy layout
_ = case forall (layout :: MemoryLayout).
KnownMemoryLayout layout =>
SMemoryLayout layout
memoryLayoutSing @layout of
  SMemoryLayout layout
SStd140 -> MemoryLayout
Std140
  SMemoryLayout layout
SStd430 -> MemoryLayout
Std430
  SMemoryLayout layout
SScalar -> MemoryLayout
Scalar
{-# INLINE memoryLayoutVal #-}

-- | Defines the precise calculation rules for a given 'MemoryLayout'.
--
-- These rules correspond to the memory layout requirements found in the OpenGL
-- and Vulkan specifications.
class MemoryLayoutRules (layout :: MemoryLayout) where
  -- | The alignment rule for top-level structs, matrix rows, and array members.
  alignBlock :: Proxy layout -> Int -> Int

  -- | The final size rule for a top-level struct.
  roundStructSize :: Proxy layout -> Int -> Int -> Int

  -- | The stride rule for an element within an array.
  layoutStride :: Proxy layout -> Int -> Int -> Int

std140Align :: Int
std140Align :: Int
std140Align = Int
16

instance MemoryLayoutRules Std140 where
  alignBlock :: Proxy 'Std140 -> Int -> Int
alignBlock Proxy 'Std140
_ = Int -> Int -> Int
forall a. (Bits a, Num a) => a -> a -> a
roundUpTo Int
std140Align
  {-# INLINE alignBlock #-}
  roundStructSize :: Proxy 'Std140 -> Int -> Int -> Int
roundStructSize Proxy 'Std140
_ = (Int -> Int -> Int) -> Int -> Int -> Int
forall a b c. (a -> b -> c) -> b -> a -> c
flip Int -> Int -> Int
forall a. (Bits a, Num a) => a -> a -> a
roundUpTo
  {-# INLINE roundStructSize #-}
  layoutStride :: Proxy 'Std140 -> Int -> Int -> Int
layoutStride Proxy 'Std140
_ Int
size Int
align = Int -> Int -> Int
forall a. (Bits a, Num a) => a -> a -> a
roundUpTo Int
std140Align (Int -> Int -> Int
forall a. (Bits a, Num a) => a -> a -> a
roundUpTo Int
align Int
size)
  {-# INLINE layoutStride #-}

instance MemoryLayoutRules Std430 where
  alignBlock :: Proxy 'Std430 -> Int -> Int
alignBlock Proxy 'Std430
_ = Int -> Int
forall a. a -> a
id
  {-# INLINE alignBlock #-}
  roundStructSize :: Proxy 'Std430 -> Int -> Int -> Int
roundStructSize Proxy 'Std430
_ = (Int -> Int -> Int) -> Int -> Int -> Int
forall a b c. (a -> b -> c) -> b -> a -> c
flip Int -> Int -> Int
forall a. (Bits a, Num a) => a -> a -> a
roundUpTo
  {-# INLINE roundStructSize #-}
  layoutStride :: Proxy 'Std430 -> Int -> Int -> Int
layoutStride Proxy 'Std430
_ = (Int -> Int -> Int) -> Int -> Int -> Int
forall a b c. (a -> b -> c) -> b -> a -> c
flip Int -> Int -> Int
forall a. (Bits a, Num a) => a -> a -> a
roundUpTo
  {-# INLINE layoutStride #-}

instance MemoryLayoutRules Scalar where
  alignBlock :: Proxy 'Scalar -> Int -> Int
alignBlock Proxy 'Scalar
_ = Int -> Int
forall a. a -> a
id
  {-# INLINE alignBlock #-}
  roundStructSize :: Proxy 'Scalar -> Int -> Int -> Int
roundStructSize Proxy 'Scalar
_ Int
size Int
_ = Int
size
  {-# INLINE roundStructSize #-}
  layoutStride :: Proxy 'Scalar -> Int -> Int -> Int
layoutStride Proxy 'Scalar
_ = (Int -> Int -> Int) -> Int -> Int -> Int
forall a b c. (a -> b -> c) -> b -> a -> c
flip Int -> Int -> Int
forall a. (Bits a, Num a) => a -> a -> a
roundUpTo
  {-# INLINE layoutStride #-}

--------------------------------------------------------------------------------
-- Layout-aware Storable
--------------------------------------------------------------------------------

-- | Wrapper whose 'sizeOf' includes stride padding, for use in arrays.
-- @SV.Vector (Strided Std140 MyType)@ can be 'copyBytes'd to the GPU in one shot.
newtype Strided (layout :: MemoryLayout) a = Strided {forall (layout :: MemoryLayout) a. Strided layout a -> a
unStrided :: a}
  deriving ((forall x. Strided layout a -> Rep (Strided layout a) x)
-> (forall x. Rep (Strided layout a) x -> Strided layout a)
-> Generic (Strided layout a)
forall x. Rep (Strided layout a) x -> Strided layout a
forall x. Strided layout a -> Rep (Strided layout a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (layout :: MemoryLayout) a x.
Rep (Strided layout a) x -> Strided layout a
forall (layout :: MemoryLayout) a x.
Strided layout a -> Rep (Strided layout a) x
$cfrom :: forall (layout :: MemoryLayout) a x.
Strided layout a -> Rep (Strided layout a) x
from :: forall x. Strided layout a -> Rep (Strided layout a) x
$cto :: forall (layout :: MemoryLayout) a x.
Rep (Strided layout a) x -> Strided layout a
to :: forall x. Rep (Strided layout a) x -> Strided layout a
Generic, Typeable, Int -> Strided layout a -> ShowS
[Strided layout a] -> ShowS
Strided layout a -> String
(Int -> Strided layout a -> ShowS)
-> (Strided layout a -> String)
-> ([Strided layout a] -> ShowS)
-> Show (Strided layout a)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (layout :: MemoryLayout) a.
Show a =>
Int -> Strided layout a -> ShowS
forall (layout :: MemoryLayout) a.
Show a =>
[Strided layout a] -> ShowS
forall (layout :: MemoryLayout) a.
Show a =>
Strided layout a -> String
$cshowsPrec :: forall (layout :: MemoryLayout) a.
Show a =>
Int -> Strided layout a -> ShowS
showsPrec :: Int -> Strided layout a -> ShowS
$cshow :: forall (layout :: MemoryLayout) a.
Show a =>
Strided layout a -> String
show :: Strided layout a -> String
$cshowList :: forall (layout :: MemoryLayout) a.
Show a =>
[Strided layout a] -> ShowS
showList :: [Strided layout a] -> ShowS
Show, Strided layout a -> Strided layout a -> Bool
(Strided layout a -> Strided layout a -> Bool)
-> (Strided layout a -> Strided layout a -> Bool)
-> Eq (Strided layout a)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (layout :: MemoryLayout) a.
Eq a =>
Strided layout a -> Strided layout a -> Bool
$c== :: forall (layout :: MemoryLayout) a.
Eq a =>
Strided layout a -> Strided layout a -> Bool
== :: Strided layout a -> Strided layout a -> Bool
$c/= :: forall (layout :: MemoryLayout) a.
Eq a =>
Strided layout a -> Strided layout a -> Bool
/= :: Strided layout a -> Strided layout a -> Bool
Eq, Eq (Strided layout a)
Eq (Strided layout a) =>
(Strided layout a -> Strided layout a -> Ordering)
-> (Strided layout a -> Strided layout a -> Bool)
-> (Strided layout a -> Strided layout a -> Bool)
-> (Strided layout a -> Strided layout a -> Bool)
-> (Strided layout a -> Strided layout a -> Bool)
-> (Strided layout a -> Strided layout a -> Strided layout a)
-> (Strided layout a -> Strided layout a -> Strided layout a)
-> Ord (Strided layout a)
Strided layout a -> Strided layout a -> Bool
Strided layout a -> Strided layout a -> Ordering
Strided layout a -> Strided layout a -> Strided layout a
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall (layout :: MemoryLayout) a. Ord a => Eq (Strided layout a)
forall (layout :: MemoryLayout) a.
Ord a =>
Strided layout a -> Strided layout a -> Bool
forall (layout :: MemoryLayout) a.
Ord a =>
Strided layout a -> Strided layout a -> Ordering
forall (layout :: MemoryLayout) a.
Ord a =>
Strided layout a -> Strided layout a -> Strided layout a
$ccompare :: forall (layout :: MemoryLayout) a.
Ord a =>
Strided layout a -> Strided layout a -> Ordering
compare :: Strided layout a -> Strided layout a -> Ordering
$c< :: forall (layout :: MemoryLayout) a.
Ord a =>
Strided layout a -> Strided layout a -> Bool
< :: Strided layout a -> Strided layout a -> Bool
$c<= :: forall (layout :: MemoryLayout) a.
Ord a =>
Strided layout a -> Strided layout a -> Bool
<= :: Strided layout a -> Strided layout a -> Bool
$c> :: forall (layout :: MemoryLayout) a.
Ord a =>
Strided layout a -> Strided layout a -> Bool
> :: Strided layout a -> Strided layout a -> Bool
$c>= :: forall (layout :: MemoryLayout) a.
Ord a =>
Strided layout a -> Strided layout a -> Bool
>= :: Strided layout a -> Strided layout a -> Bool
$cmax :: forall (layout :: MemoryLayout) a.
Ord a =>
Strided layout a -> Strided layout a -> Strided layout a
max :: Strided layout a -> Strided layout a -> Strided layout a
$cmin :: forall (layout :: MemoryLayout) a.
Ord a =>
Strided layout a -> Strided layout a -> Strided layout a
min :: Strided layout a -> Strided layout a -> Strided layout a
Ord)

-- | Wrapper without stride padding. Use for single values (push constants, lone UBOs).
newtype Packed (layout :: MemoryLayout) a = Packed {forall (layout :: MemoryLayout) a. Packed layout a -> a
unPacked :: a}
  deriving ((forall x. Packed layout a -> Rep (Packed layout a) x)
-> (forall x. Rep (Packed layout a) x -> Packed layout a)
-> Generic (Packed layout a)
forall x. Rep (Packed layout a) x -> Packed layout a
forall x. Packed layout a -> Rep (Packed layout a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (layout :: MemoryLayout) a x.
Rep (Packed layout a) x -> Packed layout a
forall (layout :: MemoryLayout) a x.
Packed layout a -> Rep (Packed layout a) x
$cfrom :: forall (layout :: MemoryLayout) a x.
Packed layout a -> Rep (Packed layout a) x
from :: forall x. Packed layout a -> Rep (Packed layout a) x
$cto :: forall (layout :: MemoryLayout) a x.
Rep (Packed layout a) x -> Packed layout a
to :: forall x. Rep (Packed layout a) x -> Packed layout a
Generic, Typeable, Int -> Packed layout a -> ShowS
[Packed layout a] -> ShowS
Packed layout a -> String
(Int -> Packed layout a -> ShowS)
-> (Packed layout a -> String)
-> ([Packed layout a] -> ShowS)
-> Show (Packed layout a)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (layout :: MemoryLayout) a.
Show a =>
Int -> Packed layout a -> ShowS
forall (layout :: MemoryLayout) a.
Show a =>
[Packed layout a] -> ShowS
forall (layout :: MemoryLayout) a.
Show a =>
Packed layout a -> String
$cshowsPrec :: forall (layout :: MemoryLayout) a.
Show a =>
Int -> Packed layout a -> ShowS
showsPrec :: Int -> Packed layout a -> ShowS
$cshow :: forall (layout :: MemoryLayout) a.
Show a =>
Packed layout a -> String
show :: Packed layout a -> String
$cshowList :: forall (layout :: MemoryLayout) a.
Show a =>
[Packed layout a] -> ShowS
showList :: [Packed layout a] -> ShowS
Show, Packed layout a -> Packed layout a -> Bool
(Packed layout a -> Packed layout a -> Bool)
-> (Packed layout a -> Packed layout a -> Bool)
-> Eq (Packed layout a)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (layout :: MemoryLayout) a.
Eq a =>
Packed layout a -> Packed layout a -> Bool
$c== :: forall (layout :: MemoryLayout) a.
Eq a =>
Packed layout a -> Packed layout a -> Bool
== :: Packed layout a -> Packed layout a -> Bool
$c/= :: forall (layout :: MemoryLayout) a.
Eq a =>
Packed layout a -> Packed layout a -> Bool
/= :: Packed layout a -> Packed layout a -> Bool
Eq, Eq (Packed layout a)
Eq (Packed layout a) =>
(Packed layout a -> Packed layout a -> Ordering)
-> (Packed layout a -> Packed layout a -> Bool)
-> (Packed layout a -> Packed layout a -> Bool)
-> (Packed layout a -> Packed layout a -> Bool)
-> (Packed layout a -> Packed layout a -> Bool)
-> (Packed layout a -> Packed layout a -> Packed layout a)
-> (Packed layout a -> Packed layout a -> Packed layout a)
-> Ord (Packed layout a)
Packed layout a -> Packed layout a -> Bool
Packed layout a -> Packed layout a -> Ordering
Packed layout a -> Packed layout a -> Packed layout a
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall (layout :: MemoryLayout) a. Ord a => Eq (Packed layout a)
forall (layout :: MemoryLayout) a.
Ord a =>
Packed layout a -> Packed layout a -> Bool
forall (layout :: MemoryLayout) a.
Ord a =>
Packed layout a -> Packed layout a -> Ordering
forall (layout :: MemoryLayout) a.
Ord a =>
Packed layout a -> Packed layout a -> Packed layout a
$ccompare :: forall (layout :: MemoryLayout) a.
Ord a =>
Packed layout a -> Packed layout a -> Ordering
compare :: Packed layout a -> Packed layout a -> Ordering
$c< :: forall (layout :: MemoryLayout) a.
Ord a =>
Packed layout a -> Packed layout a -> Bool
< :: Packed layout a -> Packed layout a -> Bool
$c<= :: forall (layout :: MemoryLayout) a.
Ord a =>
Packed layout a -> Packed layout a -> Bool
<= :: Packed layout a -> Packed layout a -> Bool
$c> :: forall (layout :: MemoryLayout) a.
Ord a =>
Packed layout a -> Packed layout a -> Bool
> :: Packed layout a -> Packed layout a -> Bool
$c>= :: forall (layout :: MemoryLayout) a.
Ord a =>
Packed layout a -> Packed layout a -> Bool
>= :: Packed layout a -> Packed layout a -> Bool
$cmax :: forall (layout :: MemoryLayout) a.
Ord a =>
Packed layout a -> Packed layout a -> Packed layout a
max :: Packed layout a -> Packed layout a -> Packed layout a
$cmin :: forall (layout :: MemoryLayout) a.
Ord a =>
Packed layout a -> Packed layout a -> Packed layout a
min :: Packed layout a -> Packed layout a -> Packed layout a
Ord)

-- | A convenience type for Data.Vector.Storable.Vector (Strided layout a)
type StridedVector (layout :: MemoryLayout) a = SV.Vector (Strided layout a)

-- | Opt-in 'copyBytes' for fixed-size arrays. Parameterize your struct by layout:
--
-- @
-- data MyStruct layout = MyStruct { pixels :: AlignedArray layout 64 (V4 Float) }
-- @
newtype AlignedArray (layout :: MemoryLayout) (n :: Nat) a = AlignedArray
  {forall (layout :: MemoryLayout) (n :: Nat) a.
AlignedArray layout n a -> Vector n (Strided layout a)
unAlignedArray :: SSV.Vector n (Strided layout a)}
  deriving ((forall x.
 AlignedArray layout n a -> Rep (AlignedArray layout n a) x)
-> (forall x.
    Rep (AlignedArray layout n a) x -> AlignedArray layout n a)
-> Generic (AlignedArray layout n a)
forall x.
Rep (AlignedArray layout n a) x -> AlignedArray layout n a
forall x.
AlignedArray layout n a -> Rep (AlignedArray layout n a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (layout :: MemoryLayout) (n :: Nat) a x.
Rep (AlignedArray layout n a) x -> AlignedArray layout n a
forall (layout :: MemoryLayout) (n :: Nat) a x.
AlignedArray layout n a -> Rep (AlignedArray layout n a) x
$cfrom :: forall (layout :: MemoryLayout) (n :: Nat) a x.
AlignedArray layout n a -> Rep (AlignedArray layout n a) x
from :: forall x.
AlignedArray layout n a -> Rep (AlignedArray layout n a) x
$cto :: forall (layout :: MemoryLayout) (n :: Nat) a x.
Rep (AlignedArray layout n a) x -> AlignedArray layout n a
to :: forall x.
Rep (AlignedArray layout n a) x -> AlignedArray layout n a
Generic, Typeable, Int -> AlignedArray layout n a -> ShowS
[AlignedArray layout n a] -> ShowS
AlignedArray layout n a -> String
(Int -> AlignedArray layout n a -> ShowS)
-> (AlignedArray layout n a -> String)
-> ([AlignedArray layout n a] -> ShowS)
-> Show (AlignedArray layout n a)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (layout :: MemoryLayout) (n :: Nat) a.
(Show a, AlignedStorable layout a) =>
Int -> AlignedArray layout n a -> ShowS
forall (layout :: MemoryLayout) (n :: Nat) a.
(Show a, AlignedStorable layout a) =>
[AlignedArray layout n a] -> ShowS
forall (layout :: MemoryLayout) (n :: Nat) a.
(Show a, AlignedStorable layout a) =>
AlignedArray layout n a -> String
$cshowsPrec :: forall (layout :: MemoryLayout) (n :: Nat) a.
(Show a, AlignedStorable layout a) =>
Int -> AlignedArray layout n a -> ShowS
showsPrec :: Int -> AlignedArray layout n a -> ShowS
$cshow :: forall (layout :: MemoryLayout) (n :: Nat) a.
(Show a, AlignedStorable layout a) =>
AlignedArray layout n a -> String
show :: AlignedArray layout n a -> String
$cshowList :: forall (layout :: MemoryLayout) (n :: Nat) a.
(Show a, AlignedStorable layout a) =>
[AlignedArray layout n a] -> ShowS
showList :: [AlignedArray layout n a] -> ShowS
Show, AlignedArray layout n a -> AlignedArray layout n a -> Bool
(AlignedArray layout n a -> AlignedArray layout n a -> Bool)
-> (AlignedArray layout n a -> AlignedArray layout n a -> Bool)
-> Eq (AlignedArray layout n a)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (layout :: MemoryLayout) (n :: Nat) a.
(AlignedStorable layout a, Eq a) =>
AlignedArray layout n a -> AlignedArray layout n a -> Bool
$c== :: forall (layout :: MemoryLayout) (n :: Nat) a.
(AlignedStorable layout a, Eq a) =>
AlignedArray layout n a -> AlignedArray layout n a -> Bool
== :: AlignedArray layout n a -> AlignedArray layout n a -> Bool
$c/= :: forall (layout :: MemoryLayout) (n :: Nat) a.
(AlignedStorable layout a, Eq a) =>
AlignedArray layout n a -> AlignedArray layout n a -> Bool
/= :: AlignedArray layout n a -> AlignedArray layout n a -> Bool
Eq, Eq (AlignedArray layout n a)
Eq (AlignedArray layout n a) =>
(AlignedArray layout n a -> AlignedArray layout n a -> Ordering)
-> (AlignedArray layout n a -> AlignedArray layout n a -> Bool)
-> (AlignedArray layout n a -> AlignedArray layout n a -> Bool)
-> (AlignedArray layout n a -> AlignedArray layout n a -> Bool)
-> (AlignedArray layout n a -> AlignedArray layout n a -> Bool)
-> (AlignedArray layout n a
    -> AlignedArray layout n a -> AlignedArray layout n a)
-> (AlignedArray layout n a
    -> AlignedArray layout n a -> AlignedArray layout n a)
-> Ord (AlignedArray layout n a)
AlignedArray layout n a -> AlignedArray layout n a -> Bool
AlignedArray layout n a -> AlignedArray layout n a -> Ordering
AlignedArray layout n a
-> AlignedArray layout n a -> AlignedArray layout n a
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall (layout :: MemoryLayout) (n :: Nat) a.
(AlignedStorable layout a, Ord a) =>
Eq (AlignedArray layout n a)
forall (layout :: MemoryLayout) (n :: Nat) a.
(AlignedStorable layout a, Ord a) =>
AlignedArray layout n a -> AlignedArray layout n a -> Bool
forall (layout :: MemoryLayout) (n :: Nat) a.
(AlignedStorable layout a, Ord a) =>
AlignedArray layout n a -> AlignedArray layout n a -> Ordering
forall (layout :: MemoryLayout) (n :: Nat) a.
(AlignedStorable layout a, Ord a) =>
AlignedArray layout n a
-> AlignedArray layout n a -> AlignedArray layout n a
$ccompare :: forall (layout :: MemoryLayout) (n :: Nat) a.
(AlignedStorable layout a, Ord a) =>
AlignedArray layout n a -> AlignedArray layout n a -> Ordering
compare :: AlignedArray layout n a -> AlignedArray layout n a -> Ordering
$c< :: forall (layout :: MemoryLayout) (n :: Nat) a.
(AlignedStorable layout a, Ord a) =>
AlignedArray layout n a -> AlignedArray layout n a -> Bool
< :: AlignedArray layout n a -> AlignedArray layout n a -> Bool
$c<= :: forall (layout :: MemoryLayout) (n :: Nat) a.
(AlignedStorable layout a, Ord a) =>
AlignedArray layout n a -> AlignedArray layout n a -> Bool
<= :: AlignedArray layout n a -> AlignedArray layout n a -> Bool
$c> :: forall (layout :: MemoryLayout) (n :: Nat) a.
(AlignedStorable layout a, Ord a) =>
AlignedArray layout n a -> AlignedArray layout n a -> Bool
> :: AlignedArray layout n a -> AlignedArray layout n a -> Bool
$c>= :: forall (layout :: MemoryLayout) (n :: Nat) a.
(AlignedStorable layout a, Ord a) =>
AlignedArray layout n a -> AlignedArray layout n a -> Bool
>= :: AlignedArray layout n a -> AlignedArray layout n a -> Bool
$cmax :: forall (layout :: MemoryLayout) (n :: Nat) a.
(AlignedStorable layout a, Ord a) =>
AlignedArray layout n a
-> AlignedArray layout n a -> AlignedArray layout n a
max :: AlignedArray layout n a
-> AlignedArray layout n a -> AlignedArray layout n a
$cmin :: forall (layout :: MemoryLayout) (n :: Nat) a.
(AlignedStorable layout a, Ord a) =>
AlignedArray layout n a
-> AlignedArray layout n a -> AlignedArray layout n a
min :: AlignedArray layout n a
-> AlignedArray layout n a -> AlignedArray layout n a
Ord)

-- | Construct an 'AlignedArray' from a sized vector.
mkAlignedArray
  :: (AlignedStorable layout a, Storable a) => SSV.Vector n a -> AlignedArray layout n a
mkAlignedArray :: forall (layout :: MemoryLayout) a (n :: Nat).
(AlignedStorable layout a, Storable a) =>
Vector n a -> AlignedArray layout n a
mkAlignedArray = Vector n (Strided layout a) -> AlignedArray layout n a
forall (layout :: MemoryLayout) (n :: Nat) a.
Vector n (Strided layout a) -> AlignedArray layout n a
AlignedArray (Vector n (Strided layout a) -> AlignedArray layout n a)
-> (Vector n a -> Vector n (Strided layout a))
-> Vector n a
-> AlignedArray layout n a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Strided layout a)
-> Vector n a -> Vector n (Strided layout a)
forall a b (n :: Nat).
(Storable a, Storable b) =>
(a -> b) -> Vector n a -> Vector n b
SSV.map a -> Strided layout a
forall (layout :: MemoryLayout) a. a -> Strided layout a
Strided
{-# INLINE CONLIKE mkAlignedArray #-}

-- | Helper function to unwrap an 'AlignedArray' and manipulate its contents.
-- Don't do unsafe pointer tricks in the closure.
withAlignedArray
  :: AlignedArray layout n a
  -> (SSV.Vector n (Strided layout a) -> SSV.Vector n (Strided layout a))
  -> AlignedArray layout n a
withAlignedArray :: forall (layout :: MemoryLayout) (n :: Nat) a.
AlignedArray layout n a
-> (Vector n (Strided layout a) -> Vector n (Strided layout a))
-> AlignedArray layout n a
withAlignedArray (AlignedArray Vector n (Strided layout a)
v) Vector n (Strided layout a) -> Vector n (Strided layout a)
f = Vector n (Strided layout a) -> AlignedArray layout n a
forall (layout :: MemoryLayout) (n :: Nat) a.
Vector n (Strided layout a) -> AlignedArray layout n a
AlignedArray (Vector n (Strided layout a) -> Vector n (Strided layout a)
f Vector n (Strided layout a)
v)
{-# INLINE withAlignedArray #-}

-- | A 'Ptr' that is tagged with its 'MemoryLayout'.
newtype AlignedPtr (layout :: MemoryLayout) a = AlignedPtr {forall (layout :: MemoryLayout) a. AlignedPtr layout a -> Ptr a
unAlignedPtr :: Ptr a}
  deriving ((forall x. AlignedPtr layout a -> Rep (AlignedPtr layout a) x)
-> (forall x. Rep (AlignedPtr layout a) x -> AlignedPtr layout a)
-> Generic (AlignedPtr layout a)
forall x. Rep (AlignedPtr layout a) x -> AlignedPtr layout a
forall x. AlignedPtr layout a -> Rep (AlignedPtr layout a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (layout :: MemoryLayout) a x.
Rep (AlignedPtr layout a) x -> AlignedPtr layout a
forall (layout :: MemoryLayout) a x.
AlignedPtr layout a -> Rep (AlignedPtr layout a) x
$cfrom :: forall (layout :: MemoryLayout) a x.
AlignedPtr layout a -> Rep (AlignedPtr layout a) x
from :: forall x. AlignedPtr layout a -> Rep (AlignedPtr layout a) x
$cto :: forall (layout :: MemoryLayout) a x.
Rep (AlignedPtr layout a) x -> AlignedPtr layout a
to :: forall x. Rep (AlignedPtr layout a) x -> AlignedPtr layout a
Generic, Typeable, Int -> AlignedPtr layout a -> ShowS
[AlignedPtr layout a] -> ShowS
AlignedPtr layout a -> String
(Int -> AlignedPtr layout a -> ShowS)
-> (AlignedPtr layout a -> String)
-> ([AlignedPtr layout a] -> ShowS)
-> Show (AlignedPtr layout a)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (layout :: MemoryLayout) a.
Int -> AlignedPtr layout a -> ShowS
forall (layout :: MemoryLayout) a. [AlignedPtr layout a] -> ShowS
forall (layout :: MemoryLayout) a. AlignedPtr layout a -> String
$cshowsPrec :: forall (layout :: MemoryLayout) a.
Int -> AlignedPtr layout a -> ShowS
showsPrec :: Int -> AlignedPtr layout a -> ShowS
$cshow :: forall (layout :: MemoryLayout) a. AlignedPtr layout a -> String
show :: AlignedPtr layout a -> String
$cshowList :: forall (layout :: MemoryLayout) a. [AlignedPtr layout a] -> ShowS
showList :: [AlignedPtr layout a] -> ShowS
Show)

type role AlignedPtr nominal nominal

-- | A class for types that have calculable layouts according to GPU requirements.
--
-- __NB__: `alignedPoke` only writes member data. Only poke into zeroed buffers
-- unless you really enjoy parsing through garbage in RenderDoc.
class (MemoryLayoutRules layout) => AlignedStorable (layout :: MemoryLayout) a where
  -- | The size of the type 'a' after its contents are laid out, but *before*
  -- any final padding is applied to the container struct itself. This is
  -- the offset after the last member.
  packedAlignedSizeOf :: Proxy layout -> Proxy a -> Int
  default packedAlignedSizeOf
    :: (GAlignedStorable layout (Rep a))
    => Proxy layout
    -> Proxy a
    -> Int
  packedAlignedSizeOf Proxy layout
l Proxy a
_ = (Int, Int) -> Int
forall a b. (a, b) -> a
fst (Proxy layout -> Proxy (Rep a) -> Int -> (Int, Int)
forall (layout :: MemoryLayout) (rep :: * -> *).
GAlignedStorable layout rep =>
Proxy layout -> Proxy rep -> Int -> (Int, Int)
galignedSize Proxy layout
l (forall {k} (t :: k). Proxy t
forall (t :: * -> *). Proxy t
Proxy @(Rep a)) Int
0)
  {-# INLINE packedAlignedSizeOf #-}

  -- | The size of the type 'a' including final padding/rounding according to the
  -- layout rules for a struct. For `Std140`, this means the size is rounded
  -- up to a multiple of 16.
  alignedSizeOf :: Proxy layout -> Proxy a -> Int
  default alignedSizeOf
    :: (GAlignedStorable layout (Rep a))
    => Proxy layout
    -> Proxy a
    -> Int
  alignedSizeOf Proxy layout
l Proxy a
_ =
    let (!Int
s, !Int
a) = Proxy layout -> Proxy (Rep a) -> Int -> (Int, Int)
forall (layout :: MemoryLayout) (rep :: * -> *).
GAlignedStorable layout rep =>
Proxy layout -> Proxy rep -> Int -> (Int, Int)
galignedSize Proxy layout
l (forall {k} (t :: k). Proxy t
forall (t :: * -> *). Proxy t
Proxy @(Rep a)) Int
0
        !structAlign :: Int
structAlign = Proxy layout -> Int -> Int
forall (layout :: MemoryLayout).
MemoryLayoutRules layout =>
Proxy layout -> Int -> Int
alignBlock Proxy layout
l Int
a
     in Proxy layout -> Int -> Int -> Int
forall (layout :: MemoryLayout).
MemoryLayoutRules layout =>
Proxy layout -> Int -> Int -> Int
roundStructSize Proxy layout
l Int
s Int
structAlign
  {-# INLINE alignedSizeOf #-}

  -- | The base alignment requirement for the type 'a'.
  alignedAlignment :: Proxy layout -> Proxy a -> Int
  default alignedAlignment
    :: (GAlignedStorable layout (Rep a))
    => Proxy layout
    -> Proxy a
    -> Int
  alignedAlignment Proxy layout
l Proxy a
_ =
    let (Int
_, !Int
a) = Proxy layout -> Proxy (Rep a) -> Int -> (Int, Int)
forall (layout :: MemoryLayout) (rep :: * -> *).
GAlignedStorable layout rep =>
Proxy layout -> Proxy rep -> Int -> (Int, Int)
galignedSize Proxy layout
l (forall {k} (t :: k). Proxy t
forall (t :: * -> *). Proxy t
Proxy @(Rep a)) Int
0
     in Proxy layout -> Int -> Int
forall (layout :: MemoryLayout).
MemoryLayoutRules layout =>
Proxy layout -> Int -> Int
alignBlock Proxy layout
l Int
a
  {-# INLINE alignedAlignment #-}

  -- | Read a value from the given pointer, respecting the layout rules.
  alignedPeek :: AlignedPtr layout a -> IO a
  default alignedPeek
    :: (Generic a, GAlignedStorable layout (Rep a))
    => AlignedPtr layout a
    -> IO a
  alignedPeek (AlignedPtr Ptr a
ptr) = Rep a Any -> a
forall a x. Generic a => Rep a x -> a
forall x. Rep a x -> a
to (Rep a Any -> a)
-> ((Rep a Any, Int) -> Rep a Any) -> (Rep a Any, Int) -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Rep a Any, Int) -> Rep a Any
forall a b. (a, b) -> a
fst ((Rep a Any, Int) -> a) -> IO (Rep a Any, Int) -> IO a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (layout :: MemoryLayout) (rep :: * -> *) a.
GAlignedStorable layout rep =>
AlignedPtr layout a -> Int -> IO (rep a, Int)
galignedPeek @layout (Ptr Any -> AlignedPtr layout Any
forall (layout :: MemoryLayout) a. Ptr a -> AlignedPtr layout a
AlignedPtr (Ptr a -> Ptr Any
forall a b. Ptr a -> Ptr b
castPtr Ptr a
ptr)) Int
0
  {-# INLINE alignedPeek #-}

  -- | Write a value to the given pointer, respecting the layout rules.
  alignedPoke :: AlignedPtr layout a -> a -> IO ()
  default alignedPoke
    :: (Generic a, GAlignedStorable layout (Rep a))
    => AlignedPtr layout a
    -> a
    -> IO ()
  alignedPoke (AlignedPtr Ptr a
ptr) a
val = IO Int -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO Int -> IO ()) -> IO Int -> IO ()
forall a b. (a -> b) -> a -> b
$ forall (layout :: MemoryLayout) (rep :: * -> *) a.
GAlignedStorable layout rep =>
AlignedPtr layout a -> rep a -> Int -> IO Int
galignedPoke @layout (Ptr Any -> AlignedPtr layout Any
forall (layout :: MemoryLayout) a. Ptr a -> AlignedPtr layout a
AlignedPtr (Ptr a -> Ptr Any
forall a b. Ptr a -> Ptr b
castPtr Ptr a
ptr)) (a -> Rep a Any
forall x. a -> Rep a x
forall a x. Generic a => a -> Rep a x
from a
val) Int
0
  {-# INLINE alignedPoke #-}

-- | @sizeOf @(Strided layout a)@ calculates the full stride of the type,
-- including final padding, making it suitable for array allocations.
--
-- Use zeroed buffers when using this newtype.
instance (MemoryLayoutRules layout, AlignedStorable layout a) => Storable (Strided layout a) where
  sizeOf :: Strided layout a -> Int
sizeOf Strided layout a
_ =
    Proxy layout -> Int -> Int -> Int
forall (layout :: MemoryLayout).
MemoryLayoutRules layout =>
Proxy layout -> Int -> Int -> Int
layoutStride
      (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout)
      (Proxy layout -> Proxy a -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
alignedSizeOf (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @a))
      (Proxy layout -> Proxy a -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
alignedAlignment (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @a))
  {-# INLINE sizeOf #-}
  alignment :: Strided layout a -> Int
alignment Strided layout a
_ = Proxy layout -> Proxy a -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
alignedAlignment (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @a)
  {-# INLINE alignment #-}
  peek :: Ptr (Strided layout a) -> IO (Strided layout a)
peek Ptr (Strided layout a)
ptr = a -> Strided layout a
forall (layout :: MemoryLayout) a. a -> Strided layout a
Strided (a -> Strided layout a) -> IO a -> IO (Strided layout a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
AlignedPtr layout a -> IO a
alignedPeek @layout (Ptr a -> AlignedPtr layout a
forall (layout :: MemoryLayout) a. Ptr a -> AlignedPtr layout a
AlignedPtr (Ptr (Strided layout a) -> Ptr a
forall a b. Ptr a -> Ptr b
castPtr Ptr (Strided layout a)
ptr))
  {-# INLINE peek #-}
  poke :: Ptr (Strided layout a) -> Strided layout a -> IO ()
poke Ptr (Strided layout a)
ptr Strided layout a
a = forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
AlignedPtr layout a -> a -> IO ()
alignedPoke @layout (Ptr a -> AlignedPtr layout a
forall (layout :: MemoryLayout) a. Ptr a -> AlignedPtr layout a
AlignedPtr (Ptr (Strided layout a) -> Ptr a
forall a b. Ptr a -> Ptr b
castPtr Ptr (Strided layout a)
ptr)) (Strided layout a -> a
forall a b. Coercible a b => a -> b
coerce Strided layout a
a :: a)
  {-# INLINE poke #-}

instance (AlignedStorable layout a) => Storable (Packed layout a) where
  sizeOf :: Packed layout a -> Int
sizeOf Packed layout a
_ = Proxy layout -> Proxy a -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
alignedSizeOf (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @a)
  {-# INLINE sizeOf #-}
  alignment :: Packed layout a -> Int
alignment Packed layout a
_ = Proxy layout -> Proxy a -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
alignedAlignment (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @a)
  {-# INLINE alignment #-}
  peek :: Ptr (Packed layout a) -> IO (Packed layout a)
peek Ptr (Packed layout a)
ptr = a -> Packed layout a
forall (layout :: MemoryLayout) a. a -> Packed layout a
Packed (a -> Packed layout a) -> IO a -> IO (Packed layout a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
AlignedPtr layout a -> IO a
alignedPeek @layout (Ptr a -> AlignedPtr layout a
forall (layout :: MemoryLayout) a. Ptr a -> AlignedPtr layout a
AlignedPtr (Ptr (Packed layout a) -> Ptr a
forall a b. Ptr a -> Ptr b
castPtr Ptr (Packed layout a)
ptr))
  {-# INLINE peek #-}
  poke :: Ptr (Packed layout a) -> Packed layout a -> IO ()
poke Ptr (Packed layout a)
ptr Packed layout a
a = forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
AlignedPtr layout a -> a -> IO ()
alignedPoke @layout (Ptr a -> AlignedPtr layout a
forall (layout :: MemoryLayout) a. Ptr a -> AlignedPtr layout a
AlignedPtr (Ptr (Packed layout a) -> Ptr a
forall a b. Ptr a -> Ptr b
castPtr Ptr (Packed layout a)
ptr)) (Packed layout a -> a
forall a b. Coercible a b => a -> b
coerce Packed layout a
a :: a)
  {-# INLINE poke #-}

--------------------------------------------------------------------------------
-- Generic deriving
--------------------------------------------------------------------------------

-- | Generically derive 'AlignedStorable'.
--
-- > data MyType = MyType { field1 :: Float, field2 :: V3 Float }
-- >   deriving (Generic)
-- >
-- > instance AlignedStorable Std140 MyType
class GAlignedStorable (layout :: MemoryLayout) (rep :: Type -> Type) where
  galignedSize :: Proxy layout -> Proxy rep -> Int -> (Int, Int)
  galignedPoke :: AlignedPtr layout a -> rep a -> Int -> IO Int
  galignedPeek :: AlignedPtr layout a -> Int -> IO (rep a, Int)

instance
  ( TypeError
      (Text "Cannot derive AlignedStorable for empty data types as there is no shader equivalent.")
  )
  => GAlignedStorable layout V1
  where
  galignedSize :: Proxy layout -> Proxy V1 -> Int -> (Int, Int)
galignedSize = String -> Proxy layout -> Proxy V1 -> Int -> (Int, Int)
forall a. HasCallStack => String -> a
error String
"unreachable: empty data type"
  galignedPoke :: forall a. AlignedPtr layout a -> V1 a -> Int -> IO Int
galignedPoke = String -> AlignedPtr layout a -> V1 a -> Int -> IO Int
forall a. HasCallStack => String -> a
error String
"unreachable: empty data type"
  galignedPeek :: forall a. AlignedPtr layout a -> Int -> IO (V1 a, Int)
galignedPeek = String -> AlignedPtr layout a -> Int -> IO (V1 a, Int)
forall a. HasCallStack => String -> a
error String
"unreachable: empty data type"

instance
  ( TypeError
      (Text "Cannot derive AlignedStorable for nullary constructors as there is no shader equivalent.")
  )
  => GAlignedStorable layout U1
  where
  galignedSize :: Proxy layout -> Proxy U1 -> Int -> (Int, Int)
galignedSize = String -> Proxy layout -> Proxy U1 -> Int -> (Int, Int)
forall a. HasCallStack => String -> a
error String
"unreachable: nullary constructor"
  galignedPoke :: forall a. AlignedPtr layout a -> U1 a -> Int -> IO Int
galignedPoke = String -> AlignedPtr layout a -> U1 a -> Int -> IO Int
forall a. HasCallStack => String -> a
error String
"unreachable: nullary constructor"
  galignedPeek :: forall a. AlignedPtr layout a -> Int -> IO (U1 a, Int)
galignedPeek = String -> AlignedPtr layout a -> Int -> IO (U1 a, Int)
forall a. HasCallStack => String -> a
error String
"unreachable: nullary constructor"

instance
  ( TypeError
      ( Text
          "Cannot derive AlignedStorable for sum types as there is no unambiguous shader equivalent."
      )
  )
  => GAlignedStorable layout (a :+: b)
  where
  galignedSize :: Proxy layout -> Proxy (a :+: b) -> Int -> (Int, Int)
galignedSize = String -> Proxy layout -> Proxy (a :+: b) -> Int -> (Int, Int)
forall a. HasCallStack => String -> a
error String
"unreachable: sum type"
  galignedPoke :: forall a. AlignedPtr layout a -> (:+:) a b a -> Int -> IO Int
galignedPoke = String -> AlignedPtr layout a -> (:+:) a b a -> Int -> IO Int
forall a. HasCallStack => String -> a
error String
"unreachable: sum type"
  galignedPeek :: forall a. AlignedPtr layout a -> Int -> IO ((:+:) a b a, Int)
galignedPeek = String -> AlignedPtr layout a -> Int -> IO ((:+:) a b a, Int)
forall a. HasCallStack => String -> a
error String
"unreachable: sum type"

instance (AlignedStorable layout c) => GAlignedStorable layout (K1 i c) where
  galignedSize :: Proxy layout -> Proxy (K1 i c) -> Int -> (Int, Int)
galignedSize Proxy layout
l Proxy (K1 i c)
_ Int
off =
    let !a :: Int
a = Proxy layout -> Proxy c -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
alignedAlignment Proxy layout
l (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @c)
        !s :: Int
s = Proxy layout -> Proxy c -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
alignedSizeOf Proxy layout
l (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @c)
        !off' :: Int
off' = Int -> Int -> Int
forall a. (Bits a, Num a) => a -> a -> a
roundUpTo Int
a Int
off
     in (Int
off' Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
s, Int
a)
  {-# INLINE galignedSize #-}
  galignedPoke :: forall a. AlignedPtr layout a -> K1 i c a -> Int -> IO Int
galignedPoke (AlignedPtr Ptr a
ptr) (K1 !c
v) !Int
off = do
    let !a :: Int
a = Proxy layout -> Proxy c -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
alignedAlignment (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @c)
        !s :: Int
s = Proxy layout -> Proxy c -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
alignedSizeOf (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @c)
        !off' :: Int
off' = Int -> Int -> Int
forall a. (Bits a, Num a) => a -> a -> a
roundUpTo Int
a Int
off
    forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
AlignedPtr layout a -> a -> IO ()
alignedPoke @layout (Ptr c -> AlignedPtr layout c
forall (layout :: MemoryLayout) a. Ptr a -> AlignedPtr layout a
AlignedPtr (Ptr a
ptr Ptr a -> Int -> Ptr c
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
off')) c
v
    Int -> IO Int
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
off' Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
s)
  {-# INLINE galignedPoke #-}
  galignedPeek :: forall a. AlignedPtr layout a -> Int -> IO (K1 i c a, Int)
galignedPeek (AlignedPtr Ptr a
ptr) !Int
off = do
    let !a :: Int
a = Proxy layout -> Proxy c -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
alignedAlignment (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @c)
        !s :: Int
s = Proxy layout -> Proxy c -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
alignedSizeOf (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @c)
        !off' :: Int
off' = Int -> Int -> Int
forall a. (Bits a, Num a) => a -> a -> a
roundUpTo Int
a Int
off
    !c
v <- forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
AlignedPtr layout a -> IO a
alignedPeek @layout (Ptr c -> AlignedPtr layout c
forall (layout :: MemoryLayout) a. Ptr a -> AlignedPtr layout a
AlignedPtr (Ptr a
ptr Ptr a -> Int -> Ptr c
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
off'))
    (K1 i c a, Int) -> IO (K1 i c a, Int)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (c -> K1 i c a
forall k i c (p :: k). c -> K1 i c p
K1 c
v, Int
off' Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
s)
  {-# INLINE galignedPeek #-}

instance (GAlignedStorable layout a, GAlignedStorable layout b) => GAlignedStorable layout (a :*: b) where
  galignedSize :: Proxy layout -> Proxy (a :*: b) -> Int -> (Int, Int)
galignedSize Proxy layout
l Proxy (a :*: b)
_ Int
off =
    let (!Int
nextOffA, !Int
alignA) = Proxy layout -> Proxy a -> Int -> (Int, Int)
forall (layout :: MemoryLayout) (rep :: * -> *).
GAlignedStorable layout rep =>
Proxy layout -> Proxy rep -> Int -> (Int, Int)
galignedSize Proxy layout
l (forall {k} (t :: k). Proxy t
forall (t :: * -> *). Proxy t
Proxy @a) Int
off
        (!Int
nextOffB, !Int
alignB) = Proxy layout -> Proxy b -> Int -> (Int, Int)
forall (layout :: MemoryLayout) (rep :: * -> *).
GAlignedStorable layout rep =>
Proxy layout -> Proxy rep -> Int -> (Int, Int)
galignedSize Proxy layout
l (forall {k} (t :: k). Proxy t
forall (t :: * -> *). Proxy t
Proxy @b) Int
nextOffA
     in (Int
nextOffB, Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
alignA Int
alignB)
  {-# INLINE galignedSize #-}
  galignedPoke :: forall a. AlignedPtr layout a -> (:*:) a b a -> Int -> IO Int
galignedPoke AlignedPtr layout a
ptr (a a
valA :*: b a
valB) !Int
off = do
    !Int
nextOffA <- AlignedPtr layout a -> a a -> Int -> IO Int
forall a. AlignedPtr layout a -> a a -> Int -> IO Int
forall (layout :: MemoryLayout) (rep :: * -> *) a.
GAlignedStorable layout rep =>
AlignedPtr layout a -> rep a -> Int -> IO Int
galignedPoke AlignedPtr layout a
ptr a a
valA Int
off
    AlignedPtr layout a -> b a -> Int -> IO Int
forall a. AlignedPtr layout a -> b a -> Int -> IO Int
forall (layout :: MemoryLayout) (rep :: * -> *) a.
GAlignedStorable layout rep =>
AlignedPtr layout a -> rep a -> Int -> IO Int
galignedPoke AlignedPtr layout a
ptr b a
valB Int
nextOffA
  {-# INLINE galignedPoke #-}
  galignedPeek :: forall a. AlignedPtr layout a -> Int -> IO ((:*:) a b a, Int)
galignedPeek AlignedPtr layout a
ptr Int
off = do
    (!a a
valA, !Int
nextOffA) <- AlignedPtr layout a -> Int -> IO (a a, Int)
forall a. AlignedPtr layout a -> Int -> IO (a a, Int)
forall (layout :: MemoryLayout) (rep :: * -> *) a.
GAlignedStorable layout rep =>
AlignedPtr layout a -> Int -> IO (rep a, Int)
galignedPeek AlignedPtr layout a
ptr Int
off
    (!b a
valB, !Int
nextOffB) <- AlignedPtr layout a -> Int -> IO (b a, Int)
forall a. AlignedPtr layout a -> Int -> IO (b a, Int)
forall (layout :: MemoryLayout) (rep :: * -> *) a.
GAlignedStorable layout rep =>
AlignedPtr layout a -> Int -> IO (rep a, Int)
galignedPeek AlignedPtr layout a
ptr Int
nextOffA
    ((:*:) a b a, Int) -> IO ((:*:) a b a, Int)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a a
valA a a -> b a -> (:*:) a b a
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
:*: b a
valB, Int
nextOffB)
  {-# INLINE galignedPeek #-}

instance (GAlignedStorable layout f) => GAlignedStorable layout (M1 i c f) where
  galignedSize :: Proxy layout -> Proxy (M1 i c f) -> Int -> (Int, Int)
galignedSize Proxy layout
l Proxy (M1 i c f)
_ = Proxy layout -> Proxy f -> Int -> (Int, Int)
forall (layout :: MemoryLayout) (rep :: * -> *).
GAlignedStorable layout rep =>
Proxy layout -> Proxy rep -> Int -> (Int, Int)
galignedSize Proxy layout
l (forall {k} (t :: k). Proxy t
forall (t :: * -> *). Proxy t
Proxy @f)
  {-# INLINE galignedSize #-}
  galignedPoke :: forall a. AlignedPtr layout a -> M1 i c f a -> Int -> IO Int
galignedPoke AlignedPtr layout a
ptr = AlignedPtr layout a -> f a -> Int -> IO Int
forall a. AlignedPtr layout a -> f a -> Int -> IO Int
forall (layout :: MemoryLayout) (rep :: * -> *) a.
GAlignedStorable layout rep =>
AlignedPtr layout a -> rep a -> Int -> IO Int
galignedPoke AlignedPtr layout a
ptr (f a -> Int -> IO Int)
-> (M1 i c f a -> f a) -> M1 i c f a -> Int -> IO Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. M1 i c f a -> f a
forall k i (c :: Meta) (f :: k -> *) (p :: k). M1 i c f p -> f p
unM1
  {-# INLINE galignedPoke #-}
  galignedPeek :: forall a. AlignedPtr layout a -> Int -> IO (M1 i c f a, Int)
galignedPeek AlignedPtr layout a
ptr Int
off = (f a -> M1 i c f a) -> (f a, Int) -> (M1 i c f a, Int)
forall a b c. (a -> b) -> (a, c) -> (b, c)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first f a -> M1 i c f a
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 ((f a, Int) -> (M1 i c f a, Int))
-> IO (f a, Int) -> IO (M1 i c f a, Int)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AlignedPtr layout a -> Int -> IO (f a, Int)
forall a. AlignedPtr layout a -> Int -> IO (f a, Int)
forall (layout :: MemoryLayout) (rep :: * -> *) a.
GAlignedStorable layout rep =>
AlignedPtr layout a -> Int -> IO (rep a, Int)
galignedPeek AlignedPtr layout a
ptr Int
off
  {-# INLINE galignedPeek #-}

--------------------------------------------------------------------------------
-- Sized arrays
--------------------------------------------------------------------------------

instance
  {-# OVERLAPPABLE #-}
  (KnownNat n, AlignedStorable layout a, GV.Vector v a)
  => AlignedStorable layout (SGV.Vector v n a)
  where
  packedAlignedSizeOf :: Proxy layout -> Proxy (Vector v n a) -> Int
packedAlignedSizeOf Proxy layout
_ Proxy (Vector v n a)
_ = Proxy layout -> Proxy n -> Proxy a -> Int
forall (layout :: MemoryLayout) (n :: Nat) a.
(KnownNat n, AlignedStorable layout a) =>
Proxy layout -> Proxy n -> Proxy a -> Int
packedAlignedSizeOfArray (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @n) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @a)
  {-# INLINE packedAlignedSizeOf #-}
  alignedSizeOf :: Proxy layout -> Proxy (Vector v n a) -> Int
alignedSizeOf = Proxy layout -> Proxy (Vector v n a) -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
packedAlignedSizeOf
  {-# INLINE alignedSizeOf #-}
  alignedAlignment :: Proxy layout -> Proxy (Vector v n a) -> Int
alignedAlignment Proxy layout
l Proxy (Vector v n a)
_ = Proxy layout -> Proxy a -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
arrayAlignedAlignment Proxy layout
l (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @a)
  {-# INLINE alignedAlignment #-}
  alignedPeek :: AlignedPtr layout (Vector v n a) -> IO (Vector v n a)
alignedPeek = AlignedPtr layout (Vector v n a) -> IO (Vector v n a)
forall (layout :: MemoryLayout) (n :: Nat) a (v :: * -> *).
(KnownNat n, Vector v a, AlignedStorable layout a) =>
AlignedPtr layout (Vector v n a) -> IO (Vector v n a)
garrayAlignedPeek
  {-# INLINE alignedPeek #-}
  alignedPoke :: AlignedPtr layout (Vector v n a) -> Vector v n a -> IO ()
alignedPoke = AlignedPtr layout (Vector v n a) -> Vector v n a -> IO ()
forall (layout :: MemoryLayout) (n :: Nat) a (v :: * -> *).
(KnownNat n, Vector v a, AlignedStorable layout a) =>
AlignedPtr layout (Vector v n a) -> Vector v n a -> IO ()
garrayAlignedPoke
  {-# INLINE alignedPoke #-}

instance (KnownNat n, AlignedStorable Scalar a, GV.Vector v a) => AlignedStorable Scalar (SGV.Vector v n a) where
  packedAlignedSizeOf :: Proxy 'Scalar -> Proxy (Vector v n a) -> Int
packedAlignedSizeOf Proxy 'Scalar
_ Proxy (Vector v n a)
_ = Proxy n -> Proxy a -> Int
forall (n :: Nat) a.
(KnownNat n, AlignedStorable 'Scalar a) =>
Proxy n -> Proxy a -> Int
scalarPackedAlignedSizeOfArray (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @n) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @a)
  {-# INLINE packedAlignedSizeOf #-}
  alignedSizeOf :: Proxy 'Scalar -> Proxy (Vector v n a) -> Int
alignedSizeOf = Proxy 'Scalar -> Proxy (Vector v n a) -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
packedAlignedSizeOf
  {-# INLINE alignedSizeOf #-}
  alignedAlignment :: Proxy 'Scalar -> Proxy (Vector v n a) -> Int
alignedAlignment Proxy 'Scalar
l Proxy (Vector v n a)
_ = Proxy 'Scalar -> Proxy a -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
arrayAlignedAlignment Proxy 'Scalar
l (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @a)
  {-# INLINE alignedAlignment #-}
  alignedPeek :: AlignedPtr 'Scalar (Vector v n a) -> IO (Vector v n a)
alignedPeek = AlignedPtr 'Scalar (Vector v n a) -> IO (Vector v n a)
forall (layout :: MemoryLayout) (n :: Nat) a (v :: * -> *).
(KnownNat n, Vector v a, AlignedStorable layout a) =>
AlignedPtr layout (Vector v n a) -> IO (Vector v n a)
garrayAlignedPeek
  {-# INLINE alignedPeek #-}
  alignedPoke :: AlignedPtr 'Scalar (Vector v n a) -> Vector v n a -> IO ()
alignedPoke = AlignedPtr 'Scalar (Vector v n a) -> Vector v n a -> IO ()
forall (layout :: MemoryLayout) (n :: Nat) a (v :: * -> *).
(KnownNat n, Vector v a, AlignedStorable layout a) =>
AlignedPtr layout (Vector v n a) -> Vector v n a -> IO ()
garrayAlignedPoke
  {-# INLINE alignedPoke #-}

instance
  {-# OVERLAPPABLE #-}
  (KnownNat n, AlignedStorable layout a)
  => AlignedStorable layout (AlignedArray layout n a)
  where
  packedAlignedSizeOf :: Proxy layout -> Proxy (AlignedArray layout n a) -> Int
packedAlignedSizeOf Proxy layout
_ Proxy (AlignedArray layout n a)
_ = Proxy layout -> Proxy n -> Proxy a -> Int
forall (layout :: MemoryLayout) (n :: Nat) a.
(KnownNat n, AlignedStorable layout a) =>
Proxy layout -> Proxy n -> Proxy a -> Int
packedAlignedSizeOfArray (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @n) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @a)
  {-# INLINE packedAlignedSizeOf #-}
  alignedSizeOf :: Proxy layout -> Proxy (AlignedArray layout n a) -> Int
alignedSizeOf = Proxy layout -> Proxy (AlignedArray layout n a) -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
packedAlignedSizeOf
  {-# INLINE alignedSizeOf #-}
  alignedAlignment :: Proxy layout -> Proxy (AlignedArray layout n a) -> Int
alignedAlignment Proxy layout
l Proxy (AlignedArray layout n a)
_ = Proxy layout -> Proxy a -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
arrayAlignedAlignment Proxy layout
l (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @a)
  {-# INLINE alignedAlignment #-}
  alignedPeek :: AlignedPtr layout (AlignedArray layout n a)
-> IO (AlignedArray layout n a)
alignedPeek (AlignedPtr Ptr (AlignedArray layout n a)
src) = do
    let s :: Int
s = Integer -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer -> Int) -> Integer -> Int
forall a b. (a -> b) -> a -> b
$ Proxy n -> Integer
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @n)
    IOVector (Strided layout a)
v <- Int -> IO (MVector (PrimState IO) (Strided layout a))
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
Int -> m (MVector (PrimState m) a)
SMV.new Int
s
    IOVector (Strided layout a)
-> (Ptr (Strided layout a) -> IO ()) -> IO ()
forall a b. Storable a => IOVector a -> (Ptr a -> IO b) -> IO b
SMV.unsafeWith IOVector (Strided layout a)
v \Ptr (Strided layout a)
dest ->
      Ptr (AlignedArray layout n a)
-> Ptr (AlignedArray layout n a) -> Int -> IO ()
forall a. Ptr a -> Ptr a -> Int -> IO ()
copyBytes (Ptr (Strided layout a) -> Ptr (AlignedArray layout n a)
forall a b. Ptr a -> Ptr b
castPtr Ptr (Strided layout a)
dest) Ptr (AlignedArray layout n a)
src (Proxy layout -> Proxy (AlignedArray layout n a) -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
alignedSizeOf (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(AlignedArray layout n a)))
    Vector n (Strided layout a) -> AlignedArray layout n a
forall (layout :: MemoryLayout) (n :: Nat) a.
Vector n (Strided layout a) -> AlignedArray layout n a
AlignedArray (Vector n (Strided layout a) -> AlignedArray layout n a)
-> (Vector (Strided layout a) -> Vector n (Strided layout a))
-> Vector (Strided layout a)
-> AlignedArray layout n a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe (Vector n (Strided layout a)) -> Vector n (Strided layout a)
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe (Vector n (Strided layout a))
 -> Vector n (Strided layout a))
-> (Vector (Strided layout a)
    -> Maybe (Vector n (Strided layout a)))
-> Vector (Strided layout a)
-> Vector n (Strided layout a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (n :: Nat) a.
(Storable a, KnownNat n) =>
Vector a -> Maybe (Vector n a)
SSV.toSized @n (Vector (Strided layout a) -> AlignedArray layout n a)
-> IO (Vector (Strided layout a)) -> IO (AlignedArray layout n a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MVector (PrimState IO) (Strided layout a)
-> IO (Vector (Strided layout a))
forall a (m :: * -> *).
(Storable a, PrimMonad m) =>
MVector (PrimState m) a -> m (Vector a)
SV.unsafeFreeze IOVector (Strided layout a)
MVector (PrimState IO) (Strided layout a)
v
  {-# INLINE alignedPeek #-}
  alignedPoke :: AlignedPtr layout (AlignedArray layout n a)
-> AlignedArray layout n a -> IO ()
alignedPoke (AlignedPtr Ptr (AlignedArray layout n a)
dest) (AlignedArray Vector n (Strided layout a)
v) = Vector (Strided layout a)
-> (Ptr (Strided layout a) -> IO ()) -> IO ()
forall a b. Storable a => Vector a -> (Ptr a -> IO b) -> IO b
SV.unsafeWith (Vector n (Strided layout a) -> Vector (Strided layout a)
forall (n :: Nat) a. Vector n a -> Vector a
SSV.fromSized Vector n (Strided layout a)
v) \Ptr (Strided layout a)
src ->
    Ptr (AlignedArray layout n a)
-> Ptr (AlignedArray layout n a) -> Int -> IO ()
forall a. Ptr a -> Ptr a -> Int -> IO ()
copyBytes Ptr (AlignedArray layout n a)
dest (Ptr (Strided layout a) -> Ptr (AlignedArray layout n a)
forall a b. Ptr a -> Ptr b
castPtr Ptr (Strided layout a)
src) (Proxy layout -> Proxy (AlignedArray layout n a) -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
alignedSizeOf (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(AlignedArray layout n a)))
  {-# INLINE alignedPoke #-}

instance
  (KnownNat n, AlignedStorable Scalar a)
  => AlignedStorable Scalar (AlignedArray Scalar n a)
  where
  packedAlignedSizeOf :: Proxy 'Scalar -> Proxy (AlignedArray 'Scalar n a) -> Int
packedAlignedSizeOf Proxy 'Scalar
_ Proxy (AlignedArray 'Scalar n a)
_ = Proxy n -> Proxy a -> Int
forall (n :: Nat) a.
(KnownNat n, AlignedStorable 'Scalar a) =>
Proxy n -> Proxy a -> Int
scalarPackedAlignedSizeOfArray (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @n) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @a)
  {-# INLINE packedAlignedSizeOf #-}
  alignedSizeOf :: Proxy 'Scalar -> Proxy (AlignedArray 'Scalar n a) -> Int
alignedSizeOf = Proxy 'Scalar -> Proxy (AlignedArray 'Scalar n a) -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
packedAlignedSizeOf
  {-# INLINE alignedSizeOf #-}
  alignedAlignment :: Proxy 'Scalar -> Proxy (AlignedArray 'Scalar n a) -> Int
alignedAlignment Proxy 'Scalar
l Proxy (AlignedArray 'Scalar n a)
_ = Proxy 'Scalar -> Proxy a -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
arrayAlignedAlignment Proxy 'Scalar
l (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @a)
  {-# INLINE alignedAlignment #-}
  alignedPeek :: AlignedPtr 'Scalar (AlignedArray 'Scalar n a)
-> IO (AlignedArray 'Scalar n a)
alignedPeek (AlignedPtr Ptr (AlignedArray 'Scalar n a)
src) = do
    let s :: Int
s = Integer -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer -> Int) -> Integer -> Int
forall a b. (a -> b) -> a -> b
$ Proxy n -> Integer
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @n)
    IOVector (Strided 'Scalar a)
v <- Int -> IO (MVector (PrimState IO) (Strided 'Scalar a))
forall (m :: * -> *) a.
(PrimMonad m, Storable a) =>
Int -> m (MVector (PrimState m) a)
SMV.new Int
s
    IOVector (Strided 'Scalar a)
-> (Ptr (Strided 'Scalar a) -> IO ()) -> IO ()
forall a b. Storable a => IOVector a -> (Ptr a -> IO b) -> IO b
SMV.unsafeWith IOVector (Strided 'Scalar a)
v \Ptr (Strided 'Scalar a)
dest ->
      Ptr (AlignedArray 'Scalar n a)
-> Ptr (AlignedArray 'Scalar n a) -> Int -> IO ()
forall a. Ptr a -> Ptr a -> Int -> IO ()
copyBytes (Ptr (Strided 'Scalar a) -> Ptr (AlignedArray 'Scalar n a)
forall a b. Ptr a -> Ptr b
castPtr Ptr (Strided 'Scalar a)
dest) Ptr (AlignedArray 'Scalar n a)
src (Proxy 'Scalar -> Proxy (AlignedArray 'Scalar n a) -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
alignedSizeOf (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @Scalar) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(AlignedArray Scalar n a)))
    Vector n (Strided 'Scalar a) -> AlignedArray 'Scalar n a
forall (layout :: MemoryLayout) (n :: Nat) a.
Vector n (Strided layout a) -> AlignedArray layout n a
AlignedArray (Vector n (Strided 'Scalar a) -> AlignedArray 'Scalar n a)
-> (Vector (Strided 'Scalar a) -> Vector n (Strided 'Scalar a))
-> Vector (Strided 'Scalar a)
-> AlignedArray 'Scalar n a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe (Vector n (Strided 'Scalar a))
-> Vector n (Strided 'Scalar a)
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe (Vector n (Strided 'Scalar a))
 -> Vector n (Strided 'Scalar a))
-> (Vector (Strided 'Scalar a)
    -> Maybe (Vector n (Strided 'Scalar a)))
-> Vector (Strided 'Scalar a)
-> Vector n (Strided 'Scalar a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (n :: Nat) a.
(Storable a, KnownNat n) =>
Vector a -> Maybe (Vector n a)
SSV.toSized @n (Vector (Strided 'Scalar a) -> AlignedArray 'Scalar n a)
-> IO (Vector (Strided 'Scalar a)) -> IO (AlignedArray 'Scalar n a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MVector (PrimState IO) (Strided 'Scalar a)
-> IO (Vector (Strided 'Scalar a))
forall a (m :: * -> *).
(Storable a, PrimMonad m) =>
MVector (PrimState m) a -> m (Vector a)
SV.unsafeFreeze IOVector (Strided 'Scalar a)
MVector (PrimState IO) (Strided 'Scalar a)
v
  {-# INLINE alignedPeek #-}
  alignedPoke :: AlignedPtr 'Scalar (AlignedArray 'Scalar n a)
-> AlignedArray 'Scalar n a -> IO ()
alignedPoke (AlignedPtr Ptr (AlignedArray 'Scalar n a)
dest) (AlignedArray Vector n (Strided 'Scalar a)
v) = Vector (Strided 'Scalar a)
-> (Ptr (Strided 'Scalar a) -> IO ()) -> IO ()
forall a b. Storable a => Vector a -> (Ptr a -> IO b) -> IO b
SV.unsafeWith (Vector n (Strided 'Scalar a) -> Vector (Strided 'Scalar a)
forall (n :: Nat) a. Vector n a -> Vector a
SSV.fromSized Vector n (Strided 'Scalar a)
v) \Ptr (Strided 'Scalar a)
src ->
    Ptr (AlignedArray 'Scalar n a)
-> Ptr (AlignedArray 'Scalar n a) -> Int -> IO ()
forall a. Ptr a -> Ptr a -> Int -> IO ()
copyBytes Ptr (AlignedArray 'Scalar n a)
dest (Ptr (Strided 'Scalar a) -> Ptr (AlignedArray 'Scalar n a)
forall a b. Ptr a -> Ptr b
castPtr Ptr (Strided 'Scalar a)
src) (Proxy 'Scalar -> Proxy (AlignedArray 'Scalar n a) -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
alignedSizeOf (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @Scalar) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(AlignedArray Scalar n a)))
  {-# INLINE alignedPoke #-}

packedAlignedSizeOfArray
  :: forall layout n a
   . (KnownNat n, AlignedStorable layout a)
  => Proxy layout
  -> Proxy n
  -> Proxy a
  -> Int
packedAlignedSizeOfArray :: forall (layout :: MemoryLayout) (n :: Nat) a.
(KnownNat n, AlignedStorable layout a) =>
Proxy layout -> Proxy n -> Proxy a -> Int
packedAlignedSizeOfArray Proxy layout
_ Proxy n
_ Proxy a
_ = Integer -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Proxy n -> Integer
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @n)) Int -> Int -> Int
forall a. Num a => a -> a -> a
* forall a. Storable a => a -> Int
sizeOf @(Strided layout a) Strided layout a
forall a. HasCallStack => a
undefined
{-# INLINE packedAlignedSizeOfArray #-}

scalarPackedAlignedSizeOfArray
  :: forall n a
   . (KnownNat n, AlignedStorable Scalar a)
  => Proxy n
  -> Proxy a
  -> Int
scalarPackedAlignedSizeOfArray :: forall (n :: Nat) a.
(KnownNat n, AlignedStorable 'Scalar a) =>
Proxy n -> Proxy a -> Int
scalarPackedAlignedSizeOfArray Proxy n
_ Proxy a
_ =
  let n :: Int
n = Integer -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer -> Int) -> Integer -> Int
forall a b. (a -> b) -> a -> b
$ Proxy n -> Integer
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @n)
      stride :: Int
stride = forall a. Storable a => a -> Int
sizeOf @(Strided Scalar a) Strided 'Scalar a
forall a. HasCallStack => a
undefined
      lastElementSize :: Int
lastElementSize = Proxy 'Scalar -> Proxy a -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
packedAlignedSizeOf (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @Scalar) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @a)
   in if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
        then ((Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
stride) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
lastElementSize
        else Int
0
{-# INLINE scalarPackedAlignedSizeOfArray #-}

arrayAlignedAlignment
  :: forall layout a. (AlignedStorable layout a) => Proxy layout -> Proxy a -> Int
arrayAlignedAlignment :: forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
arrayAlignedAlignment Proxy layout
l Proxy a
a = Proxy layout -> Int -> Int
forall (layout :: MemoryLayout).
MemoryLayoutRules layout =>
Proxy layout -> Int -> Int
alignBlock Proxy layout
l (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ Proxy layout -> Proxy a -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
alignedAlignment Proxy layout
l Proxy a
a
{-# INLINE arrayAlignedAlignment #-}

garrayAlignedPeek
  :: forall layout n a v
   . (KnownNat n, GV.Vector v a, AlignedStorable layout a)
  => AlignedPtr layout (SGV.Vector v n a)
  -> IO (SGV.Vector v n a)
garrayAlignedPeek :: forall (layout :: MemoryLayout) (n :: Nat) a (v :: * -> *).
(KnownNat n, Vector v a, AlignedStorable layout a) =>
AlignedPtr layout (Vector v n a) -> IO (Vector v n a)
garrayAlignedPeek (AlignedPtr Ptr (Vector v n a)
ptr) =
  let !stride :: Int
stride = forall a. Storable a => a -> Int
sizeOf @(Strided layout a) Strided layout a
forall a. HasCallStack => a
undefined
   in (Finite n -> IO a) -> IO (Vector v n a)
forall (v :: * -> *) (n :: Nat) (m :: * -> *) a.
(KnownNat n, Vector v a, Monad m) =>
(Finite n -> m a) -> m (Vector v n a)
SGV.generateM \Finite n
i ->
        forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
AlignedPtr layout a -> IO a
alignedPeek @layout (Ptr a -> AlignedPtr layout a
forall (layout :: MemoryLayout) a. Ptr a -> AlignedPtr layout a
AlignedPtr (Ptr (Vector v n a)
ptr Ptr (Vector v n a) -> Int -> Ptr a
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` (Finite n -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Finite n
i Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
stride)))
{-# INLINE garrayAlignedPeek #-}

garrayAlignedPoke
  :: forall layout n a v
   . (KnownNat n, GV.Vector v a, AlignedStorable layout a)
  => AlignedPtr layout (SGV.Vector v n a)
  -> SGV.Vector v n a
  -> IO ()
garrayAlignedPoke :: forall (layout :: MemoryLayout) (n :: Nat) a (v :: * -> *).
(KnownNat n, Vector v a, AlignedStorable layout a) =>
AlignedPtr layout (Vector v n a) -> Vector v n a -> IO ()
garrayAlignedPoke (AlignedPtr Ptr (Vector v n a)
ptr) =
  let !stride :: Int
stride = forall a. Storable a => a -> Int
sizeOf @(Strided layout a) Strided layout a
forall a. HasCallStack => a
undefined
   in (Int -> a -> IO ()) -> Vector v n a -> IO ()
forall (n :: Nat) (v :: * -> *) a (f :: * -> *).
(Monad f, KnownNat n, Vector v a) =>
(Int -> a -> f ()) -> Vector v n a -> f ()
fusedimapMSized_ \Int
i -> forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
AlignedPtr layout a -> a -> IO ()
alignedPoke @layout (Ptr a -> AlignedPtr layout a
forall (layout :: MemoryLayout) a. Ptr a -> AlignedPtr layout a
AlignedPtr (Ptr (Vector v n a)
ptr Ptr (Vector v n a) -> Int -> Ptr a
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
stride)))
{-# INLINE garrayAlignedPoke #-}

--------------------------------------------------------------------------------
-- Utils
--------------------------------------------------------------------------------

-- | Bit-twiddling hack. Assumes multiple is a power of 2.
-- The assumption holds for all standard GPU layouts.
--
-- __NB__: As of writing, GHC's optimizer fails when optimizing GAlignedStorable
-- if this function branches.
roundUpTo :: (Bits a, Num a) => a -> a -> a
roundUpTo :: forall a. (Bits a, Num a) => a -> a -> a
roundUpTo a
multiple a
val = (a
val a -> a -> a
forall a. Num a => a -> a -> a
+ a
multiple a -> a -> a
forall a. Num a => a -> a -> a
- a
1) a -> a -> a
forall a. Bits a => a -> a -> a
.&. a -> a
forall a. Bits a => a -> a
complement (a
multiple a -> a -> a
forall a. Num a => a -> a -> a
- a
1)
{-# INLINE roundUpTo #-}

-- | Exploits the knowledge of the array length to create a straight, bounded loop over the
-- underlying vector.
fusedimapMSized_
  :: forall n v a f
   . (Monad f, KnownNat n, GV.Vector v a)
  => (Int -> a -> f ())
  -> SGV.Vector v n a
  -> f ()
fusedimapMSized_ :: forall (n :: Nat) (v :: * -> *) a (f :: * -> *).
(Monad f, KnownNat n, Vector v a) =>
(Int -> a -> f ()) -> Vector v n a -> f ()
fusedimapMSized_ Int -> a -> f ()
f Vector v n a
v =
  (Int -> f ()) -> [Int] -> f ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_
    (\Int
i -> Int -> a -> f ()
f Int
i (Vector v n a -> Int -> a
forall (v :: * -> *) (n :: Nat) a.
Vector v a =>
Vector v n a -> Int -> a
SGV.unsafeIndex Vector v n a
v Int
i))
    [Int
0 .. Integer -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Proxy n -> Integer
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (forall (t :: Nat). Proxy t
forall {k} (t :: k). Proxy t
Proxy @n)) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1]
{-# INLINE fusedimapMSized_ #-}

--------------------------------------------------------------------------------
-- Internal helpers used across macros
--------------------------------------------------------------------------------

defaultAlignedPeek :: (Storable a) => AlignedPtr layout a -> IO a
defaultAlignedPeek :: forall a (layout :: MemoryLayout).
Storable a =>
AlignedPtr layout a -> IO a
defaultAlignedPeek (AlignedPtr Ptr a
ptr) = Ptr a -> IO a
forall a. Storable a => Ptr a -> IO a
peek Ptr a
ptr
{-# INLINE defaultAlignedPeek #-}

defaultAlignedPoke :: (Storable a) => AlignedPtr layout a -> a -> IO ()
defaultAlignedPoke :: forall a (layout :: MemoryLayout).
Storable a =>
AlignedPtr layout a -> a -> IO ()
defaultAlignedPoke (AlignedPtr Ptr a
ptr) = Ptr a -> a -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr a
ptr
{-# INLINE defaultAlignedPoke #-}

packedAlignedSizeOfMat
  :: forall layout a f g
   . (AlignedStorable layout (g a))
  => Proxy layout
  -> Proxy (f (g a))
  -> Int
packedAlignedSizeOfMat :: forall (layout :: MemoryLayout) a (f :: * -> *) (g :: * -> *).
AlignedStorable layout (g a) =>
Proxy layout -> Proxy (f (g a)) -> Int
packedAlignedSizeOfMat Proxy layout
l Proxy (f (g a))
_ =
  let rowSize :: Int
rowSize = Proxy layout -> Proxy (g a) -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
packedAlignedSizeOf Proxy layout
l (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(g a))
      rowAlign :: Int
rowAlign = Proxy layout -> Proxy (g a) -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
alignedAlignment Proxy layout
l (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(g a))
   in Proxy layout -> Int -> Int -> Int
forall (layout :: MemoryLayout).
MemoryLayoutRules layout =>
Proxy layout -> Int -> Int -> Int
layoutStride (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) Int
rowSize Int
rowAlign
{-# INLINE packedAlignedSizeOfMat #-}

-- | Unsafe, for internal use only
castAlignedPtr :: forall layout a b. AlignedPtr layout a -> AlignedPtr layout b
castAlignedPtr :: forall (layout :: MemoryLayout) a b.
AlignedPtr layout a -> AlignedPtr layout b
castAlignedPtr (AlignedPtr Ptr a
ptr) = Ptr b -> AlignedPtr layout b
forall (layout :: MemoryLayout) a. Ptr a -> AlignedPtr layout a
AlignedPtr (Ptr a -> Ptr b
forall a b. Ptr a -> Ptr b
castPtr Ptr a
ptr)

-- | Unsafe, for internal use only
alignedPeekByteOff
  :: forall layout a. (AlignedStorable layout a) => AlignedPtr layout a -> Int -> IO a
alignedPeekByteOff :: forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
AlignedPtr layout a -> Int -> IO a
alignedPeekByteOff (AlignedPtr Ptr a
ptr) Int
off = AlignedPtr layout a -> IO a
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
AlignedPtr layout a -> IO a
alignedPeek (forall (layout :: MemoryLayout) a. Ptr a -> AlignedPtr layout a
AlignedPtr @layout (Ptr a
ptr Ptr a -> Int -> Ptr a
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
off))
{-# INLINE alignedPeekByteOff #-}

-- | Unsafe, for internal use only
alignedPokeByteOff
  :: forall layout a. (AlignedStorable layout a) => AlignedPtr layout a -> Int -> a -> IO ()
alignedPokeByteOff :: forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
AlignedPtr layout a -> Int -> a -> IO ()
alignedPokeByteOff (AlignedPtr Ptr a
ptr) Int
off = AlignedPtr layout a -> a -> IO ()
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
AlignedPtr layout a -> a -> IO ()
alignedPoke (forall (layout :: MemoryLayout) a. Ptr a -> AlignedPtr layout a
AlignedPtr @layout (Ptr a
ptr Ptr a -> Int -> Ptr a
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
off))
{-# INLINE alignedPokeByteOff #-}

alignedPeekV2
  :: forall layout a
   . (AlignedStorable layout a, Storable a)
  => AlignedPtr layout (V2 a)
  -> IO (V2 a)
alignedPeekV2 :: forall (layout :: MemoryLayout) a.
(AlignedStorable layout a, Storable a) =>
AlignedPtr layout (V2 a) -> IO (V2 a)
alignedPeekV2 (AlignedPtr Ptr (V2 a)
ptr) =
  let !stride :: Int
stride = Proxy layout -> Proxy a -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
alignedAlignment (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @a)
   in a -> a -> V2 a
forall a. a -> a -> V2 a
V2 (a -> a -> V2 a) -> IO a -> IO (a -> V2 a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr (V2 a) -> Int -> IO a
forall b. Ptr b -> Int -> IO a
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr (V2 a)
ptr Int
0 IO (a -> V2 a) -> IO a -> IO (V2 a)
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Ptr (V2 a) -> Int -> IO a
forall b. Ptr b -> Int -> IO a
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr (V2 a)
ptr Int
stride
{-# INLINE alignedPeekV2 #-}

alignedPokeV2
  :: forall layout a
   . (AlignedStorable layout a, Storable a)
  => AlignedPtr layout (V2 a)
  -> V2 a
  -> IO ()
alignedPokeV2 :: forall (layout :: MemoryLayout) a.
(AlignedStorable layout a, Storable a) =>
AlignedPtr layout (V2 a) -> V2 a -> IO ()
alignedPokeV2 (AlignedPtr Ptr (V2 a)
ptr) (V2 a
x a
y) = do
  let !stride :: Int
stride = Proxy layout -> Proxy a -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
alignedAlignment (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @a)
  Ptr (V2 a) -> Int -> a -> IO ()
forall b. Ptr b -> Int -> a -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr (V2 a)
ptr Int
0 a
x
  Ptr (V2 a) -> Int -> a -> IO ()
forall b. Ptr b -> Int -> a -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr (V2 a)
ptr Int
stride a
y
{-# INLINE alignedPokeV2 #-}

alignedPeekM2
  :: forall layout a v
   . (AlignedStorable layout (v a))
  => AlignedPtr layout (V2 (v a))
  -> IO (V2 (v a))
alignedPeekM2 :: forall (layout :: MemoryLayout) a (v :: * -> *).
AlignedStorable layout (v a) =>
AlignedPtr layout (V2 (v a)) -> IO (V2 (v a))
alignedPeekM2 AlignedPtr layout (V2 (v a))
aptr =
  let ptr :: AlignedPtr layout (v a)
ptr = AlignedPtr layout (V2 (v a)) -> AlignedPtr layout (v a)
forall (layout :: MemoryLayout) a b.
AlignedPtr layout a -> AlignedPtr layout b
castAlignedPtr AlignedPtr layout (V2 (v a))
aptr
      !rowSize :: Int
rowSize = Proxy layout -> Proxy (v a) -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
packedAlignedSizeOf (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(v a))
      !rowAlign :: Int
rowAlign = Proxy layout -> Proxy (v a) -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
alignedAlignment (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(v a))
      !stride :: Int
stride = Proxy layout -> Int -> Int -> Int
forall (layout :: MemoryLayout).
MemoryLayoutRules layout =>
Proxy layout -> Int -> Int -> Int
layoutStride (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) Int
rowSize Int
rowAlign
   in v a -> v a -> V2 (v a)
forall a. a -> a -> V2 a
V2
        (v a -> v a -> V2 (v a)) -> IO (v a) -> IO (v a -> V2 (v a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AlignedPtr layout (v a) -> Int -> IO (v a)
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
AlignedPtr layout a -> Int -> IO a
alignedPeekByteOff AlignedPtr layout (v a)
ptr Int
0
        IO (v a -> V2 (v a)) -> IO (v a) -> IO (V2 (v a))
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> AlignedPtr layout (v a) -> Int -> IO (v a)
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
AlignedPtr layout a -> Int -> IO a
alignedPeekByteOff AlignedPtr layout (v a)
ptr Int
stride
{-# INLINE alignedPeekM2 #-}

alignedPokeM2
  :: forall layout a v
   . (AlignedStorable layout (v a))
  => AlignedPtr layout (V2 (v a))
  -> V2 (v a)
  -> IO ()
alignedPokeM2 :: forall (layout :: MemoryLayout) a (v :: * -> *).
AlignedStorable layout (v a) =>
AlignedPtr layout (V2 (v a)) -> V2 (v a) -> IO ()
alignedPokeM2 AlignedPtr layout (V2 (v a))
aptr (V2 v a
x v a
y) = do
  let ptr :: AlignedPtr layout (v a)
ptr = AlignedPtr layout (V2 (v a)) -> AlignedPtr layout (v a)
forall (layout :: MemoryLayout) a b.
AlignedPtr layout a -> AlignedPtr layout b
castAlignedPtr AlignedPtr layout (V2 (v a))
aptr
      !rowSize :: Int
rowSize = Proxy layout -> Proxy (v a) -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
packedAlignedSizeOf (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(v a))
      !rowAlign :: Int
rowAlign = Proxy layout -> Proxy (v a) -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
alignedAlignment (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(v a))
      !stride :: Int
stride = Proxy layout -> Int -> Int -> Int
forall (layout :: MemoryLayout).
MemoryLayoutRules layout =>
Proxy layout -> Int -> Int -> Int
layoutStride (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) Int
rowSize Int
rowAlign
  AlignedPtr layout (v a) -> Int -> v a -> IO ()
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
AlignedPtr layout a -> Int -> a -> IO ()
alignedPokeByteOff AlignedPtr layout (v a)
ptr Int
0 v a
x
  AlignedPtr layout (v a) -> Int -> v a -> IO ()
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
AlignedPtr layout a -> Int -> a -> IO ()
alignedPokeByteOff AlignedPtr layout (v a)
ptr Int
stride v a
y
{-# INLINE alignedPokeM2 #-}

alignedPeekV3
  :: forall layout a. (AlignedStorable layout a, Storable a) => AlignedPtr layout (V3 a) -> IO (V3 a)
alignedPeekV3 :: forall (layout :: MemoryLayout) a.
(AlignedStorable layout a, Storable a) =>
AlignedPtr layout (V3 a) -> IO (V3 a)
alignedPeekV3 (AlignedPtr Ptr (V3 a)
ptr) =
  let a :: Int
a = Proxy layout -> Proxy a -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
alignedAlignment (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @a)
   in a -> a -> a -> V3 a
forall a. a -> a -> a -> V3 a
V3 (a -> a -> a -> V3 a) -> IO a -> IO (a -> a -> V3 a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr (V3 a) -> Int -> IO a
forall b. Ptr b -> Int -> IO a
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr (V3 a)
ptr Int
0 IO (a -> a -> V3 a) -> IO a -> IO (a -> V3 a)
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Ptr (V3 a) -> Int -> IO a
forall b. Ptr b -> Int -> IO a
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr (V3 a)
ptr Int
a IO (a -> V3 a) -> IO a -> IO (V3 a)
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Ptr (V3 a) -> Int -> IO a
forall b. Ptr b -> Int -> IO a
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr (V3 a)
ptr (Int
a Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
2)
{-# INLINE alignedPeekV3 #-}

alignedPokeV3
  :: forall layout a. (AlignedStorable layout a, Storable a) => AlignedPtr layout (V3 a) -> V3 a -> IO ()
alignedPokeV3 :: forall (layout :: MemoryLayout) a.
(AlignedStorable layout a, Storable a) =>
AlignedPtr layout (V3 a) -> V3 a -> IO ()
alignedPokeV3 (AlignedPtr Ptr (V3 a)
ptr) (V3 a
x a
y a
z) = do
  let a :: Int
a = Proxy layout -> Proxy a -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
alignedAlignment (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @a)
  Ptr (V3 a) -> Int -> a -> IO ()
forall b. Ptr b -> Int -> a -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr (V3 a)
ptr Int
0 a
x
  Ptr (V3 a) -> Int -> a -> IO ()
forall b. Ptr b -> Int -> a -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr (V3 a)
ptr Int
a a
y
  Ptr (V3 a) -> Int -> a -> IO ()
forall b. Ptr b -> Int -> a -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr (V3 a)
ptr (Int
a Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
2) a
z
{-# INLINE alignedPokeV3 #-}

alignedPeekM3
  :: forall layout a v
   . (AlignedStorable layout (v a))
  => AlignedPtr layout (V3 (v a))
  -> IO (V3 (v a))
alignedPeekM3 :: forall (layout :: MemoryLayout) a (v :: * -> *).
AlignedStorable layout (v a) =>
AlignedPtr layout (V3 (v a)) -> IO (V3 (v a))
alignedPeekM3 AlignedPtr layout (V3 (v a))
aptr =
  let ptr :: AlignedPtr layout (v a)
ptr = AlignedPtr layout (V3 (v a)) -> AlignedPtr layout (v a)
forall (layout :: MemoryLayout) a b.
AlignedPtr layout a -> AlignedPtr layout b
castAlignedPtr AlignedPtr layout (V3 (v a))
aptr
      !rowSize :: Int
rowSize = Proxy layout -> Proxy (v a) -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
packedAlignedSizeOf (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(v a))
      !rowAlign :: Int
rowAlign = Proxy layout -> Proxy (v a) -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
alignedAlignment (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(v a))
      !stride :: Int
stride = Proxy layout -> Int -> Int -> Int
forall (layout :: MemoryLayout).
MemoryLayoutRules layout =>
Proxy layout -> Int -> Int -> Int
layoutStride (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) Int
rowSize Int
rowAlign
   in v a -> v a -> v a -> V3 (v a)
forall a. a -> a -> a -> V3 a
V3
        (v a -> v a -> v a -> V3 (v a))
-> IO (v a) -> IO (v a -> v a -> V3 (v a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AlignedPtr layout (v a) -> Int -> IO (v a)
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
AlignedPtr layout a -> Int -> IO a
alignedPeekByteOff AlignedPtr layout (v a)
ptr Int
0
        IO (v a -> v a -> V3 (v a)) -> IO (v a) -> IO (v a -> V3 (v a))
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> AlignedPtr layout (v a) -> Int -> IO (v a)
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
AlignedPtr layout a -> Int -> IO a
alignedPeekByteOff AlignedPtr layout (v a)
ptr Int
stride
        IO (v a -> V3 (v a)) -> IO (v a) -> IO (V3 (v a))
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> AlignedPtr layout (v a) -> Int -> IO (v a)
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
AlignedPtr layout a -> Int -> IO a
alignedPeekByteOff AlignedPtr layout (v a)
ptr (Int
stride Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
2)
{-# INLINE alignedPeekM3 #-}

alignedPokeM3
  :: forall layout a v
   . (AlignedStorable layout (v a))
  => AlignedPtr layout (V3 (v a))
  -> V3 (v a)
  -> IO ()
alignedPokeM3 :: forall (layout :: MemoryLayout) a (v :: * -> *).
AlignedStorable layout (v a) =>
AlignedPtr layout (V3 (v a)) -> V3 (v a) -> IO ()
alignedPokeM3 AlignedPtr layout (V3 (v a))
aptr (V3 v a
x v a
y v a
z) = do
  let ptr :: AlignedPtr layout (v a)
ptr = AlignedPtr layout (V3 (v a)) -> AlignedPtr layout (v a)
forall (layout :: MemoryLayout) a b.
AlignedPtr layout a -> AlignedPtr layout b
castAlignedPtr AlignedPtr layout (V3 (v a))
aptr
      !rowSize :: Int
rowSize = Proxy layout -> Proxy (v a) -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
packedAlignedSizeOf (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(v a))
      !rowAlign :: Int
rowAlign = Proxy layout -> Proxy (v a) -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
alignedAlignment (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(v a))
      !stride :: Int
stride = Proxy layout -> Int -> Int -> Int
forall (layout :: MemoryLayout).
MemoryLayoutRules layout =>
Proxy layout -> Int -> Int -> Int
layoutStride (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) Int
rowSize Int
rowAlign
  AlignedPtr layout (v a) -> Int -> v a -> IO ()
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
AlignedPtr layout a -> Int -> a -> IO ()
alignedPokeByteOff AlignedPtr layout (v a)
ptr Int
0 v a
x
  AlignedPtr layout (v a) -> Int -> v a -> IO ()
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
AlignedPtr layout a -> Int -> a -> IO ()
alignedPokeByteOff AlignedPtr layout (v a)
ptr Int
stride v a
y
  AlignedPtr layout (v a) -> Int -> v a -> IO ()
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
AlignedPtr layout a -> Int -> a -> IO ()
alignedPokeByteOff AlignedPtr layout (v a)
ptr (Int
stride Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
2) v a
z
{-# INLINE alignedPokeM3 #-}

alignedPokeV4
  :: forall layout a. (AlignedStorable layout a, Storable a) => AlignedPtr layout (V4 a) -> V4 a -> IO ()
alignedPokeV4 :: forall (layout :: MemoryLayout) a.
(AlignedStorable layout a, Storable a) =>
AlignedPtr layout (V4 a) -> V4 a -> IO ()
alignedPokeV4 (AlignedPtr Ptr (V4 a)
ptr) (V4 a
x a
y a
z a
w) = do
  let a :: Int
a = Proxy layout -> Proxy a -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
alignedAlignment (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @a)
  Ptr (V4 a) -> Int -> a -> IO ()
forall b. Ptr b -> Int -> a -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr (V4 a)
ptr Int
0 a
x
  Ptr (V4 a) -> Int -> a -> IO ()
forall b. Ptr b -> Int -> a -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr (V4 a)
ptr Int
a a
y
  Ptr (V4 a) -> Int -> a -> IO ()
forall b. Ptr b -> Int -> a -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr (V4 a)
ptr (Int
a Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
2) a
z
  Ptr (V4 a) -> Int -> a -> IO ()
forall b. Ptr b -> Int -> a -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr (V4 a)
ptr (Int
a Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
3) a
w
{-# INLINE alignedPokeV4 #-}

alignedPeekV4
  :: forall layout a. (AlignedStorable layout a, Storable a) => AlignedPtr layout (V4 a) -> IO (V4 a)
alignedPeekV4 :: forall (layout :: MemoryLayout) a.
(AlignedStorable layout a, Storable a) =>
AlignedPtr layout (V4 a) -> IO (V4 a)
alignedPeekV4 (AlignedPtr Ptr (V4 a)
ptr) =
  let a :: Int
a = Proxy layout -> Proxy a -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
alignedAlignment (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @a)
   in a -> a -> a -> a -> V4 a
forall a. a -> a -> a -> a -> V4 a
V4
        (a -> a -> a -> a -> V4 a) -> IO a -> IO (a -> a -> a -> V4 a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr (V4 a) -> Int -> IO a
forall b. Ptr b -> Int -> IO a
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr (V4 a)
ptr Int
0
        IO (a -> a -> a -> V4 a) -> IO a -> IO (a -> a -> V4 a)
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Ptr (V4 a) -> Int -> IO a
forall b. Ptr b -> Int -> IO a
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr (V4 a)
ptr Int
a
        IO (a -> a -> V4 a) -> IO a -> IO (a -> V4 a)
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Ptr (V4 a) -> Int -> IO a
forall b. Ptr b -> Int -> IO a
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr (V4 a)
ptr (Int
a Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
2)
        IO (a -> V4 a) -> IO a -> IO (V4 a)
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Ptr (V4 a) -> Int -> IO a
forall b. Ptr b -> Int -> IO a
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr (V4 a)
ptr (Int
a Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
3)
{-# INLINE alignedPeekV4 #-}

alignedPeekM4
  :: forall layout a v
   . (AlignedStorable layout (v a))
  => AlignedPtr layout (V4 (v a))
  -> IO (V4 (v a))
alignedPeekM4 :: forall (layout :: MemoryLayout) a (v :: * -> *).
AlignedStorable layout (v a) =>
AlignedPtr layout (V4 (v a)) -> IO (V4 (v a))
alignedPeekM4 AlignedPtr layout (V4 (v a))
aptr =
  let ptr :: AlignedPtr layout (v a)
ptr = AlignedPtr layout (V4 (v a)) -> AlignedPtr layout (v a)
forall (layout :: MemoryLayout) a b.
AlignedPtr layout a -> AlignedPtr layout b
castAlignedPtr AlignedPtr layout (V4 (v a))
aptr
      !rowSize :: Int
rowSize = Proxy layout -> Proxy (v a) -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
packedAlignedSizeOf (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(v a))
      !rowAlign :: Int
rowAlign = Proxy layout -> Proxy (v a) -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
alignedAlignment (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(v a))
      !stride :: Int
stride = Proxy layout -> Int -> Int -> Int
forall (layout :: MemoryLayout).
MemoryLayoutRules layout =>
Proxy layout -> Int -> Int -> Int
layoutStride (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) Int
rowSize Int
rowAlign
   in v a -> v a -> v a -> v a -> V4 (v a)
forall a. a -> a -> a -> a -> V4 a
V4
        (v a -> v a -> v a -> v a -> V4 (v a))
-> IO (v a) -> IO (v a -> v a -> v a -> V4 (v a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AlignedPtr layout (v a) -> Int -> IO (v a)
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
AlignedPtr layout a -> Int -> IO a
alignedPeekByteOff AlignedPtr layout (v a)
ptr Int
0
        IO (v a -> v a -> v a -> V4 (v a))
-> IO (v a) -> IO (v a -> v a -> V4 (v a))
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> AlignedPtr layout (v a) -> Int -> IO (v a)
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
AlignedPtr layout a -> Int -> IO a
alignedPeekByteOff AlignedPtr layout (v a)
ptr Int
stride
        IO (v a -> v a -> V4 (v a)) -> IO (v a) -> IO (v a -> V4 (v a))
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> AlignedPtr layout (v a) -> Int -> IO (v a)
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
AlignedPtr layout a -> Int -> IO a
alignedPeekByteOff AlignedPtr layout (v a)
ptr (Int
stride Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
2)
        IO (v a -> V4 (v a)) -> IO (v a) -> IO (V4 (v a))
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> AlignedPtr layout (v a) -> Int -> IO (v a)
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
AlignedPtr layout a -> Int -> IO a
alignedPeekByteOff AlignedPtr layout (v a)
ptr (Int
stride Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
3)
{-# INLINE alignedPeekM4 #-}

alignedPokeM4
  :: forall layout a v
   . (AlignedStorable layout (v a))
  => AlignedPtr layout (V4 (v a))
  -> V4 (v a)
  -> IO ()
alignedPokeM4 :: forall (layout :: MemoryLayout) a (v :: * -> *).
AlignedStorable layout (v a) =>
AlignedPtr layout (V4 (v a)) -> V4 (v a) -> IO ()
alignedPokeM4 AlignedPtr layout (V4 (v a))
aptr (V4 v a
x v a
y v a
z v a
w) = do
  let ptr :: AlignedPtr layout (v a)
ptr = AlignedPtr layout (V4 (v a)) -> AlignedPtr layout (v a)
forall (layout :: MemoryLayout) a b.
AlignedPtr layout a -> AlignedPtr layout b
castAlignedPtr AlignedPtr layout (V4 (v a))
aptr
      !rowSize :: Int
rowSize = Proxy layout -> Proxy (v a) -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
packedAlignedSizeOf (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(v a))
      !rowAlign :: Int
rowAlign = Proxy layout -> Proxy (v a) -> Int
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
Proxy layout -> Proxy a -> Int
alignedAlignment (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(v a))
      !stride :: Int
stride = Proxy layout -> Int -> Int -> Int
forall (layout :: MemoryLayout).
MemoryLayoutRules layout =>
Proxy layout -> Int -> Int -> Int
layoutStride (forall {k} (t :: k). Proxy t
forall (t :: MemoryLayout). Proxy t
Proxy @layout) Int
rowSize Int
rowAlign
  AlignedPtr layout (v a) -> Int -> v a -> IO ()
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
AlignedPtr layout a -> Int -> a -> IO ()
alignedPokeByteOff AlignedPtr layout (v a)
ptr Int
0 v a
x
  AlignedPtr layout (v a) -> Int -> v a -> IO ()
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
AlignedPtr layout a -> Int -> a -> IO ()
alignedPokeByteOff AlignedPtr layout (v a)
ptr Int
stride v a
y
  AlignedPtr layout (v a) -> Int -> v a -> IO ()
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
AlignedPtr layout a -> Int -> a -> IO ()
alignedPokeByteOff AlignedPtr layout (v a)
ptr (Int
stride Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
2) v a
z
  AlignedPtr layout (v a) -> Int -> v a -> IO ()
forall (layout :: MemoryLayout) a.
AlignedStorable layout a =>
AlignedPtr layout a -> Int -> a -> IO ()
alignedPokeByteOff AlignedPtr layout (v a)
ptr (Int
stride Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
3) v a
w
{-# INLINE alignedPokeM4 #-}

--------------------------------------------------------------------------------
-- Base instances for primitive shader types
--
-- CPP is the simple way to stamp out the instances. I'll probably switch to TH
-- at some point.
--------------------------------------------------------------------------------

-- schema: (MemoryLayout, Type, size, alignment)
#define FOR_EACH_STD140_PRIMITIVE(X) \
  X (Std140, Bool, 4, 4) \
  X (Std140, Half, 2, 2) \
  X (Std140, Float, 4, 4) \
  X (Std140, Double, 8, 8) \
  X (Std140, Int8, 4, 4) \
  X (Std140, Int16, 4, 4) \
  X (Std140, Int32, 4, 4) \
  X (Std140, Int64, 8, 8) \
  X (Std140, Word8, 4, 4) \
  X (Std140, Word16, 4, 4) \
  X (Std140, Word32, 4, 4) \
  X (Std140, Word64, 8, 8)

-- schema: (MemoryLayout, Type, size, alignment)
#define FOR_EACH_STD430_PRIMITIVE(X) \
  X (Std430, Bool, 4, 4) \
  X (Std430, Half, 2, 2) \
  X (Std430, Float, 4, 4) \
  X (Std430, Double, 8, 8) \
  X (Std430, Int8, 1, 1) \
  X (Std430, Int16, 2, 2) \
  X (Std430, Int32, 4, 4) \
  X (Std430, Int64, 8, 8) \
  X (Std430, Word8, 1, 1) \
  X (Std430, Word16, 2, 2) \
  X (Std430, Word32, 4, 4) \
  X (Std430, Word64, 8, 8)

-- schema: (MemoryLayout, Type, size, alignment)
#define FOR_EACH_SCALAR_PRIMITIVE(X) \
  X (Scalar, Bool, 4, 4) \
  X (Scalar, Half, 2, 2) \
  X (Scalar, Float, 4, 4) \
  X (Scalar, Double, 8, 8) \
  X (Scalar, Int8, 1, 1) \
  X (Scalar, Int16, 2, 2) \
  X (Scalar, Int32, 4, 4) \
  X (Scalar, Int64, 8, 8) \
  X (Scalar, Word8, 1, 1) \
  X (Scalar, Word16, 2, 2) \
  X (Scalar, Word32, 4, 4) \
  X (Scalar, Word64, 8, 8)

-- schema: (Type)
#define FOR_EACH_MATRIX_PRIMITIVE(X) \
  X (Half) \
  X (Float) \
  X (Double)

#define PRIMITIVE_INSTANCE(LAYOUT, T, S, A) \
instance AlignedStorable LAYOUT T where { \
  packedAlignedSizeOf _ _ = S; \
  {-# INLINE packedAlignedSizeOf #-}; \
  alignedSizeOf _ _ = S; \
  {-# INLINE alignedSizeOf #-}; \
  alignedAlignment _ _ = A; \
  {-# INLINE alignedAlignment #-}; \
  alignedPeek = defaultAlignedPeek; \
  {-# INLINE alignedPeek #-}; \
  alignedPoke = defaultAlignedPoke; \
  {-# INLINE alignedPoke #-}; \
  };

#define X(LAYOUT, T, S, A) PRIMITIVE_INSTANCE(LAYOUT, T, S, A)
FOR_EACH_STD140_PRIMITIVE (X)
FOR_EACH_STD430_PRIMITIVE (X)
FOR_EACH_SCALAR_PRIMITIVE (X)
#undef X

--------------------------------------------------------------------------------
-- Base instances for vectors and matrices
--------------------------------------------------------------------------------

#define VEC2_STD_INSTANCE(LAYOUT, T) \
instance AlignedStorable LAYOUT (V2 T) where { \
  packedAlignedSizeOf _ _ = 2 * alignedSizeOf (Proxy :: Proxy LAYOUT) (Proxy :: Proxy T); \
  {-# INLINE packedAlignedSizeOf #-}; \
  alignedSizeOf _ _ = 2 * alignedSizeOf (Proxy :: Proxy LAYOUT) (Proxy :: Proxy T); \
  {-# INLINE alignedSizeOf #-}; \
  alignedAlignment _ _ = 2 * alignedAlignment (Proxy :: Proxy LAYOUT) (Proxy :: Proxy T); \
  {-# INLINE alignedAlignment #-}; \
  alignedPeek = alignedPeekV2; \
  {-# INLINE alignedPeek #-}; \
  alignedPoke = alignedPokeV2; \
  {-# INLINE alignedPoke #-}; \
  };

#define X(LAYOUT, T, S, A) VEC2_STD_INSTANCE(LAYOUT, T)
FOR_EACH_STD140_PRIMITIVE (X)
FOR_EACH_STD430_PRIMITIVE (X)
#undef X

#define VEC2_SCALAR_INSTANCE(T) \
instance AlignedStorable Scalar (V2 T) where { \
  packedAlignedSizeOf _ _ = 2 * alignedSizeOf (Proxy :: Proxy Scalar) (Proxy :: Proxy T); \
  {-# INLINE packedAlignedSizeOf #-}; \
  alignedSizeOf _ _ = 2 * alignedSizeOf (Proxy :: Proxy Scalar) (Proxy :: Proxy T); \
  {-# INLINE alignedSizeOf #-}; \
  alignedAlignment _ _ = alignedAlignment (Proxy :: Proxy Scalar) (Proxy :: Proxy T); \
  alignedPeek = defaultAlignedPeek; \
  {-# INLINE alignedPeek #-}; \
  alignedPoke = defaultAlignedPoke; \
  {-# INLINE alignedPoke #-}; \
  };

#define X(LAYOUT, T, S, A) VEC2_SCALAR_INSTANCE(T)
FOR_EACH_SCALAR_PRIMITIVE (X)
#undef X

#define MAT2_STD_INSTANCE(LAYOUT, T) \
instance AlignedStorable LAYOUT (M22 T) where { \
  packedAlignedSizeOf l a = 2 * packedAlignedSizeOfMat l a; \
  {-# INLINE packedAlignedSizeOf #-}; \
  alignedSizeOf = packedAlignedSizeOf; \
  {-# INLINE alignedSizeOf #-}; \
  alignedAlignment l _ = alignBlock l (alignedAlignment l (Proxy :: Proxy (V2 T))); \
  {-# INLINE alignedAlignment #-}; \
  alignedPeek = alignedPeekM2; \
  {-# INLINE alignedPeek #-}; \
  alignedPoke = alignedPokeM2; \
  {-# INLINE alignedPoke #-}; \
  };

#define X(T) MAT2_STD_INSTANCE(Std140, T)
FOR_EACH_MATRIX_PRIMITIVE (X)
#undef X

#define X(T) MAT2_STD_INSTANCE(Std430, T)
FOR_EACH_MATRIX_PRIMITIVE (X)
#undef X

-- For Scalar layout, matrices are trivially the same as nested vectors
#define X(T) VEC2_SCALAR_INSTANCE((V2 T))
FOR_EACH_MATRIX_PRIMITIVE (X)
#undef X

#define MAT23_STD_INSTANCE(LAYOUT, T) \
instance AlignedStorable LAYOUT (M23 T) where { \
  packedAlignedSizeOf l a = 2 * packedAlignedSizeOfMat l a; \
  {-# INLINE packedAlignedSizeOf #-}; \
  alignedSizeOf = packedAlignedSizeOf; \
  {-# INLINE alignedSizeOf #-}; \
  alignedAlignment l _ = alignBlock l (alignedAlignment l (Proxy :: Proxy (V3 T))); \
  {-# INLINE alignedAlignment #-}; \
  alignedPeek = alignedPeekM2; \
  {-# INLINE alignedPeek #-}; \
  alignedPoke = alignedPokeM2; \
  {-# INLINE alignedPoke #-}; \
  };

#define X(T) MAT23_STD_INSTANCE(Std140, T)
FOR_EACH_MATRIX_PRIMITIVE (X)
#undef X

#define X(T) MAT23_STD_INSTANCE(Std430, T)
FOR_EACH_MATRIX_PRIMITIVE (X)
#undef X

-- For Scalar layout, matrices are trivially the same as nested vectors
#define X(T) VEC2_SCALAR_INSTANCE((V3 T))
FOR_EACH_MATRIX_PRIMITIVE (X)
#undef X

#define MAT24_STD_INSTANCE(LAYOUT, T) \
instance AlignedStorable LAYOUT (M24 T) where { \
  packedAlignedSizeOf l a = 2 * packedAlignedSizeOfMat l a; \
  {-# INLINE packedAlignedSizeOf #-}; \
  alignedSizeOf = packedAlignedSizeOf ; \
  {-# INLINE alignedSizeOf #-}; \
  alignedAlignment l _ = alignBlock l (alignedAlignment l (Proxy :: Proxy (V4 T))); \
  {-# INLINE alignedAlignment #-}; \
  alignedPeek = alignedPeekM2; \
  {-# INLINE alignedPeek #-}; \
  alignedPoke = alignedPokeM2; \
  {-# INLINE alignedPoke #-}; \
  };

#define X(T) MAT24_STD_INSTANCE(Std140, T)
FOR_EACH_MATRIX_PRIMITIVE (X)
#undef X

#define X(T) MAT24_STD_INSTANCE(Std430, T)
FOR_EACH_MATRIX_PRIMITIVE (X)
#undef X

-- For Scalar layout, matrices are trivially the same as nested vectors
#define X(T) VEC2_SCALAR_INSTANCE((V4 T))
FOR_EACH_MATRIX_PRIMITIVE (X)
#undef X

#define VEC3_STD_INSTANCE(LAYOUT, A) \
instance AlignedStorable LAYOUT (V3 A) where { \
  packedAlignedSizeOf l _ = 3 * alignedSizeOf l (Proxy :: Proxy A); \
  {-# INLINE packedAlignedSizeOf #-} ; \
  alignedSizeOf l _ = 3 * alignedSizeOf l (Proxy :: Proxy A); \
  alignedAlignment l _ = 4 * alignedAlignment l (Proxy :: Proxy A); \
  {-# INLINE alignedAlignment #-} ; \
  alignedPeek = alignedPeekV3; \
  {-# INLINE alignedPeek #-} ; \
  alignedPoke = alignedPokeV3; \
    {-# INLINE alignedPoke #-} ; \
  }; \

#define X(LAYOUT, T, S, A) VEC3_STD_INSTANCE(LAYOUT, T)
FOR_EACH_STD140_PRIMITIVE (X)
FOR_EACH_STD430_PRIMITIVE (X)
#undef X

#define VEC3_SCALAR_INSTANCE(A) \
instance AlignedStorable Scalar (V3 A) where { \
  packedAlignedSizeOf _ _ = 3 * alignedSizeOf (Proxy :: Proxy Scalar) (Proxy :: Proxy A); \
  {-# INLINE packedAlignedSizeOf #-}; \
  alignedSizeOf _ _ = 3 * alignedSizeOf (Proxy :: Proxy Scalar) (Proxy :: Proxy A); \
  {-# INLINE alignedSizeOf #-}; \
  alignedAlignment _ _ = alignedAlignment (Proxy :: Proxy Scalar) (Proxy :: Proxy A); \
  {-# INLINE alignedAlignment #-}; \
  alignedPeek = defaultAlignedPeek; \
  {-# INLINE alignedPeek #-}; \
  alignedPoke = defaultAlignedPoke; \
  {-# INLINE alignedPoke #-}; \
  };

#define X(LAYOUT, T, S, A) VEC3_SCALAR_INSTANCE(T)
FOR_EACH_SCALAR_PRIMITIVE (X)
#undef X

#define MAT3_STD_INSTANCE(LAYOUT, A) \
instance AlignedStorable LAYOUT (M33 A) where { \
  packedAlignedSizeOf l a = 3 * packedAlignedSizeOfMat l a; \
  {-# INLINE packedAlignedSizeOf #-}; \
  alignedSizeOf = packedAlignedSizeOf; \
  {-# INLINE alignedSizeOf #-}; \
  alignedAlignment l _ = alignBlock l (alignedAlignment l (Proxy :: Proxy (V3 A))); \
  {-# INLINE alignedAlignment #-} ; \
  alignedPeek = alignedPeekM3; \
  {-# INLINE alignedPeek #-}; \
  alignedPoke = alignedPokeM3; \
  {-# INLINE alignedPoke #-}; \
  };

#define X(T) MAT3_STD_INSTANCE(Std140, T)
FOR_EACH_MATRIX_PRIMITIVE (X)
#undef X

#define X(T) MAT3_STD_INSTANCE(Std430, T)
FOR_EACH_MATRIX_PRIMITIVE (X)
#undef X

-- For Scalar layout, matrices are trivially the same as nested vectors
#define X(T) VEC3_SCALAR_INSTANCE((V3 T))
FOR_EACH_MATRIX_PRIMITIVE (X)
#undef X

#define MAT32_STD_INSTANCE(LAYOUT, A) \
instance AlignedStorable LAYOUT (M32 A) where { \
  packedAlignedSizeOf l a = 3 * packedAlignedSizeOfMat l a ; \
  {-# INLINE packedAlignedSizeOf #-}; \
  alignedSizeOf = packedAlignedSizeOf; \
  {-# INLINE alignedSizeOf #-}; \
  alignedAlignment l _ = alignBlock l (alignedAlignment l (Proxy :: Proxy (V2 A))); \
  {-# INLINE alignedAlignment #-} ; \
  alignedPeek = alignedPeekM3; \
  {-# INLINE alignedPeek #-}; \
  alignedPoke = alignedPokeM3; \
  {-# INLINE alignedPoke #-}; \
  };

#define X(T) MAT32_STD_INSTANCE(Std140, T)
FOR_EACH_MATRIX_PRIMITIVE (X)
#undef X

#define X(T) MAT32_STD_INSTANCE(Std430, T)
FOR_EACH_MATRIX_PRIMITIVE (X)
#undef X

-- For Scalar layout, matrices are trivially the same as nested vectors
#define X(T) VEC3_SCALAR_INSTANCE((V2 T))
FOR_EACH_MATRIX_PRIMITIVE (X)
#undef X

#define MAT34_STD_INSTANCE(LAYOUT, A) \
instance AlignedStorable LAYOUT (M34 A) where { \
  packedAlignedSizeOf l a = 3 * packedAlignedSizeOfMat l a; \
  {-# INLINE packedAlignedSizeOf #-}; \
  alignedSizeOf = packedAlignedSizeOf ; \
  {-# INLINE alignedSizeOf #-}; \
  alignedAlignment l _ = alignBlock l (alignedAlignment l (Proxy :: Proxy (V4 A))); \
  {-# INLINE alignedAlignment #-} ; \
  alignedPeek = alignedPeekM3; \
  {-# INLINE alignedPeek #-}; \
  alignedPoke = alignedPokeM3; \
  {-# INLINE alignedPoke #-}; \
  };

#define X(T) MAT34_STD_INSTANCE(Std140, T)
FOR_EACH_MATRIX_PRIMITIVE (X)
#undef X

#define X(T) MAT34_STD_INSTANCE(Std430, T)
FOR_EACH_MATRIX_PRIMITIVE (X)
#undef X

-- For Scalar layout, matrices are trivially the same as nested vectors
#define X(T) VEC3_SCALAR_INSTANCE((V4 T))
FOR_EACH_MATRIX_PRIMITIVE (X)
#undef X

#define VEC4_STD_INSTANCE(LAYOUT, A) \
instance AlignedStorable LAYOUT (V4 A) where { \
  packedAlignedSizeOf l _ = 4 * alignedSizeOf l (Proxy :: Proxy A); \
  {-# INLINE packedAlignedSizeOf #-}; \
  alignedSizeOf l _ = 4 * alignedSizeOf l (Proxy :: Proxy A); \
  {-# INLINE alignedSizeOf #-}; \
  alignedAlignment l _ = 4 * alignedAlignment l (Proxy :: Proxy A); \
  {-# INLINE alignedAlignment #-} ; \
  alignedPeek = alignedPeekV4; \
  {-# INLINE alignedPeek #-}; \
  alignedPoke = alignedPokeV4; \
  {-# INLINE alignedPoke #-}; \
  };

#define X(LAYOUT, T, S, A) VEC4_STD_INSTANCE(LAYOUT, T)
FOR_EACH_STD140_PRIMITIVE (X)
FOR_EACH_STD430_PRIMITIVE (X)
#undef X

#define VEC4_SCALAR_INSTANCE(A) \
instance AlignedStorable Scalar (V4 A) where { \
  packedAlignedSizeOf _ _ = 4 * alignedSizeOf (Proxy :: Proxy Scalar) (Proxy :: Proxy A); \
  {-# INLINE packedAlignedSizeOf #-}; \
  alignedSizeOf _ _ = 4 * alignedSizeOf (Proxy :: Proxy Scalar) (Proxy :: Proxy A); \
  {-# INLINE alignedSizeOf #-}; \
  alignedAlignment _ _ = alignedAlignment (Proxy :: Proxy Scalar) (Proxy :: Proxy A); \
  {-# INLINE alignedAlignment #-}; \
  alignedPeek = defaultAlignedPeek; \
  {-# INLINE alignedPeek #-}; \
  alignedPoke = defaultAlignedPoke; \
  {-# INLINE alignedPoke #-}; \
  };

#define X(LAYOUT, T, S, A) VEC4_SCALAR_INSTANCE(T)
FOR_EACH_SCALAR_PRIMITIVE (X)
#undef X

#define MAT4_STD_INSTANCE(LAYOUT, A) \
instance AlignedStorable LAYOUT (M44 A) where { \
  packedAlignedSizeOf l a = 4 * packedAlignedSizeOfMat l a; \
  {-# INLINE packedAlignedSizeOf #-}; \
  alignedSizeOf = packedAlignedSizeOf; \
  {-# INLINE alignedSizeOf #-}; \
  alignedAlignment l _ = alignBlock l (alignedAlignment l (Proxy :: Proxy (V4 A))); \
  {-# INLINE alignedAlignment #-}; \
  alignedPeek = alignedPeekM4; \
  {-# INLINE alignedPeek #-}; \
  alignedPoke = alignedPokeM4; \
  {-# INLINE alignedPoke #-}; \
  };

#define X(T) MAT4_STD_INSTANCE(Std140, T)
FOR_EACH_MATRIX_PRIMITIVE (X)
#undef X

#define X(T) MAT4_STD_INSTANCE(Std430, T)
FOR_EACH_MATRIX_PRIMITIVE (X)
#undef X

-- For Scalar layout, matrices are trivially the same as nested vectors
#define X(T) VEC4_SCALAR_INSTANCE((V4 T))
FOR_EACH_MATRIX_PRIMITIVE (X)
#undef X

#define MAT42_STD_INSTANCE(LAYOUT, A) \
instance AlignedStorable LAYOUT (M42 A) where { \
  packedAlignedSizeOf l a = 4 * packedAlignedSizeOfMat l a; \
  {-# INLINE packedAlignedSizeOf #-}; \
  alignedSizeOf = packedAlignedSizeOf; \
  {-# INLINE alignedSizeOf #-}; \
  alignedAlignment l _ = alignBlock l (alignedAlignment l (Proxy :: Proxy (V2 A))); \
  {-# INLINE alignedAlignment #-}; \
  alignedPeek = alignedPeekM4; \
  {-# INLINE alignedPeek #-}; \
  alignedPoke = alignedPokeM4; \
  {-# INLINE alignedPoke #-}; \
  };

#define X(T) MAT42_STD_INSTANCE(Std140, T)
FOR_EACH_MATRIX_PRIMITIVE (X)
#undef X

#define X(T) MAT42_STD_INSTANCE(Std430, T)
FOR_EACH_MATRIX_PRIMITIVE (X)
#undef X

-- For Scalar layout, matrices are trivially the same as nested vectors
#define X(T) VEC4_SCALAR_INSTANCE((V2 T))
FOR_EACH_MATRIX_PRIMITIVE (X)
#undef X

#define MAT43_STD_INSTANCE(LAYOUT, A) \
instance AlignedStorable LAYOUT (M43 A) where { \
  packedAlignedSizeOf l a = 4 * packedAlignedSizeOfMat l a; \
  {-# INLINE packedAlignedSizeOf #-}; \
  alignedSizeOf = packedAlignedSizeOf; \
  {-# INLINE alignedSizeOf #-}; \
  alignedAlignment l _ = alignBlock l (alignedAlignment l (Proxy :: Proxy (V3 A))); \
  {-# INLINE alignedAlignment #-}; \
  alignedPeek = alignedPeekM4; \
  {-# INLINE alignedPeek #-}; \
  alignedPoke = alignedPokeM4; \
  {-# INLINE alignedPoke #-}; \
  };

#define X(T) MAT43_STD_INSTANCE(Std140, T)
FOR_EACH_MATRIX_PRIMITIVE (X)
#undef X

#define X(T) MAT43_STD_INSTANCE(Std430, T)
FOR_EACH_MATRIX_PRIMITIVE (X)
#undef X

-- For Scalar layout, matrices are trivially the same as nested vectors
#define X(T) VEC4_SCALAR_INSTANCE((V3 T))
FOR_EACH_MATRIX_PRIMITIVE (X)
#undef X