diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,14 @@
 # Changelog for keid-core
 
+## 0.1.11.0
+
+- Fixes and updates to match geomancy-0.3 rewrite.
+  * Reverse-depth perspective camera.
+  * Conter-clockwise winding.
+  * PVM matrix composition order.
+- Changed the compatibility extensions for device and instance to be required, but put them under a `darwin_HOST_OS` define.
+  * Even being optional they break launching under RenderDoc.
+
 ## 0.1.10.0
 
 - Added `ghWindowSize` to replace `ghScreenVar` - a unified var to track window and framebuffer sizes, and their relative scale.
diff --git a/keid-core.cabal b/keid-core.cabal
--- a/keid-core.cabal
+++ b/keid-core.cabal
@@ -1,17 +1,17 @@
 cabal-version: 1.12
 
--- This file has been generated from package.yaml by hpack version 0.38.0.
+-- This file has been generated from package.yaml by hpack version 0.38.1.
 --
 -- see: https://github.com/sol/hpack
 
 name:           keid-core
-version:        0.1.10.0
+version:        0.1.11.0
 synopsis:       Core parts of Keid engine.
 category:       Game Engine
 homepage:       https://keid.haskell-game.dev
 author:         IC Rainbow
 maintainer:     keid@aenor.ru
-copyright:      2024 IC Rainbow
+copyright:      2025 IC Rainbow
 license:        BSD3
 license-file:   LICENSE
 build-type:     Simple
@@ -138,7 +138,7 @@
     , derive-storable-plugin
     , file-embed
     , foldl
-    , geomancy
+    , geomancy >=0.3.0.0
     , geomancy-layout
     , ktx-codec >=0.0.2.0
     , neat-interpolation
diff --git a/src/Engine/Camera.hs b/src/Engine/Camera.hs
--- a/src/Engine/Camera.hs
+++ b/src/Engine/Camera.hs
@@ -87,7 +87,7 @@
     }
 
 pattern PROJECTION_NEAR :: (Eq a, Num a, Fractional a) => a
-pattern PROJECTION_NEAR = 0x0.02 -- i.e. 1/2048
+pattern PROJECTION_NEAR = 0x0.002 -- i.e. 1/2048
 
 pattern PROJECTION_FAR :: (Eq a, Num a) => a
 pattern PROJECTION_FAR = 16384
@@ -127,13 +127,12 @@
 spawnPerspective = spawnProjection mkTransformPerspective (τ / 4)
 
 mkTransformPerspective :: Vk.Extent2D -> ProjectionInput 'Perspective -> Transform
-mkTransformPerspective Vk.Extent2D{width, height} ProjectionInput{..} =
-  Projection.perspective
-    projectionParams
+mkTransformPerspective Vk.Extent2D{width, height} ProjectionInput{projectionParams=vertFoV, ..} =
+  Projection.reverseDepthRH
+    vertFoV
     projectionNear
-    projectionFar
-    width
-    height
+    (fromIntegral width)
+    (fromIntegral height)
 
 spawnOrthoPixelsCentered
   :: ( MonadReader (App Engine.GlobalHandles st) m
@@ -149,7 +148,7 @@
 
 mkTransformOrthoPixelsCentered :: Vk.Extent2D -> ProjectionInput 'Orthographic -> Transform
 mkTransformOrthoPixelsCentered Vk.Extent2D{width, height} ProjectionInput{..} =
-  Projection.orthoOffCenter projectionNear projectionFar width height
+  Projection.reverseDepthOrthoRH projectionNear projectionFar (fromIntegral width) (fromIntegral height)
 
 trackOrthoPixelsCentered
   :: ( MonadReader (App Engine.GlobalHandles st) m
@@ -196,7 +195,7 @@
 initialOrbitalInput :: ViewOrbitalInput
 initialOrbitalInput = ViewOrbitalInput
   { orbitAzimuth  = 0 -- τ/8
-  , orbitAscent   = τ/7
+  , orbitAscent   = 0 -- τ/7
   , orbitDistance = 8.0
   , orbitScale    = 1
   , orbitTarget   = 0
@@ -207,14 +206,14 @@
 mkViewOrbital :: Vec3 -> ViewOrbitalInput -> View
 mkViewOrbital cameraTarget ViewOrbitalInput{..} = View{..}
   where
-    viewTransform = View.lookAt viewPosition cameraTarget orbitUp
+    viewTransform = View.lookAtRH viewPosition cameraTarget orbitUp
     viewTransformInv = Transform.inverse viewTransform
 
     viewPosition =
-      orbitTarget +
+      orbitTarget -
       Quaternion.rotate
-        ( Quaternion.axisAngle orbitUp orbitAzimuth *
-          Quaternion.axisAngle orbitRight orbitAscent
+        ( Quaternion.axisAngle orbitUp (-orbitAzimuth) *
+          Quaternion.axisAngle orbitRight (-orbitAscent)
         )
         (vec3 0 0 $ orbitDistance * orbitScale)
 
diff --git a/src/Engine/Camera/Controls.hs b/src/Engine/Camera/Controls.hs
--- a/src/Engine/Camera/Controls.hs
+++ b/src/Engine/Camera/Controls.hs
@@ -94,7 +94,7 @@
         pan =
           Quaternion.rotate
             (Quaternion.axisAngle up azimuth)
-            (vec3 0 0 (delta * acceleration))
+            (vec3 0 (negate $ delta * acceleration) 0)
 
         up = Camera.orbitUp voi
         azimuth = Camera.orbitAzimuth voi
diff --git a/src/Engine/Setup.hs b/src/Engine/Setup.hs
--- a/src/Engine/Setup.hs
+++ b/src/Engine/Setup.hs
@@ -4,36 +4,33 @@
 
 import RIO
 
+import Foreign.Ptr (castFunPtr)
 import GHC.Clock (getMonotonicTimeNSec)
 import UnliftIO.Resource (MonadResource)
 import UnliftIO.Resource qualified as Resource
 import Vulkan.Core10 qualified as Vk
 import Vulkan.Core12 (pattern API_VERSION_1_2)
+import Vulkan.Dynamic qualified as VkDynamic
 import Vulkan.Extensions.VK_EXT_debug_utils qualified as Ext
 import Vulkan.Extensions.VK_KHR_get_physical_device_properties2 qualified as Khr
 import Vulkan.Extensions.VK_KHR_portability_enumeration qualified as Khr
 import Vulkan.Extensions.VK_KHR_surface qualified as Khr
 import Vulkan.Requirement (InstanceRequirement(..))
 import Vulkan.Utils.Initialization (createInstanceFromRequirements)
-import Vulkan.Utils.Requirements (checkInstanceRequirements, requirementReport)
 import Vulkan.Utils.QueueAssignment (QueueFamilyIndex(..))
+import Vulkan.Utils.Requirements (checkInstanceRequirements, requirementReport)
 import Vulkan.Zero (zero)
 import VulkanMemoryAllocator qualified as VMA
 
-#if MIN_VERSION_vulkan(3,15,0)
-import Foreign.Ptr (castFunPtr)
-import Vulkan.Dynamic qualified as VkDynamic
-#endif
-
 import Engine.Setup.Device (allocatePhysical, allocateLogical)
 import Engine.Setup.Window qualified as Window
+import Engine.StageSwitch (newStageSwitchVar)
 import Engine.Types (GlobalHandles(..))
 import Engine.Types.Options (Options(..))
 import Engine.Vulkan.Swapchain (SwapchainResources)
 import Engine.Vulkan.Types (PhysicalDeviceInfo(..))
 import Engine.Vulkan.Types qualified as Vulkan
 import Engine.Worker qualified as Worker
-import Engine.StageSwitch (newStageSwitchVar)
 
 setup
   :: ( HasLogFunc env
@@ -52,7 +49,11 @@
     "Keid Engine"
 
   let
-    iReqs = portabilityEnum : deviceProps : debugUtils : windowReqs
+    iReqs =
+#ifdef darwin_HOST_OS
+      portabilityEnum :
+#endif
+      deviceProps : debugUtils : windowReqs
     oReqs = []
     appInfo = Vk.ApplicationInfo
       { apiVersion = API_VERSION_1_2
@@ -63,7 +64,12 @@
       }
     instanceCI = zero
       { Vk.applicationInfo = Just appInfo
-      , Vk.flags = Vk.INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR
+      , Vk.flags =
+#ifdef darwin_HOST_OS
+          Vk.INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR
+#else
+          zero
+#endif
       }
   (instanceCI', reqResult, optResult) <- checkInstanceRequirements iReqs oReqs instanceCI
   let report = fmap fromString $ requirementReport reqResult optResult
@@ -151,7 +157,11 @@
   logDebug $ displayShow opts
 
   let
-    iReqs = portabilityEnum : deviceProps : debugUtils : headlessReqs
+    iReqs =
+#ifdef darwin_HOST_OS
+      portabilityEnum :
+#endif
+      deviceProps : debugUtils : headlessReqs
     oReqs = []
     appInfo = Vk.ApplicationInfo
       { apiVersion = API_VERSION_1_2
@@ -162,7 +172,12 @@
       }
     instanceCI = zero
       { Vk.applicationInfo = Just appInfo
-      , Vk.flags = Vk.INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR
+      , Vk.flags =
+#ifdef darwin_HOST_OS
+          Vk.INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR
+#else
+          zero
+#endif
       }
 
   (instanceCI', reqResult, optResult) <- checkInstanceRequirements iReqs oReqs instanceCI
diff --git a/src/Engine/Setup/Device.hs b/src/Engine/Setup/Device.hs
--- a/src/Engine/Setup/Device.hs
+++ b/src/Engine/Setup/Device.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE OverloadedRecordDot #-}
 
 -- | Physical device tools
@@ -21,6 +22,7 @@
 import Vulkan.Extensions.VK_KHR_surface qualified as Khr
 import Vulkan.Extensions.VK_KHR_swapchain (pattern KHR_SWAPCHAIN_EXTENSION_NAME)
 import Vulkan.Extensions.VK_KHR_timeline_semaphore (pattern KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME)
+import Vulkan.Requirement (DeviceRequirement)
 import Vulkan.Utils.Initialization (createDeviceFromRequirements, physicalDeviceName, pickPhysicalDevice)
 import Vulkan.Utils.QueueAssignment (QueueSpec(..))
 import Vulkan.Utils.QueueAssignment qualified as Utils
@@ -197,36 +199,7 @@
 allocateLogical pdi pd = do
   logDebug "Creating logical device"
 
-  ld <- createDeviceFromRequirements
-    [Utils.reqs|
-      1.2
-
-      VK_KHR_maintenance3
-      VK_KHR_swapchain
-
-      -- PhysicalDeviceFeatures.robustBufferAccess
-      PhysicalDeviceFeatures.textureCompressionBC
-
-      VK_KHR_multiview
-      PhysicalDeviceMultiviewFeatures.multiview
-
-      VK_EXT_descriptor_indexing
-      PhysicalDeviceDescriptorIndexingFeatures.descriptorBindingPartiallyBound
-      PhysicalDeviceDescriptorIndexingFeatures.descriptorBindingVariableDescriptorCount
-      PhysicalDeviceDescriptorIndexingFeatures.runtimeDescriptorArray
-      PhysicalDeviceDescriptorIndexingFeatures.shaderSampledImageArrayNonUniformIndexing
-
-      VK_KHR_timeline_semaphore
-      PhysicalDeviceTimelineSemaphoreFeatures.timelineSemaphore
-    |]
-    [Utils.reqs|
-      VK_KHR_portability_subset
-
-      PhysicalDeviceFeatures.samplerAnisotropy
-      PhysicalDeviceFeatures.sampleRateShading
-    |]
-    pd
-    deviceCI
+  ld <- createDeviceFromRequirements reqs opts pd deviceCI
 
   toIO (logDebug "Destroying logical device") >>=
     Resource.register
@@ -237,6 +210,40 @@
     deviceCI = zero
       { Vk.queueCreateInfos = fmap SomeStruct (pdiQueueCreateInfos pdi)
       }
+
+reqs :: [DeviceRequirement]
+reqs =
+#ifdef darwin_HOST_OS
+  [Utils.req| VK_KHR_portability_subset |] :
+#endif
+  [Utils.reqs|
+    1.2
+
+    VK_KHR_maintenance3
+    VK_KHR_swapchain
+
+    -- PhysicalDeviceFeatures.robustBufferAccess
+    PhysicalDeviceFeatures.textureCompressionBC
+
+    VK_KHR_multiview
+    PhysicalDeviceMultiviewFeatures.multiview
+
+    VK_EXT_descriptor_indexing
+    PhysicalDeviceDescriptorIndexingFeatures.descriptorBindingPartiallyBound
+    PhysicalDeviceDescriptorIndexingFeatures.descriptorBindingVariableDescriptorCount
+    PhysicalDeviceDescriptorIndexingFeatures.runtimeDescriptorArray
+    PhysicalDeviceDescriptorIndexingFeatures.shaderSampledImageArrayNonUniformIndexing
+
+    VK_KHR_timeline_semaphore
+    PhysicalDeviceTimelineSemaphoreFeatures.timelineSemaphore
+  |]
+
+opts :: [DeviceRequirement]
+opts =
+  [Utils.reqs|
+    PhysicalDeviceFeatures.samplerAnisotropy
+    PhysicalDeviceFeatures.sampleRateShading
+  |]
 
 noSuchThing :: MonadThrow m => String -> m a
 noSuchThing message =
diff --git a/src/Engine/Vulkan/Pipeline/Graphics.hs b/src/Engine/Vulkan/Pipeline/Graphics.hs
--- a/src/Engine/Vulkan/Pipeline/Graphics.hs
+++ b/src/Engine/Vulkan/Pipeline/Graphics.hs
@@ -147,7 +147,7 @@
   , cBlend              = False
   , cDepthWrite         = True
   , cDepthTest          = True
-  , cDepthCompare       = Vk.COMPARE_OP_LESS
+  , cDepthCompare       = Vk.COMPARE_OP_GREATER
   , cTopology           = Vk.PRIMITIVE_TOPOLOGY_TRIANGLE_LIST
   , cCull               = Vk.CULL_MODE_BACK_BIT
   , cDepthBias          = Nothing
@@ -307,7 +307,7 @@
           , Vk.lineWidth               = 1
           , Vk.polygonMode             = Vk.POLYGON_MODE_FILL
           , Vk.cullMode                = cCull
-          , Vk.frontFace               = Vk.FRONT_FACE_CLOCKWISE
+          , Vk.frontFace               = Vk.FRONT_FACE_COUNTER_CLOCKWISE
           , Vk.depthBiasEnable         = False
           }
 
diff --git a/src/Render/Pass/Offscreen.hs b/src/Render/Pass/Offscreen.hs
--- a/src/Render/Pass/Offscreen.hs
+++ b/src/Render/Pass/Offscreen.hs
@@ -142,7 +142,7 @@
 
     clear = Vector.fromList
       [ Vk.Color $ Vk.Float32 0 0 0 1
-      , Vk.DepthStencil (Vk.ClearDepthStencilValue 1.0 0)
+      , Vk.DepthStencil (Vk.ClearDepthStencilValue 0.0 0)
       ]
 
 -- ** Render pass
