Migrate as_sksl out of skgpu::wangs_formula.
This is only referenced by tessellation code now, so it's been moved to GrTessellationShader.cpp. (In the near future, we may remove this code entirely, since it is not very impactful for performance.) Change-Id: Id0f176220efb3eeed63e08c2c1faa48df07cd124 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/533676 Reviewed-by: Michael Ludwig <michaelludwig@google.com> Auto-Submit: John Stiles <johnstiles@google.com> Commit-Queue: John Stiles <johnstiles@google.com>
This commit is contained in:
parent
3f8fc145ba
commit
4f33f5bef8
@ -119,5 +119,8 @@ generated_cc_atom(
|
||||
name = "GrTessellationShader_src",
|
||||
srcs = ["GrTessellationShader.cpp"],
|
||||
visibility = ["//:__subpackages__"],
|
||||
deps = [":GrTessellationShader_hdr"],
|
||||
deps = [
|
||||
":GrTessellationShader_hdr",
|
||||
"//src/gpu/tessellate:WangsFormula_hdr",
|
||||
],
|
||||
)
|
||||
|
@ -77,7 +77,7 @@ std::unique_ptr<GrGeometryProcessor::ProgramImpl> HardwareWedgeShader::makeProgr
|
||||
code.appendf(R"(
|
||||
#define PRECISION %f)", skgpu::kTessellationPrecision);
|
||||
code.append(kSkSLTypeDefs);
|
||||
code.append(skgpu::wangs_formula::as_sksl());
|
||||
code.append(GrTessellationShader::WangsFormulaSkSL());
|
||||
|
||||
code.append(R"(
|
||||
layout(vertices = 1) out;
|
||||
@ -221,7 +221,7 @@ std::unique_ptr<GrGeometryProcessor::ProgramImpl> HardwareCurveShader::makeProgr
|
||||
code.appendf(R"(
|
||||
#define PRECISION %f)", skgpu::kTessellationPrecision);
|
||||
code.append(kSkSLTypeDefs);
|
||||
code.append(skgpu::wangs_formula::as_sksl());
|
||||
code.append(GrTessellationShader::WangsFormulaSkSL());
|
||||
code.append(R"(
|
||||
layout(vertices = 1) out;
|
||||
|
||||
|
@ -101,7 +101,7 @@ std::unique_ptr<GrGeometryProcessor::ProgramImpl> MiddleOutShader::makeProgramIm
|
||||
(float)skgpu::kMaxFixedResolveLevel);
|
||||
v->defineConstant("MAX_FIXED_SEGMENTS",
|
||||
(float)(skgpu::kMaxParametricSegments));
|
||||
v->insertFunction(skgpu::wangs_formula::as_sksl().c_str());
|
||||
v->insertFunction(GrTessellationShader::WangsFormulaSkSL());
|
||||
if (middleOutShader.fAttribs & PatchAttribs::kExplicitCurveType) {
|
||||
v->insertFunction(SkStringPrintf(R"(
|
||||
bool is_conic_curve() {
|
||||
|
@ -350,7 +350,7 @@ SkString GrStrokeTessellationShader::HardwareImpl::getTessControlShaderGLSL(
|
||||
code.appendf("#define NUM_RADIAL_SEGMENTS_PER_RADIAN vsStrokeArgs[0].x\n");
|
||||
}
|
||||
|
||||
code.append(skgpu::wangs_formula::as_sksl());
|
||||
code.append(GrTessellationShader::WangsFormulaSkSL());
|
||||
code.append(kCosineBetweenVectorsFn);
|
||||
code.append(kMiterExtentFn);
|
||||
code.append(R"(
|
||||
|
@ -29,7 +29,7 @@ void GrStrokeTessellationShader::InstancedImpl::onEmitCode(EmitArgs& args, GrGPA
|
||||
args.fVertBuilder->insertFunction(kCosineBetweenVectorsFn);
|
||||
args.fVertBuilder->insertFunction(kMiterExtentFn);
|
||||
args.fVertBuilder->insertFunction(kUncheckedMixFn);
|
||||
args.fVertBuilder->insertFunction(skgpu::wangs_formula::as_sksl().c_str());
|
||||
args.fVertBuilder->insertFunction(GrTessellationShader::WangsFormulaSkSL());
|
||||
|
||||
// Tessellation control uniforms and/or dynamic attributes.
|
||||
if (!shader.hasDynamicStroke()) {
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "src/gpu/ganesh/tessellate/shaders/GrTessellationShader.h"
|
||||
#include "src/gpu/tessellate/WangsFormula.h"
|
||||
|
||||
const GrPipeline* GrTessellationShader::MakePipeline(const ProgramArgs& args,
|
||||
GrAAType aaType,
|
||||
@ -21,3 +22,57 @@ const GrPipeline* GrTessellationShader::MakePipeline(const ProgramArgs& args,
|
||||
std::move(processors),
|
||||
std::move(appliedClip));
|
||||
}
|
||||
|
||||
const char* GrTessellationShader::WangsFormulaSkSL() {
|
||||
static_assert(skgpu::wangs_formula::length_term<3>(1) == 0.75);
|
||||
static_assert(skgpu::wangs_formula::length_term_pow2<3>(1) == 0.5625);
|
||||
|
||||
return R"(
|
||||
// Returns the length squared of the largest forward difference from Wang's cubic formula.
|
||||
float wangs_formula_max_fdiff_pow2(float2 p0, float2 p1, float2 p2, float2 p3,
|
||||
float2x2 matrix) {
|
||||
float2 d0 = matrix * (fma(float2(-2), p1, p2) + p0);
|
||||
float2 d1 = matrix * (fma(float2(-2), p2, p3) + p1);
|
||||
return max(dot(d0,d0), dot(d1,d1));
|
||||
}
|
||||
float wangs_formula_cubic(float _precision_, float2 p0, float2 p1, float2 p2, float2 p3,
|
||||
float2x2 matrix) {
|
||||
float m = wangs_formula_max_fdiff_pow2(p0, p1, p2, p3, matrix);
|
||||
return max(ceil(sqrt(0.75 * _precision_ * sqrt(m))), 1.0);
|
||||
}
|
||||
float wangs_formula_cubic_log2(float _precision_, float2 p0, float2 p1, float2 p2, float2 p3,
|
||||
float2x2 matrix) {
|
||||
float m = wangs_formula_max_fdiff_pow2(p0, p1, p2, p3, matrix);
|
||||
return ceil(log2(max(0.5625 * _precision_ * _precision_ * m, 1.0)) * .25);
|
||||
}
|
||||
float wangs_formula_conic_pow2(float _precision_, float2 p0, float2 p1, float2 p2, float w) {
|
||||
// Translate the bounding box center to the origin.
|
||||
float2 C = (min(min(p0, p1), p2) + max(max(p0, p1), p2)) * 0.5;
|
||||
p0 -= C;
|
||||
p1 -= C;
|
||||
p2 -= C;
|
||||
|
||||
// Compute max length.
|
||||
float m = sqrt(max(max(dot(p0,p0), dot(p1,p1)), dot(p2,p2)));
|
||||
|
||||
// Compute forward differences.
|
||||
float2 dp = fma(float2(-2.0 * w), p1, p0) + p2;
|
||||
float dw = abs(fma(-2.0, w, 2.0));
|
||||
|
||||
// Compute numerator and denominator for parametric step size of linearization. Here, the
|
||||
// epsilon referenced from the cited paper is 1/precision.
|
||||
float rp_minus_1 = max(0.0, fma(m, _precision_, -1.0));
|
||||
float numer = length(dp) * _precision_ + rp_minus_1 * dw;
|
||||
float denom = 4 * min(w, 1.0);
|
||||
|
||||
return numer/denom;
|
||||
}
|
||||
float wangs_formula_conic(float _precision_, float2 p0, float2 p1, float2 p2, float w) {
|
||||
float n2 = wangs_formula_conic_pow2(_precision_, p0, p1, p2, w);
|
||||
return max(ceil(sqrt(n2)), 1.0);
|
||||
}
|
||||
float wangs_formula_conic_log2(float _precision_, float2 p0, float2 p1, float2 p2, float w) {
|
||||
float n2 = wangs_formula_conic_pow2(_precision_, p0, p1, p2, w);
|
||||
return ceil(log2(max(n2, 1.0)) * .5);
|
||||
})";
|
||||
}
|
||||
|
@ -70,6 +70,9 @@ public:
|
||||
args.fXferBarrierFlags, args.fColorLoadOp);
|
||||
}
|
||||
|
||||
// SkSL functions that calculate Wang's formula for cubics or conics.
|
||||
static const char* WangsFormulaSkSL();
|
||||
|
||||
private:
|
||||
const GrPrimitiveType fPrimitiveType;
|
||||
const int fTessellationPatchVertexCount;
|
||||
|
@ -281,64 +281,6 @@ AI int conic_log2(float tolerance,
|
||||
return nextlog4(conic_pow2(tolerance, pts, w, vectorXform));
|
||||
}
|
||||
|
||||
// Emits an SKSL function that calculates Wang's formula for the given set of 4 points. The points
|
||||
// represent a cubic if w < 0, or if w >= 0, a conic defined by the first 3 points.
|
||||
SK_MAYBE_UNUSED inline static SkString as_sksl() {
|
||||
SkString code;
|
||||
code.appendf(R"(
|
||||
// Returns the length squared of the largest forward difference from Wang's cubic formula.
|
||||
float wangs_formula_max_fdiff_pow2(float2 p0, float2 p1, float2 p2, float2 p3,
|
||||
float2x2 matrix) {
|
||||
float2 d0 = matrix * (fma(float2(-2), p1, p2) + p0);
|
||||
float2 d1 = matrix * (fma(float2(-2), p2, p3) + p1);
|
||||
return max(dot(d0,d0), dot(d1,d1));
|
||||
}
|
||||
float wangs_formula_cubic(float _precision_, float2 p0, float2 p1, float2 p2, float2 p3,
|
||||
float2x2 matrix) {
|
||||
float m = wangs_formula_max_fdiff_pow2(p0, p1, p2, p3, matrix);
|
||||
return max(ceil(sqrt(%f * _precision_ * sqrt(m))), 1.0);
|
||||
}
|
||||
float wangs_formula_cubic_log2(float _precision_, float2 p0, float2 p1, float2 p2, float2 p3,
|
||||
float2x2 matrix) {
|
||||
float m = wangs_formula_max_fdiff_pow2(p0, p1, p2, p3, matrix);
|
||||
return ceil(log2(max(%f * _precision_ * _precision_ * m, 1.0)) * .25);
|
||||
})", length_term<3>(1), length_term_pow2<3>(1));
|
||||
|
||||
code.appendf(R"(
|
||||
float wangs_formula_conic_pow2(float _precision_, float2 p0, float2 p1, float2 p2, float w) {
|
||||
// Translate the bounding box center to the origin.
|
||||
float2 C = (min(min(p0, p1), p2) + max(max(p0, p1), p2)) * 0.5;
|
||||
p0 -= C;
|
||||
p1 -= C;
|
||||
p2 -= C;
|
||||
|
||||
// Compute max length.
|
||||
float m = sqrt(max(max(dot(p0,p0), dot(p1,p1)), dot(p2,p2)));
|
||||
|
||||
// Compute forward differences.
|
||||
float2 dp = fma(float2(-2.0 * w), p1, p0) + p2;
|
||||
float dw = abs(fma(-2.0, w, 2.0));
|
||||
|
||||
// Compute numerator and denominator for parametric step size of linearization. Here, the
|
||||
// epsilon referenced from the cited paper is 1/precision.
|
||||
float rp_minus_1 = max(0.0, fma(m, _precision_, -1.0));
|
||||
float numer = length(dp) * _precision_ + rp_minus_1 * dw;
|
||||
float denom = 4 * min(w, 1.0);
|
||||
|
||||
return numer/denom;
|
||||
}
|
||||
float wangs_formula_conic(float _precision_, float2 p0, float2 p1, float2 p2, float w) {
|
||||
float n2 = wangs_formula_conic_pow2(_precision_, p0, p1, p2, w);
|
||||
return max(ceil(sqrt(n2)), 1.0);
|
||||
}
|
||||
float wangs_formula_conic_log2(float _precision_, float2 p0, float2 p1, float2 p2, float w) {
|
||||
float n2 = wangs_formula_conic_pow2(_precision_, p0, p1, p2, w);
|
||||
return ceil(log2(max(n2, 1.0)) * .5);
|
||||
})");
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
} // namespace skgpu::wangs_formula
|
||||
|
||||
#undef AI
|
||||
|
Loading…
Reference in New Issue
Block a user