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:
parent
00666b5739
commit
15c98cbfef
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
)
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
)
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user