Revert "Add most important intrinsics to the interpreter"

This reverts commit 838007f1ff.

Reason for revert: Significant RAM regression detected by Chrome.

Original change's description:
> Add most important intrinsics to the interpreter
> 
> Started with component-wise comparison and mix builtins.
> 
> Implemented min, max, clamp, and saturate using those.
> Moved dot to SkSL as well. Because we now have builtins
> implemented using other (intrinsic) builtins, I had to
> split the include file in two - this lets the intrinsics
> be marked so we can call them from the second phase of
> builtins that are written in SkSL.
> 
> Given that the comparisons and kSelect are now used by
> these, I added vector versions of those instructions.
> I also switched the kSelect args to match GLSL mix(),
> mostly so the logic of mapping intrinsic arguments to
> instruction register args remains simple.
> 
> Inspired by the (never-landed):
> https://skia-review.googlesource.com/c/skia/+/230739
> 
> Change-Id: Iecb0a7e8dc633625ff2cada7fb962bf2137fa881
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/272516
> Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
> Commit-Queue: Brian Osman <brianosman@google.com>

TBR=bsalomon@google.com,brianosman@google.com,ethannicholas@google.com,reed@google.com

Change-Id: I931a0ccc254b55339c9b077543a0daaf28146b19
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/273800
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
This commit is contained in:
Brian Osman 2020-02-27 18:36:57 +00:00 committed by Skia Commit-Bot
parent 00666b5739
commit 15c98cbfef
8 changed files with 138 additions and 397 deletions

View File

@ -124,37 +124,37 @@ public:
// uint8_t argumentSize
kCallExternal,
// Register target, Register src1, Register src2
V(kCompareEQF),
kCompareEQF,
// Register target, Register src1, Register src2
V(kCompareEQI),
kCompareEQI,
// Register target, Register src1, Register src2
V(kCompareNEQF),
kCompareNEQF,
// Register target, Register src1, Register src2
V(kCompareNEQI),
kCompareNEQI,
// Register target, Register src1, Register src2
V(kCompareGTF),
kCompareGTF,
// Register target, Register src1, Register src2
V(kCompareGTS),
kCompareGTS,
// Register target, Register src1, Register src2
V(kCompareGTU),
kCompareGTU,
// Register target, Register src1, Register src2
V(kCompareGTEQF),
kCompareGTEQF,
// Register target, Register src1, Register src2
V(kCompareGTEQS),
kCompareGTEQS,
// Register target, Register src1, Register src2
V(kCompareGTEQU),
kCompareGTEQU,
// Register target, Register src1, Register src2
V(kCompareLTF),
kCompareLTF,
// Register target, Register src1, Register src2
V(kCompareLTS),
kCompareLTS,
// Register target, Register src1, Register src2
V(kCompareLTU),
kCompareLTU,
// Register target, Register src1, Register src2
V(kCompareLTEQF),
kCompareLTEQF,
// Register target, Register src1, Register src2
V(kCompareLTEQS),
kCompareLTEQS,
// Register target, Register src1, Register src2
V(kCompareLTEQU),
kCompareLTEQU,
// no parameters
kContinue,
// Register target, Register src
@ -248,8 +248,8 @@ public:
kReturnValue,
// Register target, Register src, uint8_t columns, uint8_t rows
kScalarToMatrix,
// Register target, Register ifFalse, Register ifTrue, Register test (To match GLSL mix)
V(kSelect),
// Register target, Register test, Register ifTrue, Register ifFalse
kSelect,
// Register target, Register src, uint8_t count
kShiftLeft,
// Register target, Register src, uint8_t count

View File

@ -14,37 +14,14 @@ ByteCodeGenerator::ByteCodeGenerator(const Program* program, ErrorReporter* erro
: INHERITED(program, errors, nullptr)
, fOutput(output)
, fIntrinsics {
// "Normal" intrinsics are all $genType f($genType [, $genType...])
// and all map to a single instruction (possibly with a vector version)
{ "cos", { ByteCode::Instruction::kCos, false } },
{ "mix", { ByteCode::Instruction::kSelect, true } },
{ "not", { ByteCode::Instruction::kNot, false } },
{ "sin", { ByteCode::Instruction::kSin, false } },
{ "sqrt", { ByteCode::Instruction::kSqrt, false } },
{ "tan", { ByteCode::Instruction::kTan, false } },
{ "lessThan", { ByteCode::Instruction::kCompareLTF,
ByteCode::Instruction::kCompareLTS,
ByteCode::Instruction::kCompareLTU, true } },
{ "lessThanEqual", { ByteCode::Instruction::kCompareLTEQF,
ByteCode::Instruction::kCompareLTEQS,
ByteCode::Instruction::kCompareLTEQU, true } },
{ "greaterThan", { ByteCode::Instruction::kCompareGTF,
ByteCode::Instruction::kCompareGTS,
ByteCode::Instruction::kCompareGTU, true } },
{ "greaterThanEqual", { ByteCode::Instruction::kCompareGTEQF,
ByteCode::Instruction::kCompareGTEQS,
ByteCode::Instruction::kCompareGTEQU, true } },
{ "equal", { ByteCode::Instruction::kCompareEQF,
ByteCode::Instruction::kCompareEQI,
ByteCode::Instruction::kCompareEQI, true } },
{ "notEqual", { ByteCode::Instruction::kCompareNEQF,
ByteCode::Instruction::kCompareNEQI,
ByteCode::Instruction::kCompareNEQI, true } },
// "Normal" intrinsics are all $genType f($genType), mapped to a single instruction
{ "cos", ByteCode::Instruction::kCos },
{ "sin", ByteCode::Instruction::kSin },
{ "sqrt", ByteCode::Instruction::kSqrt },
{ "tan", ByteCode::Instruction::kTan },
// Special intrinsics have other signatures, or non-standard code-gen
{ "all", SpecialIntrinsic::kAll },
{ "any", SpecialIntrinsic::kAny },
{ "dot", SpecialIntrinsic::kDot },
{ "inverse", SpecialIntrinsic::kInverse },
{ "print", SpecialIntrinsic::kPrint },
} {}
@ -937,22 +914,33 @@ void ByteCodeGenerator::writeIntrinsicCall(const FunctionCall& c, Intrinsic intr
ByteCode::Register result) {
if (intrinsic.fIsSpecial) {
switch (intrinsic.fValue.fSpecial) {
case SpecialIntrinsic::kAll:
case SpecialIntrinsic::kAny: {
SkASSERT(c.fArguments.size() == 1);
case SpecialIntrinsic::kDot: {
SkASSERT(c.fArguments.size() == 2);
int count = SlotCount(c.fArguments[0]->fType);
SkASSERT(count > 1);
// Fold a bvec down to a single bool:
ByteCode::Register arg = this->next(count);
ByteCode::Instruction inst = intrinsic.fValue.fSpecial == SpecialIntrinsic::kAll
? ByteCode::Instruction::kAnd
: ByteCode::Instruction::kOr;
this->writeExpression(*c.fArguments[0], arg);
ByteCode::Register left = this->next(count);
this->writeExpression(*c.fArguments[0], left);
ByteCode::Register right = this->next(count);
this->writeExpression(*c.fArguments[1], right);
ByteCode::Register product = this->next(count);
this->writeTypedInstruction(c.fType,
ByteCode::Instruction::kMultiplyIN,
ByteCode::Instruction::kMultiplyIN,
ByteCode::Instruction::kMultiplyFN);
this->write((uint8_t) count);
this->write(product);
this->write(left);
this->write(right);
ByteCode::Register total = product;
for (int i = 1; i < count; ++i) {
this->write(inst);
this->write(result);
this->write(i == 1 ? arg : result);
this->write(arg + i);
this->writeTypedInstruction(c.fType,
ByteCode::Instruction::kAddI,
ByteCode::Instruction::kAddI,
ByteCode::Instruction::kAddF);
ByteCode::Register sum = i == count - 1 ? result : this->next(1);
this->write(sum);
this->write(total);
this->write(product + i);
total = sum;
}
break;
}
@ -982,7 +970,7 @@ void ByteCodeGenerator::writeIntrinsicCall(const FunctionCall& c, Intrinsic intr
}
}
} else {
uint8_t count = (uint8_t) SlotCount(c.fType);
int count = SlotCount(c.fType);
std::vector<ByteCode::Register> argRegs;
for (const auto& expr : c.fArguments) {
SkASSERT(SlotCount(expr->fType) == count);
@ -990,49 +978,21 @@ void ByteCodeGenerator::writeIntrinsicCall(const FunctionCall& c, Intrinsic intr
this->writeExpression(*expr, reg);
argRegs.push_back(reg);
}
const auto& instructions = intrinsic.fValue.fInstructions;
const Type& opType = c.fArguments[0]->fType;
if (instructions.fUseVector) {
if (count == 1) {
this->writeTypedInstruction(opType,
instructions.fFloat,
instructions.fSigned,
instructions.fUnsigned);
} else {
this->writeTypedInstruction(opType,
VEC(instructions.fFloat),
VEC(instructions.fSigned),
VEC(instructions.fUnsigned));
this->write(count);
}
this->write(result);
for (ByteCode::Register arg : argRegs) {
this->write(arg);
}
} else {
// No vector version of the instruction exists. Emit the scalar instruction N times.
for (uint8_t i = 0; i < count; ++i) {
this->writeTypedInstruction(opType,
instructions.fFloat,
instructions.fSigned,
instructions.fUnsigned);
for (int i = 0; i < count; ++i) {
this->write(intrinsic.fValue.fInstruction);
if (c.fType.fName != "void") {
this->write(result + i);
for (ByteCode::Register arg : argRegs) {
this->write(arg + i);
}
}
for (ByteCode::Register arg : argRegs) {
this->write(arg + i);
}
}
}
}
void ByteCodeGenerator::writeFunctionCall(const FunctionCall& c, ByteCode::Register result) {
// 'mix' is present as both a "pure" intrinsic (fDefined == false), and an SkSL implementation
// in the pre-parsed include files (fDefined == true), depending on argument types. We only
// send calls to the former through the intrinsic path here.
auto found = fIntrinsics.find(c.fFunction.fName);
if (found != fIntrinsics.end() && !c.fFunction.fDefined) {
if (found != fIntrinsics.end()) {
return this->writeIntrinsicCall(c, found->second, result);
}
int argCount = c.fArguments.size();
@ -1202,9 +1162,9 @@ void ByteCodeGenerator::writeTernaryExpression(const TernaryExpression& t,
for (int i = 0; i < count; ++i) {
this->write(ByteCode::Instruction::kSelect);
this->write(result + i);
this->write(ifFalse + i);
this->write(ifTrue + i);
this->write(test);
this->write(ifTrue + i);
this->write(ifFalse + i);
}
}

View File

@ -61,21 +61,15 @@ public:
private:
// Intrinsics which do not simply map to a single opcode
enum class SpecialIntrinsic {
kAll,
kAny,
kDot,
kInverse,
kPrint,
};
struct Intrinsic {
Intrinsic(ByteCode::Instruction i, bool useVector)
Intrinsic(ByteCode::Instruction instruction)
: fIsSpecial(false)
, fValue(i, i, i, useVector) {}
Intrinsic(ByteCode::Instruction f, ByteCode::Instruction s, ByteCode::Instruction u,
bool useVector)
: fIsSpecial(false)
, fValue(f, s, u, useVector) {}
, fValue(instruction) {}
Intrinsic(SpecialIntrinsic special)
: fIsSpecial(true)
@ -84,21 +78,13 @@ private:
bool fIsSpecial;
union Value {
Value(ByteCode::Instruction f, ByteCode::Instruction s, ByteCode::Instruction u,
bool useVector)
: fInstructions{ f, s, u, useVector } {}
Value(ByteCode::Instruction instruction)
: fInstruction(instruction) {}
Value(SpecialIntrinsic special)
: fSpecial(special) {}
struct {
ByteCode::Instruction fFloat;
ByteCode::Instruction fSigned;
ByteCode::Instruction fUnsigned;
bool fUseVector;
} fInstructions;
ByteCode::Instruction fInstruction;
SpecialIntrinsic fSpecial;
} fValue;
};

View File

@ -54,10 +54,6 @@ static const char* SKSL_INTERP_INCLUDE =
#include "sksl_interp.inc"
;
static const char* SKSL_INTERP_INLINE_INCLUDE =
#include "sksl_interp_inline.inc"
;
static const char* SKSL_VERT_INCLUDE =
#include "sksl_vert.inc"
;
@ -287,13 +283,9 @@ Compiler::Compiler(Flags flags)
this->processIncludeFile(Program::kPipelineStage_Kind, SKSL_PIPELINE_INCLUDE,
strlen(SKSL_PIPELINE_INCLUDE), fGpuSymbolTable, &fPipelineInclude,
&fPipelineSymbolTable);
this->processIncludeFile(Program::kGeneric_Kind, SKSL_INTERP_INCLUDE,
strlen(SKSL_INTERP_INCLUDE), symbols, &fInterpreterInclude,
&fInterpreterSymbolTable);
this->processIncludeFile(Program::kGeneric_Kind, SKSL_INTERP_INLINE_INCLUDE,
strlen(SKSL_INTERP_INLINE_INCLUDE), std::move(fInterpreterSymbolTable),
&fInterpreterInclude, &fInterpreterSymbolTable);
grab_intrinsics(&fInterpreterInclude, &fInterpreterIntrinsics);
// need to hang on to the source so that FunctionDefinition.fSource pointers in this file
// remain valid

View File

@ -381,22 +381,22 @@ private:
DISASSEMBLE_VECTOR_BINARY(kAddF, "addF")
DISASSEMBLE_VECTOR_BINARY(kAddI, "addI")
DISASSEMBLE_BINARY(kAnd, "and")
DISASSEMBLE_VECTOR_BINARY(kCompareEQF, "compare eqF")
DISASSEMBLE_VECTOR_BINARY(kCompareEQI, "compare eqI")
DISASSEMBLE_VECTOR_BINARY(kCompareNEQF, "compare neqF")
DISASSEMBLE_VECTOR_BINARY(kCompareNEQI, "compare neqI")
DISASSEMBLE_VECTOR_BINARY(kCompareGTF, "compare gtF")
DISASSEMBLE_VECTOR_BINARY(kCompareGTS, "compare gtS")
DISASSEMBLE_VECTOR_BINARY(kCompareGTU, "compare gtU")
DISASSEMBLE_VECTOR_BINARY(kCompareGTEQF, "compare gteqF")
DISASSEMBLE_VECTOR_BINARY(kCompareGTEQS, "compare gteqS")
DISASSEMBLE_VECTOR_BINARY(kCompareGTEQU, "compare gteqU")
DISASSEMBLE_VECTOR_BINARY(kCompareLTF, "compare ltF")
DISASSEMBLE_VECTOR_BINARY(kCompareLTS, "compare ltS")
DISASSEMBLE_VECTOR_BINARY(kCompareLTU, "compare ltU")
DISASSEMBLE_VECTOR_BINARY(kCompareLTEQF, "compare lteqF")
DISASSEMBLE_VECTOR_BINARY(kCompareLTEQS, "compare lteqS")
DISASSEMBLE_VECTOR_BINARY(kCompareLTEQU, "compare lteqU")
DISASSEMBLE_BINARY(kCompareEQF, "compare eqF")
DISASSEMBLE_BINARY(kCompareEQI, "compare eqI")
DISASSEMBLE_BINARY(kCompareNEQF, "compare neqF")
DISASSEMBLE_BINARY(kCompareNEQI, "compare neqI")
DISASSEMBLE_BINARY(kCompareGTF, "compare gtF")
DISASSEMBLE_BINARY(kCompareGTS, "compare gtS")
DISASSEMBLE_BINARY(kCompareGTU, "compare gtU")
DISASSEMBLE_BINARY(kCompareGTEQF, "compare gteqF")
DISASSEMBLE_BINARY(kCompareGTEQS, "compare gteqS")
DISASSEMBLE_BINARY(kCompareGTEQU, "compare gteqU")
DISASSEMBLE_BINARY(kCompareLTF, "compare ltF")
DISASSEMBLE_BINARY(kCompareLTS, "compare ltS")
DISASSEMBLE_BINARY(kCompareLTU, "compare ltU")
DISASSEMBLE_BINARY(kCompareLTEQF, "compare lteqF")
DISASSEMBLE_BINARY(kCompareLTEQS, "compare lteqS")
DISASSEMBLE_BINARY(kCompareLTEQU, "compare lteqU")
DISASSEMBLE_VECTOR_BINARY(kSubtractF, "subF")
DISASSEMBLE_VECTOR_BINARY(kSubtractI, "subI")
DISASSEMBLE_VECTOR_BINARY(kDivideF, "divF")
@ -553,23 +553,13 @@ private:
}
case ByteCode::Instruction::kSelect: {
ByteCode::Register target = read<ByteCode::Register>(ip);
ByteCode::Register src2 = read<ByteCode::Register>(ip);
ByteCode::Register src1 = read<ByteCode::Register>(ip);
ByteCode::Register test = read<ByteCode::Register>(ip);
ByteCode::Register src1 = read<ByteCode::Register>(ip);
ByteCode::Register src2 = read<ByteCode::Register>(ip);
printf("select $%d, $%d, $%d -> %d\n", test.fIndex, src1.fIndex, src2.fIndex,
target.fIndex);
break;
}
case ByteCode::Instruction::kSelectN: {
uint8_t count = read<uint8_t>(ip);
ByteCode::Register target = read<ByteCode::Register>(ip);
ByteCode::Register src2 = read<ByteCode::Register>(ip);
ByteCode::Register src1 = read<ByteCode::Register>(ip);
ByteCode::Register test = read<ByteCode::Register>(ip);
printf("select%d $%d, $%d, $%d -> %d\n", count, test.fIndex, src1.fIndex,
src2.fIndex, target.fIndex);
break;
}
DISASSEMBLE_BINARY(kShiftLeft, "shiftLeft")
DISASSEMBLE_BINARY(kShiftRightS, "shiftRightS")
DISASSEMBLE_BINARY(kShiftRightU, "shiftRightU")
@ -755,37 +745,21 @@ private:
&&kCall,
&&kCallExternal,
&&kCompareEQF,
&&kCompareEQFN,
&&kCompareEQI,
&&kCompareEQIN,
&&kCompareNEQF,
&&kCompareNEQFN,
&&kCompareNEQI,
&&kCompareNEQIN,
&&kCompareGTF,
&&kCompareGTFN,
&&kCompareGTS,
&&kCompareGTSN,
&&kCompareGTU,
&&kCompareGTUN,
&&kCompareGTEQF,
&&kCompareGTEQFN,
&&kCompareGTEQS,
&&kCompareGTEQSN,
&&kCompareGTEQU,
&&kCompareGTEQUN,
&&kCompareLTF,
&&kCompareLTFN,
&&kCompareLTS,
&&kCompareLTSN,
&&kCompareLTU,
&&kCompareLTUN,
&&kCompareLTEQF,
&&kCompareLTEQFN,
&&kCompareLTEQS,
&&kCompareLTEQSN,
&&kCompareLTEQU,
&&kCompareLTEQUN,
&&kContinue,
&&kCopy,
&&kCos,
@ -842,7 +816,6 @@ private:
&&kReturnValue,
&&kScalarToMatrix,
&&kSelect,
&&kSelectN,
&&kShiftLeft,
&&kShiftRightS,
&&kShiftRightU,
@ -883,37 +856,21 @@ private:
CHECK_LABEL(kCall);
CHECK_LABEL(kCallExternal);
CHECK_LABEL(kCompareEQF);
CHECK_LABEL(kCompareEQFN);
CHECK_LABEL(kCompareEQI);
CHECK_LABEL(kCompareEQIN);
CHECK_LABEL(kCompareNEQF);
CHECK_LABEL(kCompareNEQFN);
CHECK_LABEL(kCompareNEQI);
CHECK_LABEL(kCompareNEQIN);
CHECK_LABEL(kCompareGTF);
CHECK_LABEL(kCompareGTFN);
CHECK_LABEL(kCompareGTS);
CHECK_LABEL(kCompareGTSN);
CHECK_LABEL(kCompareGTU);
CHECK_LABEL(kCompareGTUN);
CHECK_LABEL(kCompareGTEQF);
CHECK_LABEL(kCompareGTEQFN);
CHECK_LABEL(kCompareGTEQS);
CHECK_LABEL(kCompareGTEQSN);
CHECK_LABEL(kCompareGTEQU);
CHECK_LABEL(kCompareGTEQUN);
CHECK_LABEL(kCompareLTF);
CHECK_LABEL(kCompareLTFN);
CHECK_LABEL(kCompareLTS);
CHECK_LABEL(kCompareLTSN);
CHECK_LABEL(kCompareLTU);
CHECK_LABEL(kCompareLTUN);
CHECK_LABEL(kCompareLTEQF);
CHECK_LABEL(kCompareLTEQFN);
CHECK_LABEL(kCompareLTEQS);
CHECK_LABEL(kCompareLTEQSN);
CHECK_LABEL(kCompareLTEQU);
CHECK_LABEL(kCompareLTEQUN);
CHECK_LABEL(kContinue);
CHECK_LABEL(kCopy);
CHECK_LABEL(kCos);
@ -970,7 +927,6 @@ private:
CHECK_LABEL(kReturnValue);
CHECK_LABEL(kScalarToMatrix);
CHECK_LABEL(kSelect);
CHECK_LABEL(kSelectN);
CHECK_LABEL(kShiftLeft);
CHECK_LABEL(kShiftRightS);
CHECK_LABEL(kShiftRightU);
@ -1025,22 +981,22 @@ private:
VECTOR_BINARY_OP(kAddF, fFloat, fFloat, +)
VECTOR_BINARY_OP(kAddI, fInt, fInt, +)
BINARY_OP(kAnd, fInt, fInt, &)
VECTOR_BINARY_OP(kCompareEQF, fFloat, fInt, ==)
VECTOR_BINARY_OP(kCompareEQI, fInt, fInt, ==)
VECTOR_BINARY_OP(kCompareNEQF, fFloat, fInt, !=)
VECTOR_BINARY_OP(kCompareNEQI, fInt, fInt, !=)
VECTOR_BINARY_OP(kCompareGTF, fFloat, fInt, >)
VECTOR_BINARY_OP(kCompareGTS, fInt, fInt, >)
VECTOR_BINARY_OP(kCompareGTU, fUInt, fUInt, >)
VECTOR_BINARY_OP(kCompareGTEQF, fFloat, fInt, >=)
VECTOR_BINARY_OP(kCompareGTEQS, fInt, fInt, >=)
VECTOR_BINARY_OP(kCompareGTEQU, fUInt, fUInt, >=)
VECTOR_BINARY_OP(kCompareLTF, fFloat, fInt, <)
VECTOR_BINARY_OP(kCompareLTS, fInt, fInt, <)
VECTOR_BINARY_OP(kCompareLTU, fUInt, fUInt, <)
VECTOR_BINARY_OP(kCompareLTEQF, fFloat, fInt, <=)
VECTOR_BINARY_OP(kCompareLTEQS, fInt, fInt, <=)
VECTOR_BINARY_OP(kCompareLTEQU, fUInt, fUInt, <=)
BINARY_OP(kCompareEQF, fFloat, fInt, ==)
BINARY_OP(kCompareEQI, fInt, fInt, ==)
BINARY_OP(kCompareNEQF, fFloat, fInt, !=)
BINARY_OP(kCompareNEQI, fInt, fInt, !=)
BINARY_OP(kCompareGTF, fFloat, fInt, >)
BINARY_OP(kCompareGTS, fInt, fInt, >)
BINARY_OP(kCompareGTU, fUInt, fUInt, >)
BINARY_OP(kCompareGTEQF, fFloat, fInt, >=)
BINARY_OP(kCompareGTEQS, fInt, fInt, >=)
BINARY_OP(kCompareGTEQU, fUInt, fUInt, >=)
BINARY_OP(kCompareLTF, fFloat, fInt, <)
BINARY_OP(kCompareLTS, fInt, fInt, <)
BINARY_OP(kCompareLTU, fUInt, fUInt, <)
BINARY_OP(kCompareLTEQF, fFloat, fInt, <=)
BINARY_OP(kCompareLTEQS, fInt, fInt, <=)
BINARY_OP(kCompareLTEQU, fUInt, fUInt, <=)
VECTOR_BINARY_OP(kSubtractF, fFloat, fFloat, -)
VECTOR_BINARY_OP(kSubtractI, fInt, fInt, -)
VECTOR_BINARY_OP(kDivideF, fFloat, fFloat, /)
@ -1513,28 +1469,14 @@ private:
}
LABEL(kSelect) {
ByteCode::Register target = read<ByteCode::Register>(&ip);
ByteCode::Register src2 = read<ByteCode::Register>(&ip);
ByteCode::Register src1 = read<ByteCode::Register>(&ip);
ByteCode::Register test = read<ByteCode::Register>(&ip);
ByteCode::Register src1 = read<ByteCode::Register>(&ip);
ByteCode::Register src2 = read<ByteCode::Register>(&ip);
fRegisters[target.fIndex] = skvx::if_then_else(fRegisters[test.fIndex].fInt,
fRegisters[src1.fIndex].fFloat,
fRegisters[src2.fIndex].fFloat);
NEXT();
}
LABEL(kSelectN) {
uint8_t count = read<uint8_t>(&ip);
ByteCode::Register target = read<ByteCode::Register>(&ip);
ByteCode::Register src2 = read<ByteCode::Register>(&ip);
ByteCode::Register src1 = read<ByteCode::Register>(&ip);
ByteCode::Register test = read<ByteCode::Register>(&ip);
for (int i = 0; i < count; ++i) {
fRegisters[target.fIndex + i] =
skvx::if_then_else(fRegisters[test.fIndex + i].fInt,
fRegisters[src1.fIndex + i].fFloat,
fRegisters[src2.fIndex + i].fFloat);
}
NEXT();
}
LABEL(kShiftLeft) {
ByteCode::Register target = read<ByteCode::Register>(&ip);
ByteCode::Register src = read<ByteCode::Register>(&ip);

View File

@ -4,6 +4,7 @@ sk_has_side_effects void print(float f);
$genType cos($genType y);
$genHType cos($genHType y);
float dot($genType x, $genType y);
float2x2 inverse(float2x2 m);
float3x3 inverse(float3x3 m);
float4x4 inverse(float4x4 m);
@ -14,40 +15,41 @@ $genHType sqrt($genHType x);
$genType tan($genType x);
$genHType tan($genHType x);
$genType mix($genType x, $genType y, $genBType a);
$genHType mix($genHType x, $genHType y, $genBType a);
$genIType mix($genIType x, $genIType y, $genBType a);
$genBType mix($genBType x, $genBType y, $genBType a);
float degrees(float rad) { return rad * 57.2957795; }
float2 degrees(float2 rad) { return rad * 57.2957795; }
float3 degrees(float3 rad) { return rad * 57.2957795; }
float4 degrees(float4 rad) { return rad * 57.2957795; }
$bvec lessThan($vec x, $vec y);
$bvec lessThan($hvec x, $hvec y);
$bvec lessThan($ivec x, $ivec y);
$bvec lessThan($uvec x, $uvec y);
$bvec lessThanEqual($vec x, $vec y);
$bvec lessThanEqual($hvec x, $hvec y);
$bvec lessThanEqual($ivec x, $ivec y);
$bvec lessThanEqual($uvec x, $uvec y);
$bvec greaterThan($vec x, $vec y);
$bvec greaterThan($hvec x, $hvec y);
$bvec greaterThan($ivec x, $ivec y);
$bvec greaterThan($uvec x, $uvec y);
$bvec greaterThanEqual($vec x, $vec y);
$bvec greaterThanEqual($hvec x, $hvec y);
$bvec greaterThanEqual($ivec x, $ivec y);
$bvec greaterThanEqual($uvec x, $uvec y);
$bvec equal($vec x, $vec y);
$bvec equal($hvec x, $hvec y);
$bvec equal($ivec x, $ivec y);
$bvec equal($uvec x, $uvec y);
$bvec equal($bvec x, $bvec y);
$bvec notEqual($vec x, $vec y);
$bvec notEqual($hvec x, $hvec y);
$bvec notEqual($ivec x, $ivec y);
$bvec notEqual($uvec x, $uvec y);
$bvec notEqual($bvec x, $bvec y);
float radians(float deg) { return deg * 0.0174532925; }
float2 radians(float2 deg) { return deg * 0.0174532925; }
float3 radians(float3 deg) { return deg * 0.0174532925; }
float4 radians(float4 deg) { return deg * 0.0174532925; }
bool any($bvec x);
bool all($bvec x);
$bvec not($bvec x);
float length(float2 v) { return sqrt(dot(v, v)); }
float length(float3 v) { return sqrt(dot(v, v)); }
float length(float4 v) { return sqrt(dot(v, v)); }
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); }
float2 normalize(float2 v) { return v / length(v); }
float3 normalize(float3 v) { return v / length(v); }
float4 normalize(float4 v) { return v / length(v); }
float mix(float x, float y, float t) { return x * (1 - t) + y * t; }
float2 mix(float2 x, float2 y, float t) { return x * (1 - t) + y * t; }
float3 mix(float3 x, float3 y, float t) { return x * (1 - t) + y * t; }
float4 mix(float4 x, float4 y, float t) { return x * (1 - t) + y * t; }
float2 mix(float2 x, float2 y, float2 t) { return x * (1 - t) + y * t; }
float3 mix(float3 x, float3 y, float3 t) { return x * (1 - t) + y * t; }
float4 mix(float4 x, float4 y, float4 t) { return x * (1 - t) + y * t; }
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);
}
)

View File

@ -1,120 +0,0 @@
STRINGIFY(
float dot(float2 a, float2 b) { return a.x*b.x + a.y*b.y; }
float dot(float3 a, float3 b) { return a.x*b.x + a.y*b.y + a.z*b.z; }
float dot(float4 a, float4 b) { return a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w; }
float degrees(float rad) { return rad * 57.2957795; }
float2 degrees(float2 rad) { return rad * 57.2957795; }
float3 degrees(float3 rad) { return rad * 57.2957795; }
float4 degrees(float4 rad) { return rad * 57.2957795; }
float radians(float deg) { return deg * 0.0174532925; }
float2 radians(float2 deg) { return deg * 0.0174532925; }
float3 radians(float3 deg) { return deg * 0.0174532925; }
float4 radians(float4 deg) { return deg * 0.0174532925; }
float length(float2 v) { return sqrt(dot(v, v)); }
float length(float3 v) { return sqrt(dot(v, v)); }
float length(float4 v) { return sqrt(dot(v, v)); }
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); }
float2 normalize(float2 v) { return v / length(v); }
float3 normalize(float3 v) { return v / length(v); }
float4 normalize(float4 v) { return v / length(v); }
float mix(float x, float y, float t) { return x * (1 - t) + y * t; }
float2 mix(float2 x, float2 y, float t) { return x * (1 - t) + y * t; }
float3 mix(float3 x, float3 y, float t) { return x * (1 - t) + y * t; }
float4 mix(float4 x, float4 y, float t) { return x * (1 - t) + y * t; }
float2 mix(float2 x, float2 y, float2 t) { return x * (1 - t) + y * t; }
float3 mix(float3 x, float3 y, float3 t) { return x * (1 - t) + y * t; }
float4 mix(float4 x, float4 y, float4 t) { return x * (1 - t) + y * t; }
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);
}
float min(float x, float y) { return mix(y, x, x < y); }
float2 min(float2 x, float2 y) { return mix(y, x, lessThan(x, y)); }
float3 min(float3 x, float3 y) { return mix(y, x, lessThan(x, y)); }
float4 min(float4 x, float4 y) { return mix(y, x, lessThan(x, y)); }
float2 min(float2 x, float y) { return mix(float2(y), x, lessThan(x, float2(y))); }
float3 min(float3 x, float y) { return mix(float3(y), x, lessThan(x, float3(y))); }
float4 min(float4 x, float y) { return mix(float4(y), x, lessThan(x, float4(y))); }
float max(float x, float y) { return mix(y, x, x > y); }
float2 max(float2 x, float2 y) { return mix(y, x, greaterThan(x, y)); }
float3 max(float3 x, float3 y) { return mix(y, x, greaterThan(x, y)); }
float4 max(float4 x, float4 y) { return mix(y, x, greaterThan(x, y)); }
float2 max(float2 x, float y) { return mix(float2(y), x, greaterThan(x, float2(y))); }
float3 max(float3 x, float y) { return mix(float3(y), x, greaterThan(x, float3(y))); }
float4 max(float4 x, float y) { return mix(float4(y), x, greaterThan(x, float4(y))); }
float clamp(float x, float minVal, float maxVal) { return min(max(x, minVal), maxVal); }
float2 clamp(float2 x, float2 minVal, float2 maxVal) { return min(max(x, minVal), maxVal); }
float3 clamp(float3 x, float3 minVal, float3 maxVal) { return min(max(x, minVal), maxVal); }
float4 clamp(float4 x, float4 minVal, float4 maxVal) { return min(max(x, minVal), maxVal); }
float2 clamp(float2 x, float minVal, float maxVal) { return min(max(x, minVal), maxVal); }
float3 clamp(float3 x, float minVal, float maxVal) { return min(max(x, minVal), maxVal); }
float4 clamp(float4 x, float minVal, float maxVal) { return min(max(x, minVal), maxVal); }
float saturate(float x) { return min(max(x, 0), 1); }
float2 saturate(float2 x) { return min(max(x, 0), 1); }
float3 saturate(float3 x) { return min(max(x, 0), 1); }
float4 saturate(float4 x) { return min(max(x, 0), 1); }
float step(float edge, float x) { return mix(1, 0, x < edge); }
float2 step(float2 edge, float2 x) { return mix(float2(1), float2(0), lessThan(x, edge)); }
float3 step(float3 edge, float3 x) { return mix(float3(1), float3(0), lessThan(x, edge)); }
float4 step(float4 edge, float4 x) { return mix(float4(1), float4(0), lessThan(x, edge)); }
float2 step(float edge, float2 x) { return mix(float2(1), float2(0), lessThan(x, float2(edge))); }
float3 step(float edge, float3 x) { return mix(float3(1), float3(0), lessThan(x, float3(edge))); }
float4 step(float edge, float4 x) { return mix(float4(1), float4(0), lessThan(x, float4(edge))); }
float smoothstep(float edge0, float edge1, float x) {
float t = saturate((x - edge0) / (edge1 - edge0));
return t * t * (3.0 - 2.0 * t);
}
float2 smoothstep(float2 edge0, float2 edge1, float2 x) {
float2 t = saturate((x - edge0) / (edge1 - edge0));
return t * t * (3.0 - 2.0 * t);
}
float3 smoothstep(float3 edge0, float3 edge1, float3 x) {
float3 t = saturate((x - edge0) / (edge1 - edge0));
return t * t * (3.0 - 2.0 * t);
}
float4 smoothstep(float4 edge0, float4 edge1, float4 x) {
float4 t = saturate((x - edge0) / (edge1 - edge0));
return t * t * (3.0 - 2.0 * t);
}
float2 smoothstep(float edge0, float edge1, float2 x) {
float2 t = saturate((x - edge0) / (edge1 - edge0));
return t * t * (3.0 - 2.0 * t);
}
float3 smoothstep(float edge0, float edge1, float3 x) {
float3 t = saturate((x - edge0) / (edge1 - edge0));
return t * t * (3.0 - 2.0 * t);
}
float4 smoothstep(float edge0, float edge1, float4 x) {
float4 t = saturate((x - edge0) / (edge1 - edge0));
return t * t * (3.0 - 2.0 * t);
}
)

View File

@ -796,6 +796,8 @@ DEF_TEST(SkSLInterpreterFunctions, r) {
"float main(float x) { return sub(sqr(x), x); }\n"
// Different signatures
"float dot(float2 a, float2 b) { return a.x*b.x + a.y*b.y; }\n"
"float dot(float3 a, float3 b) { return a.x*b.x + a.y*b.y + a.z*b.z; }\n"
"float dot3_test(float x) { return dot(float3(x, x + 1, x + 2), float3(1, -1, 2)); }\n"
"float dot2_test(float x) { return dot(float2(x, x + 1), float2(1, -1)); }\n";
@ -957,29 +959,6 @@ DEF_TEST(SkSLInterpreterMix, r) {
expectedVector[] = { 3.0f, 4.0f, 5.0f, 6.0f };
test(r, "float4 main(float4 x, float4 y) { return mix(x, y, 0.5); }", valueVectors,
expectedVector);
auto expect = [&expectedVector](float a, float b, float c, float d) {
expectedVector[0] = a;
expectedVector[1] = b;
expectedVector[2] = c;
expectedVector[3] = d;
};
expect(1, 2, 7, 8);
test(r, "float4 main(float4 x, float4 y) { return mix(x, y, greaterThan(x, float4(2.5))); }",
valueVectors, expectedVector);
expect(5, 6, 3, 4);
test(r, "float4 main(float4 x, float4 y) { return mix(x, y, lessThan(x, float4(2.5))); }",
valueVectors, expectedVector);
expect(1, 2, 7, 8);
test(r, "float4 main(float4 x, float4 y) { return mix(x, y, greaterThanEqual(x, float4(3))); }",
valueVectors, expectedVector);
expect(5, 6, 3, 4);
test(r, "float4 main(float4 x, float4 y) { return mix(x, y, lessThanEqual(x, float4(2))); }",
valueVectors, expectedVector);
}
DEF_TEST(SkSLInterpreterCross, r) {