packages feed

fir-0.1.0.0: src/FIR/Syntax/Synonyms.hs

{-# OPTIONS_GHC -fno-warn-missing-pattern-synonym-signatures -Wno-missing-signatures #-}

{-# LANGUAGE AllowAmbiguousTypes    #-}
{-# LANGUAGE ConstraintKinds        #-}
{-# LANGUAGE DataKinds              #-}
{-# LANGUAGE FlexibleContexts       #-}
{-# LANGUAGE FlexibleInstances      #-}
{-# LANGUAGE GADTs                  #-}
{-# LANGUAGE MultiParamTypeClasses  #-}
{-# LANGUAGE PatternSynonyms        #-}
{-# LANGUAGE PolyKinds              #-}
{-# LANGUAGE ScopedTypeVariables    #-}
{-# LANGUAGE TypeApplications       #-}
{-# LANGUAGE TypeFamilyDependencies #-}
{-# LANGUAGE TypeOperators          #-}
{-# LANGUAGE UndecidableInstances   #-}
{-# LANGUAGE ViewPatterns           #-}
{-# LANGUAGE StandaloneKindSignatures #-}
{-# LANGUAGE TypeAbstractions #-}

{-|
Module: FIR.Syntax.Synonyms

This module provides various convenience synonyms
to mitigate verbosity in user-written programs.

-}

module FIR.Syntax.Synonyms
  (
  -- * Synonyms for floating point types of a given width
    Float16, Float32, Float64

  -- * Synonyms for entry point globals with a given storage class
  , UniformConstant, Input, Output
  , Uniform, PushConstant
  , StorageBuffer, Private
  , Workgroup, CrossWorkgroup
  , AtomicCounter
  , RayPayload, RayPayloadIn
  , CallableData, CallableDataIn
  , HitAttribute, ShaderRecordBuffer

  -- * Synonyms for function with given function control information
  , Function, Function'

  -- * Synonyms for images
  -- ** Sampled images
  , Texture1D, Texture2D, Texture3D, Texture
  -- ** Storage images
  , Image1D, Image2D, Image3D, StorageImage
  , UnknownFormatImage1D, UnknownFormatImage2D, UnknownFormatImage3D
  -- ** Image operand shorthands
  , pattern DepthTestOffsets
  , pattern GatherComponentWithOffsets
  -- ** Helper type family for choosing image texel type
  , FormatDefault

  -- * Synonyms involved in pipeline creation
  , Slot
  , pattern StructInput

  -- * Synonyms for optics
  , Field
  , Col, Cols
  , Row, Rows
  , Entry, Elts
  , Diag, Center

  -- * Pattern synonyms for vectors/matrices
  -- ** Patterns for vectors
  , pattern Vec2, pattern Vec3, pattern Vec4

  -- ** Patterns for matrices
  , pattern Mat22, pattern Mat23, pattern Mat24
  , pattern Mat32, pattern Mat33, pattern Mat34
  , pattern Mat42, pattern Mat43, pattern Mat44

  -- * Ray tracing flags
  , pattern RayFlagsNone, pattern RayFlagsOpaque, pattern RayFlagsNoOpaque
  , pattern RayFlagsTerminateOnFirstHit, pattern RayFlagsSkipClosestHitShader
  , pattern RayFlagsCullBackFacingTriangles, pattern RayFlagsCullFrontFacingTriangles
  , pattern RayFlagsCullOpaque, pattern RayFlagsCullNoOpaque

  -- * Ray tracing hit kinds
  , pattern HitKindFrontFacingTriangle, pattern HitKindBackFacingTriangle

  )
  where

-- base
import Prelude
  hiding ( Floating, Integral )
import Data.Int
  ( Int8, Int16, Int32 )
import Data.Kind
  ( Type )
import Data.Word
  ( Word8, Word16, Word32 )
import GHC.TypeLits
  ( Symbol )
import GHC.TypeNats
  ( Nat, KnownNat
  , type (*)
  )

-- half
import Numeric.Half
  ( Half )

-- fir
import Control.Type.Optic
  ( Optic(..), Index
  , (:.:), (:*:)
  , OfType
  , EndProd
  )
import Data.Type.Known
  ( Known )
import Data.Type.Map
  ( (:->)((:->)), InsertionSort, Value )
import FIR.AST
  ( Code
  , Syntactic(fromAST)
  , pattern (:$)
  , pattern MkVector, pattern Mat, pattern UnMat
  , pattern Gather
  )
import FIR.Definition
  ( Definition(Global) )
import qualified FIR.Definition as Def
import FIR.Syntax.AST
  ( )
import FIR.Syntax.Optics
  ( )
import FIR.Layout
  ( Layout(Locations)
  , Poke(SizeOf)
  )
import FIR.Pipeline
  ( PrimitiveTopology
  , BindingStrides
  , VertexLocationDescriptions
  , PipelineInfo(VertexInputInfo)
  , PipelineStages(VertexInput)
  )
import FIR.Prim.Array
  ( Array )
import FIR.Prim.Image
  ( ImageProperties(Properties)
  , ImageCoordinateKind(..)
  , Image, GatherInfo(..)
  )
import FIR.Prim.Struct
  ( Struct
  , LocationSlot(LocationSlot)
  )
import FIR.Prim.Types
  ( PrimTy, ScalarTy )
import FIR.Validation.Bounds
  ( StructIndexFromName )
import FIR.Validation.Formats
  ( ComputeFormats )
import Math.Linear
  ( V, M
  , pattern V2, pattern V3, pattern V4
  )
import SPIRV.ScalarTy
  ( Signedness(..) )
import SPIRV.Image
  ( Dimensionality(..)
  , HasDepth(..)
  , Arrayness(..)
  , MultiSampling(..)
  , Normalisation(..)
  , ImageUsage(..)
  , ImageFormat(..)
  )
import SPIRV.Control
  ( NoFunctionControl )
import qualified SPIRV.Image   as Image
import qualified SPIRV.Image   as SPIRV
  ( ImageFormat )
import qualified SPIRV.Storage as Storage

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

type Float16 = Half
type Float32 = Float
type Float64 = Double

-- synonyms for (decorated) globals
type UniformConstant    decs ty = Global Storage.UniformConstant    decs ty
type Input              decs ty = Global Storage.Input              decs ty
type Output             decs ty = Global Storage.Output             decs ty
type Uniform            decs ty = Global Storage.Uniform            decs ty
type PushConstant       decs ty = Global Storage.PushConstant       decs ty
type StorageBuffer      decs ty = Global Storage.StorageBuffer      decs ty
type Private            decs ty = Global Storage.Private            decs ty
type Workgroup          decs ty = Global Storage.Workgroup          decs ty
type CrossWorkgroup     decs ty = Global Storage.CrossWorkgroup     decs ty
type AtomicCounter      decs ty = Global Storage.AtomicCounter      decs ty
type RayPayload         decs ty = Global ( 'Storage.RayStorage ( Storage.RayPayload   Storage.Lifetime ) ) decs ty
type RayPayloadIn       decs ty = Global ( 'Storage.RayStorage ( Storage.RayPayload   Storage.Incoming ) ) decs ty
type CallableData       decs ty = Global ( 'Storage.RayStorage ( Storage.CallableData Storage.Lifetime ) ) decs ty
type CallableDataIn     decs ty = Global ( 'Storage.RayStorage ( Storage.CallableData Storage.Incoming ) ) decs ty
type HitAttribute       decs ty = Global ( 'Storage.RayStorage Storage.HitAttribute                      ) decs ty
type ShaderRecordBuffer decs ty = Global ( 'Storage.RayStorage Storage.ShaderRecordBuffer                ) decs ty

-- synonym for function with no function control information
type Function     as b = Def.Function NoFunctionControl as b
type Function' fc as b = Def.Function fc as b

-- synonyms for images
type Texture1D decs fmt
  = Global Storage.UniformConstant
      decs
      ( Image
         (Properties FloatingPointCoordinates (FormatDefault fmt) OneD   (Just NotDepthImage) NonArrayed SingleSampled Sampled (Just fmt))
      )
type Texture2D decs fmt
  = Global Storage.UniformConstant
      decs
      ( Image
         (Properties FloatingPointCoordinates (FormatDefault fmt) TwoD   (Just NotDepthImage) NonArrayed SingleSampled Sampled (Just fmt))
      )
type Texture3D decs fmt
  = Global Storage.UniformConstant
      decs
      ( Image
         (Properties FloatingPointCoordinates (FormatDefault fmt) ThreeD (Just NotDepthImage) NonArrayed SingleSampled Sampled (Just fmt))
      )

type Image1D decs fmt
  = Global Storage.UniformConstant
      decs
      ( Image
         (Properties IntegralCoordinates (FormatDefault fmt) OneD   (Just NotDepthImage) NonArrayed SingleSampled Storage (Just fmt))
      )
type Image2D decs fmt
  = Global Storage.UniformConstant
      decs
      ( Image
         (Properties IntegralCoordinates (FormatDefault fmt) TwoD   (Just NotDepthImage) NonArrayed SingleSampled Storage (Just fmt))
      )
type Image3D decs fmt
  = Global Storage.UniformConstant
      decs
      ( Image
         (Properties IntegralCoordinates (FormatDefault fmt) ThreeD (Just NotDepthImage) NonArrayed SingleSampled Storage (Just fmt))
      )

type UnknownFormatImage1D decs texel
  = Global Storage.UniformConstant
      decs
      ( Image
         (Properties IntegralCoordinates texel OneD   (Just NotDepthImage) NonArrayed SingleSampled Storage Nothing)
      )
type UnknownFormatImage2D decs texel
  = Global Storage.UniformConstant
      decs
      ( Image
         (Properties IntegralCoordinates texel TwoD   (Just NotDepthImage) NonArrayed SingleSampled Storage Nothing)
      )
type UnknownFormatImage3D decs texel
  = Global Storage.UniformConstant
      decs
      ( Image
         (Properties IntegralCoordinates texel ThreeD (Just NotDepthImage) NonArrayed SingleSampled Storage Nothing)
      )

type Texture decs props
  = Global
      Storage.UniformConstant
      decs
      ( Image props )
type StorageImage decs props
  = Global
      Storage.UniformConstant
      decs
      ( Image props )

-- shorthand pattern synonyms for image operands
pattern DepthTestOffsets offs ops = Gather (DepthWithOffsets offs) ops
pattern GatherComponentWithOffsets component offs ops
  = Gather (ComponentWithOffsets component offs) ops

-----------------------------------------------------
-- helper type family for choosing image texel type

type family FormatDefault ( fmt :: ImageFormat Nat ) :: Type where
  FormatDefault ('ImageFormat Image.Floating (16 ': _)) = Half
  FormatDefault ('ImageFormat Image.Floating (_  ': _)) = Float
  FormatDefault ('ImageFormat (Image.Integer Normalised _) _ ) = Float
  FormatDefault ('ImageFormat (Image.Integer Unnormalised Signed  ) ( 8  ': _ )) = Int8
  FormatDefault ('ImageFormat (Image.Integer Unnormalised Signed  ) ( 16 ': _ )) = Int16
  FormatDefault ('ImageFormat (Image.Integer Unnormalised Signed  ) ( _  ': _ )) = Int32
  FormatDefault ('ImageFormat (Image.Integer Unnormalised Unsigned) ( 8  ': _ )) = Word8
  FormatDefault ('ImageFormat (Image.Integer Unnormalised Unsigned) ( 16 ': _ )) = Word16
  FormatDefault ('ImageFormat (Image.Integer Unnormalised Unsigned) ( _  ': _ )) = Word32

-----------------------------------------------------
-- pipeline synonyms

-- | Synonym for interface location slots.
type Slot (l :: Nat) (c :: Nat) = 'LocationSlot l c

-- | Utility pattern synonym for specifying a simple kind of vertex input:
-- use a single array of structs to keep track of vertex data.
pattern StructInput
  :: forall
        ( as        :: [LocationSlot Nat :-> Type] )
        ( top       :: PrimitiveTopology Nat       )
        ( descs     :: VertexLocationDescriptions  )
        ( stride    :: Nat                         )
        ( strides   :: BindingStrides              )
        ( stageData :: Type                        )
  .  ( descs   ~ StructLocationDescriptions 0 as
     , stride  ~ SizeOf Locations (Struct as)
     , strides ~ '[ 0 ':-> stride ]
     , Known (PrimitiveTopology Nat) top
     , Known VertexLocationDescriptions descs
     , KnownNat stride
     , Known BindingStrides strides
     )
  => ()
  => PipelineStages (VertexInputInfo top descs strides) stageData
pattern StructInput = VertexInput


-- internal helper type synonyms / type families used for the above pattern synonym

type StructLocationDescriptions ( bdNo :: Nat ) ( as :: [LocationSlot Nat :-> Type] )
  = ( AnnotateLocationsWithBindingAndOffset
        bdNo
        ( LocationDescriptionsOfStruct as )
    :: VertexLocationDescriptions
    )

type family AnnotateLocationsWithBindingAndOffset
              ( bdNo :: Nat )
              ( locationFormats :: [ Nat :-> SPIRV.ImageFormat Nat ] )
           :: [ Nat :-> ( Nat, Nat, SPIRV.ImageFormat Nat ) ]
           where
  AnnotateLocationsWithBindingAndOffset _ '[] = '[]
  AnnotateLocationsWithBindingAndOffset bdNo
    ( ( loc ':-> fmt ) ': locs )
      = ( loc ':-> '( bdNo, 16 * loc, fmt ) )
      ': AnnotateLocationsWithBindingAndOffset bdNo locs

type LocationDescriptionsOfStruct
      ( as :: [ LocationSlot Nat :-> Type ] )
    = ( ComputeFormats (InsertionSort as) :: [ Nat :-> SPIRV.ImageFormat Nat ] )

----------------------------------------------------------------------
-- synonyms for optics

type family FieldRes ( k :: Symbol ) ( struct :: Type ) :: Type where
  FieldRes k (Struct as)  = Value (StructIndexFromName k as)
  FieldRes k (Code (Struct as)) = Code (Value (StructIndexFromName k as))

type Field :: forall struct. forall (k :: Symbol) -> Optic '[] struct (FieldRes k struct)
type family Field @struct k where
  Field @(Struct as)        k = Field_ k
  Field @(Code (Struct as)) k = Field_ k

-- internal synonyms to help inference in subsequent definitions
type Col_ :: forall (m :: Nat) (n :: Nat) a. Nat -> Optic '[] (M m n a) (V m a)
type Col_  i = Index i

type Col__ :: forall (m :: Nat) (n :: Nat) a. Nat -> Optic '[] (Code (M m n a)) (Code (V m a))
type Col__ i = Index i

type Ix_ :: forall (n :: Nat) a. Nat -> Optic '[] (V n a) a
type Ix_   i = Index i

type Ix__ :: forall (n :: Nat) a. Nat -> Optic '[] (Code (V n a)) (Code a)
type Ix__  i = Index i

type family EltRes (t :: Type) :: Type where
  EltRes (V m a) = a
  EltRes (M m n a) = a
  EltRes (Array n a) = a
  EltRes (Code (V m a)) = Code a
  EltRes (Code (M m n a)) = Code a
  EltRes (Code (Array n a)) = Code a

type Elts :: forall t. Optic '[] t (EltRes t)
type family Elts @t where
  Elts @t = OfType (EltRes t)

type family ColRes (mat :: Type) :: Type where
  ColRes (Code (M m n a)) = Code (V m a)
  ColRes (M m n a) = V m a

type Col :: forall mat. Nat -> Optic '[] mat (ColRes mat)
type family Col i = optic | optic -> i where
  Col @(Code (M m n a)) i = Col__ i
  Col @(M m n a)        i = Col_  i

type Cols :: forall mat. Optic '[] mat (ColRes mat)
type family Cols @mat where
  Cols @mat = OfType (ColRes mat)

type family RowRes (mat :: Type) :: Type where
  RowRes (M m n a) = V n a
  RowRes (Code (M m n a)) = Code (V n a)

type Row :: forall mat. Nat -> Optic '[] mat (RowRes mat)
type family Row i where
  Row @(Code (M m 2 a)) i
    = Prod_
        (   (Col__ 0 :.: Ix__ i)
        :*: (Col__ 1 :.: Ix__ i)
        :*: EndProd
        )
  Row @(Code (M m 3 a)) i
    = Prod_
        (   (Col__ 0 :.: Ix__ i)
        :*: (Col__ 1 :.: Ix__ i)
        :*: (Col__ 2 :.: Ix__ i)
        :*: EndProd
        )
  Row @(Code (M m 4 a)) i
    = Prod_
        (   (Col__ 0 :.: Ix__ i)
        :*: (Col__ 1 :.: Ix__ i)
        :*: (Col__ 2 :.: Ix__ i)
        :*: (Col__ 3 :.: Ix__ i)
        :*: EndProd
        )
  Row @(M m 2 a) i
    = Prod_
        (   (Col_ 0 :.: Ix_ i)
        :*: (Col_ 1 :.: Ix_ i)
        :*: EndProd
        )
  Row @(M m 3 a) i
    = Prod_
        (   (Col_ 0 :.: Ix_ i)
        :*: (Col_ 1 :.: Ix_ i)
        :*: (Col_ 2 :.: Ix_ i)
        :*: EndProd
        )
  Row @(M m 4 a) i
    = Prod_
        (   (Col_ 0 :.: Ix_ i)
        :*: (Col_ 1 :.: Ix_ i)
        :*: (Col_ 2 :.: Ix_ i)
        :*: (Col_ 3 :.: Ix_ i)
        :*: EndProd
        )

type Rows :: forall mat. Optic '[] mat (RowRes mat)
type family Rows @mat where
  Rows @(M 2 n a)
    = ( Prod_ ( Row 0 :*: Row 1 :*: EndProd )
          :: Optic '[] (M 2 n a) (Struct '[ "row0" ':-> V n a, "row1" ':-> V n a]) )
    :.: OfType (V n a)
  Rows @(M 3 n a)
    = ( Prod_ ( Row 0 :*: Row 1 :*: Row 2 :*: EndProd )
          :: Optic '[] (M 3 n a) (Struct '[ "row0" ':-> V n a, "row1" ':-> V n a, "row2" ':-> V n a]) )
    :.: OfType (V n a)
  Rows @(M 4 n a)
    = ( Prod_ ( Row 0 :*: Row 1 :*: Row 2 :*: Row 3 :*: EndProd )
          :: Optic '[] (M 4 n a) (Struct '[ "row0" ':-> V n a, "row1" ':-> V n a, "row2" ':-> V n a, "row3" ':-> V n a ]) )
    :.: OfType (V n a)
  Rows @(Code (M 2 n a))
    = ( Prod_ ( Row 0 :*: Row 1 :*: EndProd )
          :: Optic '[] (Code (M 2 n a)) (Struct '[ "row0" ':-> Code (V n a), "row1" ':-> Code (V n a)]) )
    :.: OfType (Code (V n a))
  Rows @(Code (M 3 n a))
    = ( Prod_ ( Row 0 :*: Row 1 :*: Row 2 :*: EndProd )
          :: Optic '[] (Code (M 3 n a)) (Struct '[ "row0" ':-> Code (V n a), "row1" ':-> Code (V n a), "row2" ':-> Code (V n a)]) )
    :.: OfType (Code (V n a))
  Rows @(Code (M 4 n a))
    = ( Prod_ ( Row 0 :*: Row 1 :*: Row 2 :*: Row 3 :*: EndProd )
          :: Optic '[] (Code (M 4 n a)) (Struct '[ "row0" ':-> Code (V n a), "row1" ':-> Code (V n a), "row2" ':-> Code (V n a), "row3" ':-> Code (V n a)]) )
    :.: OfType (Code (V n a))

type family EntryRes (mat :: Type) :: Type where
  EntryRes (M m n a) = a
  EntryRes (Code (M m n a)) = Code a

type Entry :: forall mat. Nat -> Nat -> Optic '[] mat (EntryRes mat)
type family Entry i j where
  Entry @(M m n a)        i j = Col_  j :.: Ix_  i
  Entry @(Code (M m n a)) i j = Col__ j :.: Ix__ i

type family DiagRes (mat :: Type) :: Type where
  DiagRes (M n n a) = V n a
  DiagRes (Code (M n n a)) = Code (V n a)

type Diag :: forall mat. Optic '[] mat (DiagRes mat)
type family Diag @mat where
  Diag @(M 2 2 a)
    = Prod_
        (   (Col_ 0 :.: Ix_ 0)
        :*: (Col_ 1 :.: Ix_ 1)
        :*: EndProd
        )
  Diag @(M 3 3 a)
    = Prod_
        (   (Col_ 0 :.: Ix_ 0)
        :*: (Col_ 1 :.: Ix_ 1)
        :*: (Col_ 2 :.: Ix_ 2)
        :*: EndProd
        )
  Diag @(M 4 4 a)
    = Prod_
        (   (Col_ 0 :.: Ix_ 0)
        :*: (Col_ 1 :.: Ix_ 1)
        :*: (Col_ 2 :.: Ix_ 2)
        :*: (Col_ 3 :.: Ix_ 3)
        :*: EndProd
        )
  Diag @(Code (M 2 2 a))
    = Prod_
        (   (Col__ 0 :.: Ix__ 0)
        :*: (Col__ 1 :.: Ix__ 1)
        :*: EndProd
        )
  Diag @(Code (M 3 3 a))
    = Prod_
        (   (Col__ 0 :.: Ix__ 0)
        :*: (Col__ 1 :.: Ix__ 1)
        :*: (Col__ 2 :.: Ix__ 2)
        :*: EndProd
        )
  Diag @(Code (M 4 4 a))
    = Prod_
        (   (Col__ 0 :.: Ix__ 0)
        :*: (Col__ 1 :.: Ix__ 1)
        :*: (Col__ 2 :.: Ix__ 2)
        :*: (Col__ 3 :.: Ix__ 3)
        :*: EndProd
        )

type Center :: forall mat. Optic '[] mat (EntryRes mat)
type family Center @mat where
  Center @mat = Diag @mat :.: OfType (EntryRes mat)

----------------------------------------------------------------------
-- pattern synonyms for vectors/matrices

-- these patterns could be generalised to have types such as:
-- Vec2 :: forall a. (Syntactic a, PrimTy (Internal a))
--      => a -> a -> Code ( V 2 (Internal a) )
-- but this leads to poor type-inference

{-# COMPLETE Vec2 #-}
pattern Vec2 :: forall a. PrimTy a => Code a -> Code a -> Code ( V 2 a )
pattern Vec2 x y <- (fromAST -> V2 x y)
  where Vec2 x y = MkVector ( V2 x y )

{-# COMPLETE Vec3 #-}
pattern Vec3 :: forall a. PrimTy a => Code a -> Code a -> Code a -> Code ( V 3 a )
pattern Vec3 x y z <- (fromAST -> V3 x y z)
  where Vec3 x y z = MkVector ( V3 x y z )

{-# COMPLETE Vec4 #-}
pattern Vec4 :: forall a. PrimTy a => Code a -> Code a -> Code a -> Code a -> Code ( V 4 a )
pattern Vec4 x y z w <- (fromAST -> V4 x y z w)
  where Vec4 x y z w = MkVector ( V4 x y z w )

{-# COMPLETE Mat22 #-}
pattern Mat22
  :: ScalarTy a
  => Code a -> Code a
  -> Code a -> Code a
  -> Code ( M 2 2 a )
pattern Mat22 a11 a12
              a21 a22
  <- ( fromAST . ( UnMat :$ )
       -> V2 ( V2 a11 a21 )
             ( V2 a12 a22 )
     )
  where Mat22
            a11 a12
            a21 a22
          = Mat :$ Vec2
            ( Vec2 a11 a21 )
            ( Vec2 a12 a22 )

{-# COMPLETE Mat23 #-}
pattern Mat23
  :: ScalarTy a
  => Code a -> Code a -> Code a
  -> Code a -> Code a -> Code a
  -> Code ( M 2 3 a )
pattern Mat23 a11 a12 a13
              a21 a22 a23
   <- ( fromAST . ( UnMat :$ )
        -> V3 ( V2 a11 a21 )
              ( V2 a12 a22 )
              ( V2 a13 a23 )
      )
  where Mat23
            a11 a12 a13
            a21 a22 a23
          = Mat :$ Vec3
              ( Vec2 a11 a21 )
              ( Vec2 a12 a22 )
              ( Vec2 a13 a23 )

{-# COMPLETE Mat24 #-}
pattern Mat24
  :: ScalarTy a
  => Code a -> Code a -> Code a -> Code a
  -> Code a -> Code a -> Code a -> Code a
  -> Code ( M 2 4 a )
pattern Mat24 a11 a12 a13 a14
              a21 a22 a23 a24
   <- ( fromAST . ( UnMat :$ )
        -> V4 ( V2 a11 a21 )
              ( V2 a12 a22 )
              ( V2 a13 a23 )
              ( V2 a14 a24 )
      )
  where Mat24
            a11 a12 a13 a14
            a21 a22 a23 a24
          = Mat :$ Vec4
              ( Vec2 a11 a21 )
              ( Vec2 a12 a22 )
              ( Vec2 a13 a23 )
              ( Vec2 a14 a24 )

{-# COMPLETE Mat32 #-}
pattern Mat32
  :: ScalarTy a
  => Code a -> Code a
  -> Code a -> Code a
  -> Code a -> Code a
  -> Code ( M 3 2 a )
pattern Mat32 a11 a12
              a21 a22
              a31 a32
   <- ( fromAST . ( UnMat :$ )
        -> V2 ( V3 a11 a21 a31 )
              ( V3 a12 a22 a32 )
      )
  where Mat32
            a11 a12
            a21 a22
            a31 a32
          = Mat :$ Vec2
              ( Vec3 a11 a21 a31 )
              ( Vec3 a12 a22 a32 )

{-# COMPLETE Mat33 #-}
pattern Mat33
  :: ScalarTy a
  => Code a -> Code a -> Code a
  -> Code a -> Code a -> Code a
  -> Code a -> Code a -> Code a
  -> Code ( M 3 3 a )
pattern Mat33 a11 a12 a13
              a21 a22 a23
              a31 a32 a33
   <- ( fromAST . ( UnMat :$ )
        -> V3 ( V3 a11 a21 a31 )
              ( V3 a12 a22 a32 )
              ( V3 a13 a23 a33 )
      )
  where Mat33
            a11 a12 a13
            a21 a22 a23
            a31 a32 a33
          = Mat :$ Vec3
              ( Vec3 a11 a21 a31 )
              ( Vec3 a12 a22 a32 )
              ( Vec3 a13 a23 a33 )

{-# COMPLETE Mat34 #-}
pattern Mat34
  :: ScalarTy a
  => Code a -> Code a -> Code a -> Code a
  -> Code a -> Code a -> Code a -> Code a
  -> Code a -> Code a -> Code a -> Code a
  -> Code ( M 3 4 a )
pattern Mat34 a11 a12 a13 a14
              a21 a22 a23 a24
              a31 a32 a33 a34
   <- ( fromAST . ( UnMat :$ )
        -> V4 ( V3 a11 a21 a31 )
              ( V3 a12 a22 a32 )
              ( V3 a13 a23 a33 )
              ( V3 a14 a24 a34 )
      )
  where Mat34
            a11 a12 a13 a14
            a21 a22 a23 a24
            a31 a32 a33 a34
          = Mat :$ Vec4
              ( Vec3 a11 a21 a31 )
              ( Vec3 a12 a22 a32 )
              ( Vec3 a13 a23 a33 )
              ( Vec3 a14 a24 a34 )

{-# COMPLETE Mat42 #-}
pattern Mat42
  :: ScalarTy a
  => Code a -> Code a
  -> Code a -> Code a
  -> Code a -> Code a
  -> Code a -> Code a
  -> Code ( M 4 2 a )
pattern Mat42 a11 a12
              a21 a22
              a31 a32
              a41 a42
   <- ( fromAST . ( UnMat :$ )
        -> V2 ( V4 a11 a21 a31 a41 )
              ( V4 a12 a22 a32 a42 )
      )
  where Mat42
            a11 a12
            a21 a22
            a31 a32
            a41 a42
          = Mat :$ Vec2
              ( Vec4 a11 a21 a31 a41 )
              ( Vec4 a12 a22 a32 a42 )

{-# COMPLETE Mat43 #-}
pattern Mat43
  :: ScalarTy a
  => Code a -> Code a -> Code a
  -> Code a -> Code a -> Code a
  -> Code a -> Code a -> Code a
  -> Code a -> Code a -> Code a
  -> Code ( M 4 3 a )
pattern Mat43 a11 a12 a13
              a21 a22 a23
              a31 a32 a33
              a41 a42 a43
   <- ( fromAST . ( UnMat :$ )
        -> V3 ( V4 a11 a21 a31 a41 )
              ( V4 a12 a22 a32 a42 )
              ( V4 a13 a23 a33 a43 )
      )
  where Mat43
            a11 a12 a13
            a21 a22 a23
            a31 a32 a33
            a41 a42 a43
          = Mat :$ Vec3
              ( Vec4 a11 a21 a31 a41 )
              ( Vec4 a12 a22 a32 a42 )
              ( Vec4 a13 a23 a33 a43 )

{-# COMPLETE Mat44 #-}
pattern Mat44
  :: ScalarTy a
  => Code a -> Code a -> Code a -> Code a
  -> Code a -> Code a -> Code a -> Code a
  -> Code a -> Code a -> Code a -> Code a
  -> Code a -> Code a -> Code a -> Code a
  -> Code ( M 4 4 a )
pattern Mat44 a11 a12 a13 a14
              a21 a22 a23 a24
              a31 a32 a33 a34
              a41 a42 a43 a44
   <- ( fromAST . ( UnMat :$ )
        -> V4 ( V4 a11 a21 a31 a41 )
              ( V4 a12 a22 a32 a42 )
              ( V4 a13 a23 a33 a43 )
              ( V4 a14 a24 a34 a44 )
      )
  where Mat44
            a11 a12 a13 a14
            a21 a22 a23 a24
            a31 a32 a33 a34
            a41 a42 a43 a44
          = Mat :$ Vec4
              ( Vec4 a11 a21 a31 a41 )
              ( Vec4 a12 a22 a32 a42 )
              ( Vec4 a13 a23 a33 a43 )
              ( Vec4 a14 a24 a34 a44 )

-- Ray flags.
pattern RayFlagsNone :: Word32
pattern RayFlagsNone = 0
pattern RayFlagsOpaque :: Word32
pattern RayFlagsOpaque = 1
pattern RayFlagsNoOpaque :: Word32
pattern RayFlagsNoOpaque = 2
pattern RayFlagsTerminateOnFirstHit :: Word32
pattern RayFlagsTerminateOnFirstHit = 4
pattern RayFlagsSkipClosestHitShader :: Word32
pattern RayFlagsSkipClosestHitShader = 8
pattern RayFlagsCullBackFacingTriangles :: Word32
pattern RayFlagsCullBackFacingTriangles = 16
pattern RayFlagsCullFrontFacingTriangles :: Word32
pattern RayFlagsCullFrontFacingTriangles = 32
pattern RayFlagsCullOpaque :: Word32
pattern RayFlagsCullOpaque = 64
pattern RayFlagsCullNoOpaque :: Word32
pattern RayFlagsCullNoOpaque = 128

pattern HitKindFrontFacingTriangle :: Word32
pattern HitKindFrontFacingTriangle = 0xfe
pattern HitKindBackFacingTriangle :: Word32
pattern HitKindBackFacingTriangle = 0xff