{-# LANGUAGE MultiParamTypeClasses #-}
module Language.SpirV.StorageClass 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_storage_class_a_storage_class Source for Storage Class>
data StorageClass =
    UniformConstant
  | Input
  | Uniform
  | Output
  | Workgroup
  | CrossWorkgroup
  | Private
  | Function
  | Generic
  | PushConstant
  | AtomicCounter
  | Image
  deriving(Read, Show, Eq, Ord)

instance SpirEnum StorageClass Word32 where
  toWord UniformConstant = 0
  toWord Input = 1
  toWord Uniform = 2
  toWord Output = 3
  toWord Workgroup = 4
  toWord CrossWorkgroup = 5
  toWord Private = 6
  toWord Function = 7
  toWord Generic = 8
  toWord PushConstant = 9
  toWord AtomicCounter = 10
  toWord Image = 11

  fromWord 0 = Just UniformConstant
  fromWord 1 = Just Input
  fromWord 2 = Just Uniform
  fromWord 3 = Just Output
  fromWord 4 = Just Workgroup
  fromWord 5 = Just CrossWorkgroup
  fromWord 6 = Just Private
  fromWord 7 = Just Function
  fromWord 8 = Just Generic
  fromWord 9 = Just PushConstant
  fromWord 10 = Just AtomicCounter
  fromWord 11 = Just Image
  fromWord _ = Nothing

  requiredCapabilities Input = [Capability.Shader]
  requiredCapabilities Uniform = [Capability.Shader]
  requiredCapabilities Output = [Capability.Shader]
  requiredCapabilities Private = [Capability.Shader]
  requiredCapabilities Generic = [Capability.GenericPointer]
  requiredCapabilities PushConstant = [Capability.Shader]
  requiredCapabilities AtomicCounter = [Capability.AtomicStorage]
  requiredCapabilities _ = []