feat(vk): Add an option to disable fixed function clockwise mode (#11666) 838cad2bf2
Dithering does better when we evaluate our blend equations in medium
precision from the fragment shader, vs letting it happen in the blend
unit (which, presumably, must be lower precision). For this reason, an
app may wish to disable "fixed function" rendering for clockwise mode.

Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com>
diff --git a/.rive_head b/.rive_head
index 73ed209..a0c43f6 100644
--- a/.rive_head
+++ b/.rive_head
@@ -1 +1 @@
-f4c16df15d8d74e7bde43ef10ccdb9c966ed4940
+838cad2bf2c34bd2820de1f3058f6c360fadc99f
diff --git a/renderer/include/rive/renderer/vulkan/render_context_vulkan_impl.hpp b/renderer/include/rive/renderer/vulkan/render_context_vulkan_impl.hpp
index e2ff857..0ed52de 100644
--- a/renderer/include/rive/renderer/vulkan/render_context_vulkan_impl.hpp
+++ b/renderer/include/rive/renderer/vulkan/render_context_vulkan_impl.hpp
@@ -25,6 +25,14 @@
     struct ContextOptions
     {
         bool forceAtomicMode = false;
+
+        // Dithering does better when we evaluate our blend equations in medium
+        // precision from the fragment shader, vs letting it happen in the blend
+        // unit (which, presumably, must be lower precision). For this reason,
+        // an app may wish to disable "fixed function" rendering for clockwise
+        // mode.
+        bool disableClockwiseFixedFunctionMode = false;
+
         ShaderCompilationMode shaderCompilationMode =
             ShaderCompilationMode::standard;
     };
diff --git a/renderer/src/vulkan/render_context_vulkan_impl.cpp b/renderer/src/vulkan/render_context_vulkan_impl.cpp
index fd131e8..ceee3e2 100644
--- a/renderer/src/vulkan/render_context_vulkan_impl.cpp
+++ b/renderer/src/vulkan/render_context_vulkan_impl.cpp
@@ -780,16 +780,18 @@
     m_platformFeatures.supportsAtomicMode =
         m_vk->features.fragmentStoresAndAtomics;
     m_platformFeatures.supportsClockwiseMode =
-        m_platformFeatures.supportsClockwiseFixedFunctionMode =
-            m_vk->features.fragmentShaderPixelInterlock &&
-            !contextOptions.forceAtomicMode &&
-            // TODO: Before we can support rasterOrdering and clockwise at the
-            // same time, we need to figure out barriers between transient PLS
-            // attachments being bound as both input attachments and storage
-            // textures. (Probably by using
-            // VK_EXT_rasterization_order_attachment_access whenever possible in
-            // clockwise mode.)
-            !m_platformFeatures.supportsRasterOrderingMode;
+        m_vk->features.fragmentShaderPixelInterlock &&
+        !contextOptions.forceAtomicMode &&
+        // TODO: Before we can support rasterOrdering and clockwise at the same
+        // time, we need to figure out barriers between transient PLS
+        // attachments being bound as both input attachments and storage
+        // textures. (Probably by using
+        // VK_EXT_rasterization_order_attachment_access whenever possible in
+        // clockwise mode.)
+        !m_platformFeatures.supportsRasterOrderingMode;
+    m_platformFeatures.supportsClockwiseFixedFunctionMode =
+        m_platformFeatures.supportsClockwiseMode &&
+        !contextOptions.disableClockwiseFixedFunctionMode;
 #endif
     m_platformFeatures.supportsClockwiseAtomicMode =
         m_platformFeatures.supportsAtomicMode;