[graphite] Make stencil-and-cover stencil settings accessible
This is in preparation for additional tessellation-based RenderSteps.
Cq-Include-Trybots: luci.skia.skia.primary:Test-Mac12-Clang-MacBookPro16.2-GPU-IntelIrisPlus-x86_64-Debug-All-Graphite,Test-Mac11-Clang-MacMini9.1-GPU-AppleM1-arm64-Release-All-Graphite,Test-Mac11-Clang-MacMini9.1-GPU-AppleM1-arm64-Debug-All-ASAN_Graphite,Test-Mac10.15.7-Clang-MacBookPro11.5-GPU-RadeonHD8870M-x86_64-Debug-All-Graphite,Perf-Mac11-Clang-MacMini9.1-GPU-AppleM1-arm64-Release-All-Graphite,Perf-Mac10.15.7-Clang-MacBookPro11.5-GPU-RadeonHD8870M-x86_64-Release-All-Graphite,Build-Mac-Clang-x86_64-Release-Graphite,Build-Mac-Clang-x86_64-Debug-Graphite,Build-Mac-Clang-arm64-Release-iOS_Graphite,Build-Mac-Clang-arm64-Release-Graphite,Build-Mac-Clang-arm64-Debug-iOS_Graphite,Build-Mac-Clang-arm64-Debug-Graphite_NoGpu,Build-Mac-Clang-arm64-Debug-Graphite,Build-Mac-Clang-arm64-Debug-ASAN_Graphite
Bug: skia:12703
Change-Id: I497ea14802201be10535ee26147838b28ab6b34d
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/521957
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
diff --git a/experimental/graphite/src/render/StencilAndCoverDSS.h b/experimental/graphite/src/render/StencilAndCoverDSS.h
new file mode 100644
index 0000000..a396ca8
--- /dev/null
+++ b/experimental/graphite/src/render/StencilAndCoverDSS.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef skgpu_render_StencilAndCoverDSS_DEFINED
+#define skgpu_render_StencilAndCoverDSS_DEFINED
+
+#include "experimental/graphite/src/DrawTypes.h"
+
+namespace skgpu {
+
+/**
+ * "stencil" pass DepthAndStencilSettings reusable for RenderSteps following some form of
+ * stencil-then-cover multi-pass algorithm.
+ */
+
+// Increments stencil value on clockwise triangles. Used for "winding" fill.
+constexpr DepthStencilSettings::Face kIncrementCW = {
+ /*stencilFail=*/ StencilOp::kKeep,
+ /*depthFail=*/ StencilOp::kKeep,
+ /*dsPass=*/ StencilOp::kIncWrap,
+ /*stencilCompare=*/CompareOp::kAlways,
+ /*readMask=*/ 0xffffffff,
+ /*writeMask=*/ 0xffffffff
+};
+
+// Decrements stencil value on counterclockwise triangles. Used for "winding" fill.
+constexpr DepthStencilSettings::Face kDecrementCCW = {
+ /*stencilFail=*/ StencilOp::kKeep,
+ /*depthFail=*/ StencilOp::kKeep,
+ /*dsPass=*/ StencilOp::kDecWrap,
+ /*stencilCompare=*/CompareOp::kAlways,
+ /*readMask=*/ 0xffffffff,
+ /*writeMask=*/ 0xffffffff
+};
+
+// Toggles the bottom stencil bit. Used for "even-odd" fill.
+constexpr DepthStencilSettings::Face kToggle = {
+ /*stencilFail=*/ StencilOp::kKeep,
+ /*depthFail=*/ StencilOp::kKeep,
+ /*dsPass=*/ StencilOp::kInvert,
+ /*stencilCompare=*/CompareOp::kAlways,
+ /*readMask=*/ 0xffffffff,
+ /*writeMask=*/ 0x00000001
+};
+
+// Stencil settings to use for a standard Redbook "stencil" pass corresponding to a "winding"
+// fill rule (regular or inverse is selected by a follow-up pass).
+constexpr DepthStencilSettings kWindingStencilPass = {
+ /*frontStencil=*/kIncrementCW,
+ /*backStencil=*/ kDecrementCCW,
+ /*refValue=*/ 0,
+ /*stencilTest=*/ true,
+ /*depthCompare=*/CompareOp::kAlways, // TODO: kGreater once steps know the right depth value
+ /*depthTest=*/ true,
+ /*depthWrite=*/ false // The depth write will be handled by the covering pass
+};
+
+// Stencil settings to use for a standard Redbook "stencil" pass corresponding to an "even-odd"
+// fill rule (regular or inverse is selected by a follow-up pass).
+constexpr DepthStencilSettings kEvenOddStencilPass = {
+ /*frontStencil=*/kToggle,
+ /*backStencil=*/ kToggle,
+ /*refValue=*/ 0,
+ /*stencilTest=*/ true,
+ /*depthCompare=*/CompareOp::kAlways, // TODO: kGreater once steps know the right depth value
+ /*depthTest=*/ true,
+ /*depthWrite=*/ false // The depth write will be handled by the covering pass
+};
+
+/**
+ * "cover" pass DepthAndStencilSettings reusable for RenderSteps following some form of
+ * stencil-then-cover multi-pass algorithm.
+ */
+
+// Resets non-zero bits to 0, passes when not zero. We set depthFail to kZero because if we
+// encounter that case, the kNotEqual=0 stencil test passed, so it does need to be set back to 0
+// and the dsPass op won't be run. In practice, since the stencil steps will fail the same depth
+// test, the stencil value will likely not be non-zero, but best to be explicit.
+constexpr DepthStencilSettings::Face kPassNonZero = {
+ /*stencilFail=*/ StencilOp::kKeep,
+ /*depthFail=*/ StencilOp::kZero,
+ /*dsPass=*/ StencilOp::kZero,
+ /*stencilCompare=*/CompareOp::kNotEqual,
+ /*readMask=*/ 0xffffffff,
+ /*writeMask=*/ 0xffffffff
+};
+
+ // Resets non-zero bits to 0, passes when zero.
+constexpr DepthStencilSettings::Face kPassZero = {
+ /*stencilFail=*/ StencilOp::kZero,
+ /*depthFail=*/ StencilOp::kKeep,
+ /*dsPass=*/ StencilOp::kKeep,
+ /*stencilCompare=*/CompareOp::kEqual,
+ /*readMask=*/ 0xffffffff,
+ /*writeMask=*/ 0xffffffff
+};
+
+// Stencil settings to use for a standard Redbook "cover" pass for a regular fill, assuming that the
+// stencil buffer has been modified by either kWindingStencilPass or kEvenOddStencilPass.
+constexpr DepthStencilSettings kRegularCoverPass = {
+ /*frontStencil=*/kPassNonZero,
+ /*frontStencil=*/kPassNonZero,
+ /*refValue=*/ 0,
+ /*stencilTest=*/ true,
+ /*depthCompare=*/CompareOp::kAlways, // TODO: kGreater once steps know the right depth value
+ /*depthTest=*/ true,
+ /*depthWrite=*/ true
+};
+
+// Stencil settings to use for a standard Redbook "cover" pass for inverse fills, assuming that the
+// stencil buffer has been modified by either kWindingStencilPass or kEvenOddStencilPass.
+constexpr DepthStencilSettings kInverseCoverPass = {
+ /*frontStencil=*/kPassZero,
+ /*frontStencil=*/kPassZero,
+ /*refValue=*/ 0,
+ /*stencilTest=*/ true,
+ /*depthCompare=*/CompareOp::kAlways, // TODO: kGreater once steps know the right depth value
+ /*depthTest=*/ true,
+ /*depthWrite=*/ true
+};
+
+} // namespace skgpu
+
+#endif // skgpu_render_RedbookDepthAndStencilSettings
diff --git a/experimental/graphite/src/render/StencilAndFillPathRenderer.cpp b/experimental/graphite/src/render/StencilAndFillPathRenderer.cpp
index 26c6128..aedfd7e 100644
--- a/experimental/graphite/src/render/StencilAndFillPathRenderer.cpp
+++ b/experimental/graphite/src/render/StencilAndFillPathRenderer.cpp
@@ -11,6 +11,7 @@
#include "experimental/graphite/src/UniformManager.h"
#include "experimental/graphite/src/geom/Shape.h"
#include "experimental/graphite/src/geom/Transform_graphite.h"
+#include "experimental/graphite/src/render/StencilAndCoverDSS.h"
#include "include/core/SkPathTypes.h"
#include "include/core/SkRect.h"
#include "src/core/SkUniformData.h"
@@ -25,119 +26,13 @@
namespace {
-// TODO: These settings are actually shared by tessellating path renderers, so will be exposed later
-
-// Returns the stencil settings to use for a standard Redbook "stencil" pass.
-constexpr DepthStencilSettings fillrule_settings(bool evenOdd) {
- // Increments clockwise triangles and decrements counterclockwise. Used for "winding" fill.
- constexpr DepthStencilSettings::Face kIncCW = {
- /*stencilFail=*/ StencilOp::kKeep,
- /*depthFail=*/ StencilOp::kKeep,
- /*dsPass=*/ StencilOp::kIncWrap,
- /*stencilCompare=*/CompareOp::kAlways,
- /*readMask=*/ 0xffffffff,
- /*writeMask=*/ 0xffffffff
- };
- constexpr DepthStencilSettings::Face kDecCCW = {
- /*stencilFail=*/ StencilOp::kKeep,
- /*depthFail=*/ StencilOp::kKeep,
- /*dsPass=*/ StencilOp::kDecWrap,
- /*stencilCompare=*/CompareOp::kAlways,
- /*readMask=*/ 0xffffffff,
- /*writeMask=*/ 0xffffffff
- };
-
- // Toggles the bottom stencil bit. Used for "even-odd" fill.
- constexpr DepthStencilSettings::Face kToggle = {
- /*stencilFail=*/ StencilOp::kKeep,
- /*depthFail=*/ StencilOp::kKeep,
- /*dsPass=*/ StencilOp::kInvert,
- /*stencilCompare=*/CompareOp::kAlways,
- /*readMask=*/ 0xffffffff,
- /*writeMask=*/ 0x00000001
- };
-
- // Always use ref = 0, disable depths, but still use greater depth test.
- constexpr DepthStencilSettings kWindingFill = {
- /*frontStencil=*/kIncCW,
- /*backStencil=*/ kDecCCW,
- /*refValue=*/ 0,
- /*stencilTest=*/ true,
- /*depthCompare=*/CompareOp::kAlways, // kGreater once steps know the right depth value
- /*depthTest=*/ true,
- /*depthWrite=*/ false
- };
- constexpr DepthStencilSettings kEvenOddFill = {
- /*frontStencil=*/kToggle,
- /*backStencil=*/ kToggle,
- /*refValue=*/ 0,
- /*stencilTest=*/ true,
- /*depthCompare=*/CompareOp::kAlways, // kGreater once steps know the right depth value
- /*depthTest=*/ true,
- /*depthWrite=*/ false
- };
-
- return evenOdd ? kEvenOddFill : kWindingFill;
-}
-
-// Returns the stencil settings to use for a standard Redbook "fill" pass. Allows non-zero
-// stencil values to pass and write a color, and resets the stencil value back to zero; discards
-// immediately on stencil values of zero (or does the inverse of these operations when the path
-// requires filling everything else).
-constexpr DepthStencilSettings cover_settings(bool inverse) {
- // Resets non-zero bits to 0, passes when not zero. We set depthFail to kZero because if we
- // encounter that case, the kNotEqual=0 stencil test passed, so it does need to be set back to 0
- // and the dsPass op won't be run. In practice, since the stencil steps will fail the same depth
- // test, the stencil value will likely not be non-zero, but best to be explicit.
- constexpr DepthStencilSettings::Face kNormal = {
- /*stencilFail=*/ StencilOp::kKeep,
- /*depthFail=*/ StencilOp::kZero,
- /*dsPass=*/ StencilOp::kZero,
- /*stencilCompare=*/CompareOp::kNotEqual,
- /*readMask=*/ 0xffffffff,
- /*writeMask=*/ 0xffffffff
- };
-
- // Resets non-zero bits to 0, passes when zero
- constexpr DepthStencilSettings::Face kInverted = {
- /*stencilFail=*/ StencilOp::kZero,
- /*depthFail=*/ StencilOp::kKeep,
- /*dsPass=*/ StencilOp::kKeep,
- /*stencilCompare=*/CompareOp::kEqual,
- /*readMask=*/ 0xffffffff,
- /*writeMask=*/ 0xffffffff
- };
-
- // Always use ref = 0, enabled depth writes, and greater depth test, both
- // front and back use the same stencil settings.
- constexpr DepthStencilSettings kNormalDSS = {
- /*frontStencil=*/kNormal,
- /*frontStencil=*/kNormal,
- /*refValue=*/ 0,
- /*stencilTest=*/ true,
- /*depthCompare=*/CompareOp::kAlways, // kGreater once steps know the right depth value
- /*depthTest=*/ true,
- /*depthWrite=*/ true
- };
- constexpr DepthStencilSettings kInvertedDSS = {
- /*frontStencil=*/kInverted,
- /*backStencil=*/ kInverted,
- /*refValue=*/ 0,
- /*stencilTest=*/ true,
- /*depthCompare=*/CompareOp::kAlways, // kGreater once steps know the right depth value
- /*depthTest=*/ true,
- /*depthWrite=*/ true
- };
- return inverse ? kInvertedDSS : kNormalDSS;
-}
-
class StencilFanRenderStep final : public RenderStep {
public:
StencilFanRenderStep(bool evenOdd)
: RenderStep(Flags::kRequiresMSAA,
/*uniforms=*/{},
PrimitiveType::kTriangles,
- fillrule_settings(evenOdd),
+ evenOdd ? kEvenOddStencilPass : kWindingStencilPass,
/*vertexAttrs=*/{{"position",
VertexAttribType::kFloat3,
SkSLType::kFloat3}},
@@ -232,7 +127,7 @@
: RenderStep(Flags::kRequiresMSAA,
/*uniforms=*/{},
PrimitiveType::kTriangles,
- fillrule_settings(evenOdd),
+ evenOdd ? kEvenOddStencilPass : kWindingStencilPass,
/*vertexAttrs=*/ {{"resolveLevel_and_idx",
VertexAttribType::kFloat2, SkSLType::kFloat2}},
/*instanceAttrs=*/{{"p01", VertexAttribType::kFloat4, SkSLType::kFloat4},
@@ -400,7 +295,7 @@
: RenderStep(Flags::kPerformsShading,
/*uniforms=*/{},
PrimitiveType::kTriangles,
- cover_settings(inverseFill),
+ inverseFill ? kInverseCoverPass : kRegularCoverPass,
/*vertexAttrs=*/{{"position",
VertexAttribType::kFloat3,
SkSLType::kFloat3}},
diff --git a/gn/graphite.gni b/gn/graphite.gni
index 4966437..d7df823 100644
--- a/gn/graphite.gni
+++ b/gn/graphite.gni
@@ -108,6 +108,7 @@
"$_src/geom/Transform.cpp",
"$_src/geom/Transform_graphite.h",
"$_src/geom/VectorTypes.h",
+ "$_src/render/StencilAndCoverDSS.h",
"$_src/render/StencilAndFillPathRenderer.cpp",
]