{-# language CPP #-}
-- | = Name
--
-- VK_NV_fragment_shader_barycentric - device extension
--
-- == VK_NV_fragment_shader_barycentric
--
-- [__Name String__]
--     @VK_NV_fragment_shader_barycentric@
--
-- [__Extension Type__]
--     Device extension
--
-- [__Registered Extension Number__]
--     204
--
-- [__Revision__]
--     1
--
-- [__Extension and Version Dependencies__]
--
--     -   Requires Vulkan 1.0
--
--     -   Requires @VK_KHR_get_physical_device_properties2@
--
-- [__Contact__]
--
--     -   Pat Brown
--         <https://github.com/KhronosGroup/Vulkan-Docs/issues/new?title=VK_NV_fragment_shader_barycentric:%20&body=@nvpbrown%20 >
--
-- == Other Extension Metadata
--
-- [__Last Modified Date__]
--     2018-08-03
--
-- [__IP Status__]
--     No known IP claims.
--
-- [__Interactions and External Dependencies__]
--
--     -   This extension requires
--         <https://htmlpreview.github.io/?https://github.com/KhronosGroup/SPIRV-Registry/blob/master/extensions/NV/SPV_NV_fragment_shader_barycentric.html SPV_NV_fragment_shader_barycentric>
--
--     -   This extension provides API support for
--         <https://github.com/KhronosGroup/GLSL/blob/master/extensions/nv/GLSL_NV_fragment_shader_barycentric.txt GL_NV_fragment_shader_barycentric>
--
-- [__Contributors__]
--
--     -   Pat Brown, NVIDIA
--
--     -   Daniel Koch, NVIDIA
--
-- == Description
--
-- This extension adds support for the following SPIR-V extension in
-- Vulkan:
--
-- -   <https://htmlpreview.github.io/?https://github.com/KhronosGroup/SPIRV-Registry/blob/master/extensions/NV/SPV_NV_fragment_shader_barycentric.html SPV_NV_fragment_shader_barycentric>
--
-- The extension provides access to three additional fragment shader
-- variable decorations in SPIR-V:
--
-- -   @PerVertexNV@, which indicates that a fragment shader input will not
--     have interpolated values, but instead must be accessed with an extra
--     array index that identifies one of the vertices of the primitive
--     producing the fragment
--
-- -   @BaryCoordNV@, which indicates that the variable is a
--     three-component floating-point vector holding barycentric weights
--     for the fragment produced using perspective interpolation
--
-- -   @BaryCoordNoPerspNV@, which indicates that the variable is a
--     three-component floating-point vector holding barycentric weights
--     for the fragment produced using linear interpolation
--
-- When using GLSL source-based shader languages, the following variables
-- from @GL_NV_fragment_shader_barycentric@ maps to these SPIR-V built-in
-- decorations:
--
-- -   @in vec3 gl_BaryCoordNV;@ → @BaryCoordNV@
--
-- -   @in vec3 gl_BaryCoordNoPerspNV;@ → @BaryCoordNoPerspNV@
--
-- GLSL variables declared using the @__pervertexNV@ GLSL qualifier are
-- expected to be decorated with @PerVertexNV@ in SPIR-V.
--
-- == New Structures
--
-- -   Extending
--     'Vulkan.Core11.Promoted_From_VK_KHR_get_physical_device_properties2.PhysicalDeviceFeatures2',
--     'Vulkan.Core10.Device.DeviceCreateInfo':
--
--     -   'PhysicalDeviceFragmentShaderBarycentricFeaturesNV'
--
-- == New Enum Constants
--
-- -   'NV_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME'
--
-- -   'NV_FRAGMENT_SHADER_BARYCENTRIC_SPEC_VERSION'
--
-- -   Extending 'Vulkan.Core10.Enums.StructureType.StructureType':
--
--     -   'Vulkan.Core10.Enums.StructureType.STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_NV'
--
-- == New Built-In Variables
--
-- -   <https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#interfaces-builtin-variables-barycoordnv BaryCoordNV>
--
-- -   <https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#interfaces-builtin-variables-barycoordnoperspnv BaryCoordNoPerspNV>
--
-- == New SPIR-V Decorations
--
-- -   <https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#shaders-interpolation-decorations-pervertexnv PerVertexNV>
--
-- == New SPIR-V Capabilities
--
-- -   <https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#spirvenv-capabilities-fragment-barycentric FragmentBarycentricNV>
--
-- == Issues
--
-- (1) The AMD_shader_explicit_vertex_parameter extension provides similar
-- functionality. Why write a new extension, and how is this extension
-- different?
--
-- __RESOLVED__: For the purposes of Vulkan\/SPIR-V, we chose to implement
-- a separate extension due to several functional differences.
--
-- First, the hardware supporting this extension can provide a
-- three-component barycentric weight vector for variables decorated with
-- @BaryCoordNV@, while variables decorated with @BaryCoordSmoothAMD@
-- provide only two components. In some cases, it may be more efficient to
-- explicitly interpolate an attribute via:
--
-- > float value = (baryCoordNV.x * v[0].attrib +
-- >                baryCoordNV.y * v[1].attrib +
-- >                baryCoordNV.z * v[2].attrib);
--
-- instead of
--
-- > float value = (baryCoordSmoothAMD.x * (v[0].attrib - v[2].attrib) +
-- >                baryCoordSmoothAMD.y * (v[1].attrib - v[2].attrib) +
-- >                v[2].attrib);
--
-- Additionally, the semantics of the decoration @BaryCoordPullModelAMD@ do
-- not appear to map to anything supported by the initial hardware
-- implementation of this extension.
--
-- This extension provides a smaller number of decorations than the AMD
-- extension, as we expect that shaders could derive variables decorated
-- with things like @BaryCoordNoPerspCentroidAMD@ with explicit attribute
-- interpolation instructions. One other relevant difference is that
-- explicit per-vertex attribute access using this extension does not
-- require a constant vertex number.
--
-- (2) Why do the built-in SPIR-V decorations for this extension include
-- two separate built-ins @BaryCoordNV@ and @BaryCoordNoPerspNV@ when a “no
-- perspective” variable could be decorated with @BaryCoordNV@ and
-- @NoPerspective@?
--
-- __RESOLVED__: The SPIR-V extension for this feature chose to mirror the
-- behavior of the GLSL extension, which provides two built-in variables.
-- Additionally, it’s not clear that its a good idea (or even legal) to
-- have two variables using the “same attribute”, but with different
-- interpolation modifiers.
--
-- == Version History
--
-- -   Revision 1, 2018-08-03 (Pat Brown)
--
--     -   Internal revisions
--
-- = See Also
--
-- 'PhysicalDeviceFragmentShaderBarycentricFeaturesNV'
--
-- = Document Notes
--
-- For more information, see the
-- <https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#VK_NV_fragment_shader_barycentric Vulkan Specification>
--
-- This page is a generated document. Fixes and changes should be made to
-- the generator scripts, not directly.
module Vulkan.Extensions.VK_NV_fragment_shader_barycentric  ( PhysicalDeviceFragmentShaderBarycentricFeaturesNV(..)
                                                            , NV_FRAGMENT_SHADER_BARYCENTRIC_SPEC_VERSION
                                                            , pattern NV_FRAGMENT_SHADER_BARYCENTRIC_SPEC_VERSION
                                                            , NV_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME
                                                            , pattern NV_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME
                                                            ) where

import Foreign.Marshal.Alloc (allocaBytesAligned)
import Foreign.Ptr (nullPtr)
import Foreign.Ptr (plusPtr)
import Vulkan.CStruct (FromCStruct)
import Vulkan.CStruct (FromCStruct(..))
import Vulkan.CStruct (ToCStruct)
import Vulkan.CStruct (ToCStruct(..))
import Vulkan.Zero (Zero(..))
import Data.String (IsString)
import Data.Typeable (Typeable)
import Foreign.Storable (Storable)
import Foreign.Storable (Storable(peek))
import Foreign.Storable (Storable(poke))
import qualified Foreign.Storable (Storable(..))
import GHC.Generics (Generic)
import Foreign.Ptr (Ptr)
import Data.Kind (Type)
import Vulkan.Core10.FundamentalTypes (bool32ToBool)
import Vulkan.Core10.FundamentalTypes (boolToBool32)
import Vulkan.Core10.FundamentalTypes (Bool32)
import Vulkan.Core10.Enums.StructureType (StructureType)
import Vulkan.Core10.Enums.StructureType (StructureType(STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_NV))
-- | VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV - Structure
-- describing barycentric support in fragment shaders that can be supported
-- by an implementation
--
-- = Members
--
-- The members of the 'PhysicalDeviceFragmentShaderBarycentricFeaturesNV'
-- structure describe the following features:
--
-- = Description
--
-- See
-- <https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#primsrast-barycentric Barycentric Interpolation>
-- for more information.
--
-- If the 'PhysicalDeviceFragmentShaderBarycentricFeaturesNV' structure is
-- included in the @pNext@ chain of
-- 'Vulkan.Core11.Promoted_From_VK_KHR_get_physical_device_properties2.PhysicalDeviceFeatures2',
-- it is filled with values indicating whether the feature is supported.
-- 'PhysicalDeviceFragmentShaderBarycentricFeaturesNV' /can/ also be
-- included in the @pNext@ chain of 'Vulkan.Core10.Device.DeviceCreateInfo'
-- to enable features.
--
-- == Valid Usage (Implicit)
--
-- = See Also
--
-- 'Vulkan.Core10.FundamentalTypes.Bool32',
-- 'Vulkan.Core10.Enums.StructureType.StructureType'
data PhysicalDeviceFragmentShaderBarycentricFeaturesNV = PhysicalDeviceFragmentShaderBarycentricFeaturesNV
  { -- | #features-fragmentShaderBarycentric# @fragmentShaderBarycentric@
    -- indicates that the implementation supports the @BaryCoordNV@ and
    -- @BaryCoordNoPerspNV@ SPIR-V fragment shader built-ins and supports the
    -- @PerVertexNV@ SPIR-V decoration on fragment shader input variables.
    PhysicalDeviceFragmentShaderBarycentricFeaturesNV -> Bool
fragmentShaderBarycentric :: Bool }
  deriving (Typeable, PhysicalDeviceFragmentShaderBarycentricFeaturesNV
-> PhysicalDeviceFragmentShaderBarycentricFeaturesNV -> Bool
(PhysicalDeviceFragmentShaderBarycentricFeaturesNV
 -> PhysicalDeviceFragmentShaderBarycentricFeaturesNV -> Bool)
-> (PhysicalDeviceFragmentShaderBarycentricFeaturesNV
    -> PhysicalDeviceFragmentShaderBarycentricFeaturesNV -> Bool)
-> Eq PhysicalDeviceFragmentShaderBarycentricFeaturesNV
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PhysicalDeviceFragmentShaderBarycentricFeaturesNV
-> PhysicalDeviceFragmentShaderBarycentricFeaturesNV -> Bool
$c/= :: PhysicalDeviceFragmentShaderBarycentricFeaturesNV
-> PhysicalDeviceFragmentShaderBarycentricFeaturesNV -> Bool
== :: PhysicalDeviceFragmentShaderBarycentricFeaturesNV
-> PhysicalDeviceFragmentShaderBarycentricFeaturesNV -> Bool
$c== :: PhysicalDeviceFragmentShaderBarycentricFeaturesNV
-> PhysicalDeviceFragmentShaderBarycentricFeaturesNV -> Bool
Eq)
#if defined(GENERIC_INSTANCES)
deriving instance Generic (PhysicalDeviceFragmentShaderBarycentricFeaturesNV)
#endif
deriving instance Show PhysicalDeviceFragmentShaderBarycentricFeaturesNV

instance ToCStruct PhysicalDeviceFragmentShaderBarycentricFeaturesNV where
  withCStruct :: PhysicalDeviceFragmentShaderBarycentricFeaturesNV
-> (Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV -> IO b)
-> IO b
withCStruct x :: PhysicalDeviceFragmentShaderBarycentricFeaturesNV
x f :: Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV -> IO b
f = Int
-> Int
-> (Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV -> IO b)
-> IO b
forall a b. Int -> Int -> (Ptr a -> IO b) -> IO b
allocaBytesAligned 24 8 ((Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV -> IO b)
 -> IO b)
-> (Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV -> IO b)
-> IO b
forall a b. (a -> b) -> a -> b
$ \p :: Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV
p -> Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV
-> PhysicalDeviceFragmentShaderBarycentricFeaturesNV
-> IO b
-> IO b
forall a b. ToCStruct a => Ptr a -> a -> IO b -> IO b
pokeCStruct Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV
p PhysicalDeviceFragmentShaderBarycentricFeaturesNV
x (Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV -> IO b
f Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV
p)
  pokeCStruct :: Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV
-> PhysicalDeviceFragmentShaderBarycentricFeaturesNV
-> IO b
-> IO b
pokeCStruct p :: Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV
p PhysicalDeviceFragmentShaderBarycentricFeaturesNV{..} f :: IO b
f = do
    Ptr StructureType -> StructureType -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke ((Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV
p Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV
-> Int -> Ptr StructureType
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` 0 :: Ptr StructureType)) (StructureType
STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_NV)
    Ptr (Ptr ()) -> Ptr () -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke ((Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV
p Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV
-> Int -> Ptr (Ptr ())
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` 8 :: Ptr (Ptr ()))) (Ptr ()
forall a. Ptr a
nullPtr)
    Ptr Bool32 -> Bool32 -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke ((Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV
p Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV
-> Int -> Ptr Bool32
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` 16 :: Ptr Bool32)) (Bool -> Bool32
boolToBool32 (Bool
fragmentShaderBarycentric))
    IO b
f
  cStructSize :: Int
cStructSize = 24
  cStructAlignment :: Int
cStructAlignment = 8
  pokeZeroCStruct :: Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV
-> IO b -> IO b
pokeZeroCStruct p :: Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV
p f :: IO b
f = do
    Ptr StructureType -> StructureType -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke ((Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV
p Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV
-> Int -> Ptr StructureType
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` 0 :: Ptr StructureType)) (StructureType
STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_NV)
    Ptr (Ptr ()) -> Ptr () -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke ((Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV
p Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV
-> Int -> Ptr (Ptr ())
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` 8 :: Ptr (Ptr ()))) (Ptr ()
forall a. Ptr a
nullPtr)
    Ptr Bool32 -> Bool32 -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke ((Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV
p Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV
-> Int -> Ptr Bool32
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` 16 :: Ptr Bool32)) (Bool -> Bool32
boolToBool32 (Bool
forall a. Zero a => a
zero))
    IO b
f

instance FromCStruct PhysicalDeviceFragmentShaderBarycentricFeaturesNV where
  peekCStruct :: Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV
-> IO PhysicalDeviceFragmentShaderBarycentricFeaturesNV
peekCStruct p :: Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV
p = do
    Bool32
fragmentShaderBarycentric <- Ptr Bool32 -> IO Bool32
forall a. Storable a => Ptr a -> IO a
peek @Bool32 ((Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV
p Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV
-> Int -> Ptr Bool32
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` 16 :: Ptr Bool32))
    PhysicalDeviceFragmentShaderBarycentricFeaturesNV
-> IO PhysicalDeviceFragmentShaderBarycentricFeaturesNV
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PhysicalDeviceFragmentShaderBarycentricFeaturesNV
 -> IO PhysicalDeviceFragmentShaderBarycentricFeaturesNV)
-> PhysicalDeviceFragmentShaderBarycentricFeaturesNV
-> IO PhysicalDeviceFragmentShaderBarycentricFeaturesNV
forall a b. (a -> b) -> a -> b
$ Bool -> PhysicalDeviceFragmentShaderBarycentricFeaturesNV
PhysicalDeviceFragmentShaderBarycentricFeaturesNV
             (Bool32 -> Bool
bool32ToBool Bool32
fragmentShaderBarycentric)

instance Storable PhysicalDeviceFragmentShaderBarycentricFeaturesNV where
  sizeOf :: PhysicalDeviceFragmentShaderBarycentricFeaturesNV -> Int
sizeOf ~PhysicalDeviceFragmentShaderBarycentricFeaturesNV
_ = 24
  alignment :: PhysicalDeviceFragmentShaderBarycentricFeaturesNV -> Int
alignment ~PhysicalDeviceFragmentShaderBarycentricFeaturesNV
_ = 8
  peek :: Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV
-> IO PhysicalDeviceFragmentShaderBarycentricFeaturesNV
peek = Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV
-> IO PhysicalDeviceFragmentShaderBarycentricFeaturesNV
forall a. FromCStruct a => Ptr a -> IO a
peekCStruct
  poke :: Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV
-> PhysicalDeviceFragmentShaderBarycentricFeaturesNV -> IO ()
poke ptr :: Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV
ptr poked :: PhysicalDeviceFragmentShaderBarycentricFeaturesNV
poked = Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV
-> PhysicalDeviceFragmentShaderBarycentricFeaturesNV
-> IO ()
-> IO ()
forall a b. ToCStruct a => Ptr a -> a -> IO b -> IO b
pokeCStruct Ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV
ptr PhysicalDeviceFragmentShaderBarycentricFeaturesNV
poked (() -> IO ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ())

instance Zero PhysicalDeviceFragmentShaderBarycentricFeaturesNV where
  zero :: PhysicalDeviceFragmentShaderBarycentricFeaturesNV
zero = Bool -> PhysicalDeviceFragmentShaderBarycentricFeaturesNV
PhysicalDeviceFragmentShaderBarycentricFeaturesNV
           Bool
forall a. Zero a => a
zero


type NV_FRAGMENT_SHADER_BARYCENTRIC_SPEC_VERSION = 1

-- No documentation found for TopLevel "VK_NV_FRAGMENT_SHADER_BARYCENTRIC_SPEC_VERSION"
pattern NV_FRAGMENT_SHADER_BARYCENTRIC_SPEC_VERSION :: forall a . Integral a => a
pattern $bNV_FRAGMENT_SHADER_BARYCENTRIC_SPEC_VERSION :: a
$mNV_FRAGMENT_SHADER_BARYCENTRIC_SPEC_VERSION :: forall r a. Integral a => a -> (Void# -> r) -> (Void# -> r) -> r
NV_FRAGMENT_SHADER_BARYCENTRIC_SPEC_VERSION = 1


type NV_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME = "VK_NV_fragment_shader_barycentric"

-- No documentation found for TopLevel "VK_NV_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME"
pattern NV_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME :: forall a . (Eq a, IsString a) => a
pattern $bNV_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME :: a
$mNV_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME :: forall r a.
(Eq a, IsString a) =>
a -> (Void# -> r) -> (Void# -> r) -> r
NV_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME = "VK_NV_fragment_shader_barycentric"