sksl: Negate dFdy when the Y axis is flipped
Bug: skia:
Change-Id: Icbdaa6b1ebbe00168f57ebb888c2345d4f7a5e7d
Reviewed-on: https://skia-review.googlesource.com/c/195160
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
diff --git a/src/sksl/SkSLGLSLCodeGenerator.cpp b/src/sksl/SkSLGLSLCodeGenerator.cpp
index 9f8a185..285a94c 100644
--- a/src/sksl/SkSLGLSLCodeGenerator.cpp
+++ b/src/sksl/SkSLGLSLCodeGenerator.cpp
@@ -460,9 +460,9 @@
(*fFunctionClasses)["abs"] = FunctionClass::kAbs;
(*fFunctionClasses)["atan"] = FunctionClass::kAtan;
(*fFunctionClasses)["determinant"] = FunctionClass::kDeterminant;
- (*fFunctionClasses)["dFdx"] = FunctionClass::kDerivative;
- (*fFunctionClasses)["dFdy"] = FunctionClass::kDerivative;
- (*fFunctionClasses)["fwidth"] = FunctionClass::kDerivative;
+ (*fFunctionClasses)["dFdx"] = FunctionClass::kDFdx;
+ (*fFunctionClasses)["dFdy"] = FunctionClass::kDFdy;
+ (*fFunctionClasses)["fwidth"] = FunctionClass::kFwidth;
(*fFunctionClasses)["fma"] = FunctionClass::kFMA;
(*fFunctionClasses)["fract"] = FunctionClass::kFract;
(*fFunctionClasses)["inverse"] = FunctionClass::kInverse;
@@ -517,7 +517,15 @@
}
}
break;
- case FunctionClass::kDerivative:
+ case FunctionClass::kDFdy:
+ if (fProgram.fSettings.fFlipY) {
+ // Flipping Y also negates the Y derivatives.
+ this->write("-dFdy");
+ nameWritten = true;
+ }
+ // fallthru
+ case FunctionClass::kDFdx:
+ case FunctionClass::kFwidth:
if (!fFoundDerivatives &&
fProgram.fSettings.fCaps->shaderDerivativeExtensionString()) {
SkASSERT(fProgram.fSettings.fCaps->shaderDerivativeSupport());
diff --git a/src/sksl/SkSLGLSLCodeGenerator.h b/src/sksl/SkSLGLSLCodeGenerator.h
index 99e7d47..2a743ea 100644
--- a/src/sksl/SkSLGLSLCodeGenerator.h
+++ b/src/sksl/SkSLGLSLCodeGenerator.h
@@ -227,7 +227,9 @@
kAbs,
kAtan,
kDeterminant,
- kDerivative,
+ kDFdx,
+ kDFdy,
+ kFwidth,
kFMA,
kFract,
kInverse,
diff --git a/src/sksl/SkSLMetalCodeGenerator.cpp b/src/sksl/SkSLMetalCodeGenerator.cpp
index da206b4..c457d35 100644
--- a/src/sksl/SkSLMetalCodeGenerator.cpp
+++ b/src/sksl/SkSLMetalCodeGenerator.cpp
@@ -218,7 +218,8 @@
} else if (c.fFunction.fBuiltin && "dFdx" == c.fFunction.fName) {
this->write("dfdx");
} else if (c.fFunction.fBuiltin && "dFdy" == c.fFunction.fName) {
- this->write("dfdy");
+ // Flipping Y also negates the Y derivatives.
+ this->write((fProgram.fSettings.fFlipY) ? "-dfdy" : "dfdy");
} else {
this->writeName(c.fFunction.fName);
}
diff --git a/src/sksl/SkSLSPIRVCodeGenerator.cpp b/src/sksl/SkSLSPIRVCodeGenerator.cpp
index 77d8805..1804ecb 100644
--- a/src/sksl/SkSLSPIRVCodeGenerator.cpp
+++ b/src/sksl/SkSLSPIRVCodeGenerator.cpp
@@ -98,8 +98,7 @@
fIntrinsicMap[String("findMSB")] = BY_TYPE_GLSL(FindSMsb, FindSMsb, FindUMsb);
fIntrinsicMap[String("dFdx")] = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpDPdx,
SpvOpUndef, SpvOpUndef, SpvOpUndef);
- fIntrinsicMap[String("dFdy")] = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpDPdy,
- SpvOpUndef, SpvOpUndef, SpvOpUndef);
+ fIntrinsicMap[String("dFdy")] = SPECIAL(DFdy);
fIntrinsicMap[String("fwidth")] = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpFwidth,
SpvOpUndef, SpvOpUndef, SpvOpUndef);
fIntrinsicMap[String("texture")] = SPECIAL(Texture);
@@ -917,6 +916,20 @@
this->writeWord(args[1], out);
break;
}
+ case kDFdy_SpecialIntrinsic: {
+ SpvId fn = this->writeExpression(*c.fArguments[0], out);
+ this->writeOpCode(SpvOpDPdy, 4, out);
+ this->writeWord(this->getType(c.fType), out);
+ this->writeWord(result, out);
+ this->writeWord(fn, out);
+ if (fProgram.fSettings.fFlipY) {
+ // Flipping Y also negates the Y derivatives.
+ SpvId flipped = this->nextId();
+ this->writeInstruction(SpvOpFNegate, this->getType(c.fType), flipped, result, out);
+ return flipped;
+ }
+ break;
+ }
case kClamp_SpecialIntrinsic: {
std::vector<SpvId> args = this->vectorize(c.fArguments, out);
SkASSERT(args.size() == 3);
diff --git a/src/sksl/SkSLSPIRVCodeGenerator.h b/src/sksl/SkSLSPIRVCodeGenerator.h
index ef96e57..02adfa5 100644
--- a/src/sksl/SkSLSPIRVCodeGenerator.h
+++ b/src/sksl/SkSLSPIRVCodeGenerator.h
@@ -95,6 +95,7 @@
kMin_SpecialIntrinsic,
kMix_SpecialIntrinsic,
kMod_SpecialIntrinsic,
+ kDFdy_SpecialIntrinsic,
kSaturate_SpecialIntrinsic,
kSubpassLoad_SpecialIntrinsic,
kTexture_SpecialIntrinsic,