Reland "SkSL: Test/implement "geometric" intrinsics"

This is a reland of 0d5d956f7b

Original change's description:
> SkSL: Test/implement "geometric" intrinsics
>
> Bug: skia:10913
> Change-Id: Ie82354b05db141c8ab90b1a615ddfada4f71a98b
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/335049
> Commit-Queue: Brian Osman <brianosman@google.com>
> Reviewed-by: John Stiles <johnstiles@google.com>

Bug: skia:10913
Change-Id: I103dd2efbbab0efeac2be786d7e8f913d5c4b22a
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/338158
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
This commit is contained in:
Brian Osman 2020-11-13 16:31:37 -05:00 committed by Skia Commit-Bot
parent 748db70156
commit 9ba7a24bdd
5 changed files with 977 additions and 364 deletions

View File

@ -29,7 +29,8 @@ static constexpr int kLabelHeight = 15;
produce a single float. It can reference:
'x' : float in [xMin, xMax]
'p' : float2 in [xMin, xMax] (helpful for intrinsics with a mix of scalar/vector params)
'p' : float2 in [xMin, xMax] Lerps from (xMax, xMin) to (xMin, xMax)
(helpful for intrinsics with a mix of scalar/vector params)
'v1' : float2(1)
'v2' : float2(2)
*/
@ -40,7 +41,7 @@ static SkString make_unary_sksl_1d(const char* fn) {
"half4 main(float2 p) {"
" float2 v1 = float2(1);"
" float2 v2 = float2(2);"
" p = p * xScale + xBias;"
" p = float2(p.x, 1 - p.x) * xScale + xBias;"
" float x = p.x;"
" float y = %s * yScale + yBias;"
" return y.xxx1;"
@ -233,3 +234,38 @@ DEF_SIMPLE_GM_BG(runtime_intrinsics_common,
plot(canvas, "smoothstep(1, 2, p).x", 0.5f, 2.5f, -0.5f, 1.5f, "smooth(mixed)" ); col(canvas);
plot(canvas, "smoothstep(v1, v2, p).x", 0.5f, 2.5f, -0.5f, 1.5f, "smooth(vector)"); row(canvas);
}
// The OpenGL ES Shading Language, Version 1.00, Section 8.4
DEF_SIMPLE_GM_BG(runtime_intrinsics_geometric,
canvas,
columns_to_width(4),
rows_to_height(5),
SK_ColorWHITE) {
canvas->translate(kPadding, kPadding);
canvas->save();
plot(canvas, "length(x)", -1.0f, 1.0f, -0.5f, 1.5f); col(canvas);
plot(canvas, "length(p)", 0.0f, 1.0f, 0.5f, 1.5f); col(canvas);
plot(canvas, "distance(x, 0)", -1.0f, 1.0f, -0.5f, 1.5f); col(canvas);
plot(canvas, "distance(p, v1)", 0.0f, 1.0f, 0.5f, 1.5f); row(canvas);
plot(canvas, "dot(x, 2)", -1.0f, 1.0f, -2.5f, 2.5f); col(canvas);
plot(canvas, "dot(p, p.y1)", -1.0f, 1.0f, -2.5f, 0.5f); row(canvas);
plot(canvas, "cross(p.xy1, p.y1x).x", 0.0f, 1.0f, -1.0f, 1.0f); col(canvas);
plot(canvas, "cross(p.xy1, p.y1x).y", 0.0f, 1.0f, -1.0f, 1.0f); col(canvas);
plot(canvas, "cross(p.xy1, p.y1x).z", 0.0f, 1.0f, -1.0f, 1.0f); row(canvas);
plot(canvas, "normalize(x)", -2.0f, 2.0f, -1.5f, 1.5f); col(canvas);
plot(canvas, "normalize(p).x", 0.0f, 2.0f, 0.0f, 1.0f); col(canvas);
plot(canvas, "normalize(p).y", 0.0f, 2.0f, 0.0f, 1.0f); col(canvas);
plot(canvas, "faceforward(v1, p.x0, v1.x0).x", -1.0f, 1.0f, -1.5f, 1.5f, "faceforward"); row(canvas);
plot(canvas, "reflect(p.x1, v1.0x).x", -1.0f, 1.0f, -1.0f, 1.0f, "reflect(horiz)"); col(canvas);
plot(canvas, "reflect(p.x1, normalize(v1)).y", -1.0f, 1.0f, -1.0f, 1.0f, "reflect(diag)" ); col(canvas);
plot(canvas, "refract(v1.x0, v1.0x, x).x", 0.0f, 1.0f, -1.0f, 1.0f, "refract().x"); col(canvas);
plot(canvas, "refract(v1.x0, v1.0x, x).y", 0.0f, 1.0f, -1.0f, 1.0f, "refract().y"); row(canvas);
}

View File

@ -55,6 +55,7 @@ ByteCodeGenerator::ByteCodeGenerator(const Context* context, const Program* prog
{ "ceil", ByteCodeInstruction::kCeil },
{ "clamp", SpecialIntrinsic::kClamp },
{ "cos", ByteCodeInstruction::kCos },
{ "distance", SpecialIntrinsic::kDistance },
{ "dot", SpecialIntrinsic::kDot },
{ "exp", ByteCodeInstruction::kExp },
{ "exp2", ByteCodeInstruction::kExp2 },
@ -1248,6 +1249,19 @@ void ByteCodeGenerator::writeIntrinsicCall(const FunctionCall& c) {
}
if (intrin.is_special) {
auto doDotProduct = [count, this] {
this->write(ByteCodeInstruction::kMultiplyF, count);
for (int i = count - 1; i-- > 0;) {
this->write(ByteCodeInstruction::kAddF, 1);
}
};
auto doLength = [count, this, &doDotProduct] {
this->write(ByteCodeInstruction::kDup, count);
doDotProduct();
this->write(ByteCodeInstruction::kSqrt, 1);
};
switch (intrin.special) {
case SpecialIntrinsic::kAll: {
for (int i = count-1; i --> 0;) {
@ -1268,23 +1282,20 @@ void ByteCodeGenerator::writeIntrinsicCall(const FunctionCall& c) {
count);
} break;
case SpecialIntrinsic::kDistance: {
SkASSERT(nargs == 2 && count == SlotCount(args[1]->type()));
this->write(ByteCodeInstruction::kSubtractF, count);
doLength();
} break;
case SpecialIntrinsic::kDot: {
SkASSERT(nargs == 2);
SkASSERT(count == SlotCount(args[1]->type()));
this->write(ByteCodeInstruction::kMultiplyF, count);
for (int i = count-1; i --> 0;) {
this->write(ByteCodeInstruction::kAddF, 1);
}
SkASSERT(nargs == 2 && count == SlotCount(args[1]->type()));
doDotProduct();
} break;
case SpecialIntrinsic::kLength: {
SkASSERT(nargs == 1);
this->write(ByteCodeInstruction::kDup, count);
this->write(ByteCodeInstruction::kMultiplyF, count);
for (int i = count-1; i --> 0;) {
this->write(ByteCodeInstruction::kAddF, 1);
}
this->write(ByteCodeInstruction::kSqrt, 1);
doLength();
} break;
case SpecialIntrinsic::kMax:
@ -1334,12 +1345,7 @@ void ByteCodeGenerator::writeIntrinsicCall(const FunctionCall& c) {
case SpecialIntrinsic::kNormalize: {
SkASSERT(nargs == 1);
this->write(ByteCodeInstruction::kDup, count);
this->write(ByteCodeInstruction::kDup, count);
this->write(ByteCodeInstruction::kMultiplyF, count);
for (int i = count-1; i --> 0;) {
this->write(ByteCodeInstruction::kAddF, 1);
}
this->write(ByteCodeInstruction::kSqrt, 1);
doLength();
dupSmallerType(1);
this->write(ByteCodeInstruction::kDivideF, count);
} break;

View File

@ -140,6 +140,7 @@ private:
kAny,
kATan,
kClamp,
kDistance,
kDot,
kLength,
kMax,

File diff suppressed because it is too large Load Diff

View File

@ -93,15 +93,12 @@ $genHType smoothstep(half edge0, half edge1, $genHType x);
// 8.4 : Geometric Functions
float length($genType x);
half length($genHType x);
float distance(float2 a, float2 b) { return length(a - b); }
float distance(float3 a, float3 b) { return length(a - b); }
float distance(float4 a, float4 b) { return length(a - b); }
float distance($genType p0, $genType p1);
half distance($genHType p0, $genHType p1);
float dot($genType x, $genType y);
half dot($genHType x, $genHType y);
float3 cross(float3 a, float3 b) {
inline float3 cross(float3 a, float3 b) {
return float3(a.y * b.z - a.z * b.y,
a.z * b.x - a.x * b.z,
a.x * b.y - a.y * b.x);
@ -109,9 +106,37 @@ float3 cross(float3 a, float3 b) {
$genType normalize($genType x);
$genHType normalize($genHType x);
// TODO: faceforward(N, I, Nref)
// TODO: reflect(I, N)
// TODO: refract(I, N, eta)
inline float faceforward(float N, float I, float Nref) { return dot(Nref, I) < 0 ? N : -N; }
inline float2 faceforward(float2 N, float2 I, float2 Nref) { return dot(Nref, I) < 0 ? N : -N; }
inline float3 faceforward(float3 N, float3 I, float3 Nref) { return dot(Nref, I) < 0 ? N : -N; }
inline float4 faceforward(float4 N, float4 I, float4 Nref) { return dot(Nref, I) < 0 ? N : -N; }
inline float reflect(float I, float N) { return I - 2 * dot(N, I) * N; }
inline float2 reflect(float2 I, float2 N) { return I - 2 * dot(N, I) * N; }
inline float3 reflect(float3 I, float3 N) { return I - 2 * dot(N, I) * N; }
inline float4 reflect(float4 I, float4 N) { return I - 2 * dot(N, I) * N; }
inline float refract(float I, float N, float eta) {
float k = 1 - eta * eta * (1 - dot(N, I) * dot(N, I));
return k < 0 ? float(0)
: eta * I - (eta * dot(N, I) + sqrt(k)) * N;
}
inline float2 refract(float2 I, float2 N, float eta) {
float k = 1 - eta * eta * (1 - dot(N, I) * dot(N, I));
return k < 0 ? float2(0)
: eta * I - (eta * dot(N, I) + sqrt(k)) * N;
}
inline float3 refract(float3 I, float3 N, float eta) {
float k = 1 - eta * eta * (1 - dot(N, I) * dot(N, I));
return k < 0 ? float3(0)
: eta * I - (eta * dot(N, I) + sqrt(k)) * N;
}
inline float4 refract(float4 I, float4 N, float eta) {
float k = 1 - eta * eta * (1 - dot(N, I) * dot(N, I));
return k < 0 ? float4(0)
: eta * I - (eta * dot(N, I) + sqrt(k)) * N;
}
// 8.5 : Matrix Functions
// TODO: matrixCompMult(x, y)