{-# LANGUAGE MultiParamTypeClasses #-}
module Language.SpirV.MemorySemantics 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_memory_semantics__id_a_memory_semantics_lt_id_gt Source for Memory Semantics>
data MemorySemantics =
    NoneRelaxed
  | Acquire
  | Release
  | AcquireRelease
  | SequentiallyConsistent
  | UniformMemory
  | SubgroupMemory
  | WorkgroupMemory
  | CrossWorkgroupMemory
  | AtomicCounterMemory
  | ImageMemory
  deriving(Read, Show, Eq, Ord)

instance SpirEnum MemorySemantics Word32 where
  toWord NoneRelaxed = 0
  toWord Acquire = 2
  toWord Release = 4
  toWord AcquireRelease = 8
  toWord SequentiallyConsistent = 16
  toWord UniformMemory = 64
  toWord SubgroupMemory = 128
  toWord WorkgroupMemory = 256
  toWord CrossWorkgroupMemory = 512
  toWord AtomicCounterMemory = 1024
  toWord ImageMemory = 2048

  fromWord 0 = Just NoneRelaxed
  fromWord 2 = Just Acquire
  fromWord 4 = Just Release
  fromWord 8 = Just AcquireRelease
  fromWord 16 = Just SequentiallyConsistent
  fromWord 64 = Just UniformMemory
  fromWord 128 = Just SubgroupMemory
  fromWord 256 = Just WorkgroupMemory
  fromWord 512 = Just CrossWorkgroupMemory
  fromWord 1024 = Just AtomicCounterMemory
  fromWord 2048 = Just ImageMemory
  fromWord _ = Nothing

  requiredCapabilities UniformMemory = [Capability.Shader]
  requiredCapabilities AtomicCounterMemory = [Capability.AtomicStorage]
  requiredCapabilities _ = []