{-# LANGUAGE MultiParamTypeClasses #-}
module Language.SpirV.BuiltIn where

import Data.Word (Word32)
import Language.SpirV.SpirEnum
import qualified Language.SpirV.Capability as Capability


-- | <https:\/\/www.khronos.org\/registry\/spir-v\/specs\/1.0\/SPIRV.html#_a_id_builtin_a_builtin Source for BuiltIn>
data BuiltIn =
    Position
  | PointSize
  | ClipDistance
  | CullDistance
  | VertexId
  | InstanceId
  | PrimitiveId
  | InvocationId
  | Layer
  | ViewportIndex
  | TessLevelOuter
  | TessLevelInner
  | TessCoord
  | PatchVertices
  | FragCoord
  | PointCoord
  | FrontFacing
  | SampleId
  | SamplePosition
  | SampleMask
  | FragDepth
  | HelperInvocation
  | NumWorkgroups
  | WorkgroupSize
  | WorkgroupId
  | LocalInvocationId
  | GlobalInvocationId
  | LocalInvocationIndex
  | WorkDim
  | GlobalSize
  | EnqueuedWorkgroupSize
  | GlobalOffset
  | GlobalLinearId
  | SubgroupSize
  | SubgroupMaxSize
  | NumSubgroups
  | NumEnqueuedSubgroups
  | SubgroupId
  | SubgroupLocalInvocationId
  | VertexIndex
  | InstanceIndex
  deriving(Read, Show, Eq, Ord)

instance SpirEnum BuiltIn Word32 where
  toWord Position = 0
  toWord PointSize = 1
  toWord ClipDistance = 3
  toWord CullDistance = 4
  toWord VertexId = 5
  toWord InstanceId = 6
  toWord PrimitiveId = 7
  toWord InvocationId = 8
  toWord Layer = 9
  toWord ViewportIndex = 10
  toWord TessLevelOuter = 11
  toWord TessLevelInner = 12
  toWord TessCoord = 13
  toWord PatchVertices = 14
  toWord FragCoord = 15
  toWord PointCoord = 16
  toWord FrontFacing = 17
  toWord SampleId = 18
  toWord SamplePosition = 19
  toWord SampleMask = 20
  toWord FragDepth = 22
  toWord HelperInvocation = 23
  toWord NumWorkgroups = 24
  toWord WorkgroupSize = 25
  toWord WorkgroupId = 26
  toWord LocalInvocationId = 27
  toWord GlobalInvocationId = 28
  toWord LocalInvocationIndex = 29
  toWord WorkDim = 30
  toWord GlobalSize = 31
  toWord EnqueuedWorkgroupSize = 32
  toWord GlobalOffset = 33
  toWord GlobalLinearId = 34
  toWord SubgroupSize = 36
  toWord SubgroupMaxSize = 37
  toWord NumSubgroups = 38
  toWord NumEnqueuedSubgroups = 39
  toWord SubgroupId = 40
  toWord SubgroupLocalInvocationId = 41
  toWord VertexIndex = 42
  toWord InstanceIndex = 43

  fromWord 0 = Just Position
  fromWord 1 = Just PointSize
  fromWord 3 = Just ClipDistance
  fromWord 4 = Just CullDistance
  fromWord 5 = Just VertexId
  fromWord 6 = Just InstanceId
  fromWord 7 = Just PrimitiveId
  fromWord 8 = Just InvocationId
  fromWord 9 = Just Layer
  fromWord 10 = Just ViewportIndex
  fromWord 11 = Just TessLevelOuter
  fromWord 12 = Just TessLevelInner
  fromWord 13 = Just TessCoord
  fromWord 14 = Just PatchVertices
  fromWord 15 = Just FragCoord
  fromWord 16 = Just PointCoord
  fromWord 17 = Just FrontFacing
  fromWord 18 = Just SampleId
  fromWord 19 = Just SamplePosition
  fromWord 20 = Just SampleMask
  fromWord 22 = Just FragDepth
  fromWord 23 = Just HelperInvocation
  fromWord 24 = Just NumWorkgroups
  fromWord 25 = Just WorkgroupSize
  fromWord 26 = Just WorkgroupId
  fromWord 27 = Just LocalInvocationId
  fromWord 28 = Just GlobalInvocationId
  fromWord 29 = Just LocalInvocationIndex
  fromWord 30 = Just WorkDim
  fromWord 31 = Just GlobalSize
  fromWord 32 = Just EnqueuedWorkgroupSize
  fromWord 33 = Just GlobalOffset
  fromWord 34 = Just GlobalLinearId
  fromWord 36 = Just SubgroupSize
  fromWord 37 = Just SubgroupMaxSize
  fromWord 38 = Just NumSubgroups
  fromWord 39 = Just NumEnqueuedSubgroups
  fromWord 40 = Just SubgroupId
  fromWord 41 = Just SubgroupLocalInvocationId
  fromWord 42 = Just VertexIndex
  fromWord 43 = Just InstanceIndex
  fromWord _ = Nothing

  requiredCapabilities Position = [Capability.Shader]
  requiredCapabilities PointSize = [Capability.Shader]
  requiredCapabilities ClipDistance = [Capability.ClipDistance]
  requiredCapabilities CullDistance = [Capability.CullDistance]
  requiredCapabilities VertexId = [Capability.Shader]
  requiredCapabilities InstanceId = [Capability.Shader]
  requiredCapabilities PrimitiveId = [Capability.Geometry , Capability.Tessellation]
  requiredCapabilities InvocationId = [Capability.Geometry , Capability.Tessellation]
  requiredCapabilities Layer = [Capability.Geometry]
  requiredCapabilities ViewportIndex = [Capability.MultiViewport]
  requiredCapabilities TessLevelOuter = [Capability.Tessellation]
  requiredCapabilities TessLevelInner = [Capability.Tessellation]
  requiredCapabilities TessCoord = [Capability.Tessellation]
  requiredCapabilities PatchVertices = [Capability.Tessellation]
  requiredCapabilities FragCoord = [Capability.Shader]
  requiredCapabilities PointCoord = [Capability.Shader]
  requiredCapabilities FrontFacing = [Capability.Shader]
  requiredCapabilities SampleId = [Capability.SampleRateShading]
  requiredCapabilities SamplePosition = [Capability.SampleRateShading]
  requiredCapabilities SampleMask = [Capability.SampleRateShading]
  requiredCapabilities FragDepth = [Capability.Shader]
  requiredCapabilities HelperInvocation = [Capability.Shader]
  requiredCapabilities WorkDim = [Capability.Kernel]
  requiredCapabilities GlobalSize = [Capability.Kernel]
  requiredCapabilities EnqueuedWorkgroupSize = [Capability.Kernel]
  requiredCapabilities GlobalOffset = [Capability.Kernel]
  requiredCapabilities GlobalLinearId = [Capability.Kernel]
  requiredCapabilities SubgroupSize = [Capability.Kernel]
  requiredCapabilities SubgroupMaxSize = [Capability.Kernel]
  requiredCapabilities NumSubgroups = [Capability.Kernel]
  requiredCapabilities NumEnqueuedSubgroups = [Capability.Kernel]
  requiredCapabilities SubgroupId = [Capability.Kernel]
  requiredCapabilities SubgroupLocalInvocationId = [Capability.Kernel]
  requiredCapabilities VertexIndex = [Capability.Shader]
  requiredCapabilities InstanceIndex = [Capability.Shader]
  requiredCapabilities _ = []