Interpreter: Implement/fix vectorized load/store of globals
Also has swizzled loads of globals. Swizzle stores are still broken. Change-Id: I0c01a309592c0aa460e1459de2636a2e1ef2ee6c Reviewed-on: https://skia-review.googlesource.com/c/skia/+/213830 Reviewed-by: Ethan Nicholas <ethannicholas@google.com> Commit-Queue: Brian Osman <brianosman@google.com>
This commit is contained in:
parent
50a4e6e3b1
commit
b745129ceb
@ -61,6 +61,7 @@ enum class ByteCodeInstruction : uint8_t {
|
||||
kLoadGlobal,
|
||||
// Followed by a count byte (1-4), and then one byte per swizzle component (0-3).
|
||||
kLoadSwizzle,
|
||||
kLoadSwizzleGlobal,
|
||||
kNegateF,
|
||||
kNegateS,
|
||||
kMultiplyF,
|
||||
|
@ -141,6 +141,7 @@ int ByteCodeGenerator::getLocation(const Variable& var) {
|
||||
continue;
|
||||
}
|
||||
if (declVar == &var) {
|
||||
SkASSERT(offset <= 255);
|
||||
return offset;
|
||||
}
|
||||
offset += slot_count(declVar->fType);
|
||||
@ -440,11 +441,15 @@ void ByteCodeGenerator::writeSwizzle(const Swizzle& s) {
|
||||
switch (s.fBase->fKind) {
|
||||
case Expression::kVariableReference_Kind: {
|
||||
const Variable& var = ((VariableReference&) *s.fBase).fVariable;
|
||||
int location = this->getLocation(var);
|
||||
this->align(4, 3);
|
||||
this->write(ByteCodeInstruction::kPushImmediate);
|
||||
this->write32(location);
|
||||
this->write(ByteCodeInstruction::kLoadSwizzle);
|
||||
if (var.fStorage == Variable::kGlobal_Storage) {
|
||||
this->write(ByteCodeInstruction::kLoadSwizzleGlobal);
|
||||
this->write8(this->getLocation(var));
|
||||
} else {
|
||||
this->align(4, 3);
|
||||
this->write(ByteCodeInstruction::kPushImmediate);
|
||||
this->write32(this->getLocation(var));
|
||||
this->write(ByteCodeInstruction::kLoadSwizzle);
|
||||
}
|
||||
this->write8(s.fComponents.size());
|
||||
for (int c : s.fComponents) {
|
||||
this->write8(c);
|
||||
@ -464,10 +469,13 @@ void ByteCodeGenerator::writeSwizzle(const Swizzle& s) {
|
||||
|
||||
void ByteCodeGenerator::writeVariableReference(const VariableReference& v) {
|
||||
if (v.fVariable.fStorage == Variable::kGlobal_Storage) {
|
||||
int count = slot_count(v.fType);
|
||||
if (count > 1) {
|
||||
this->write(ByteCodeInstruction::kVector);
|
||||
this->write8(count);
|
||||
}
|
||||
this->write(ByteCodeInstruction::kLoadGlobal);
|
||||
int location = this->getLocation(v.fVariable);
|
||||
SkASSERT(location <= 255);
|
||||
this->write8(location);
|
||||
this->write8(this->getLocation(v.fVariable));
|
||||
} else {
|
||||
this->align(4, 3);
|
||||
this->write(ByteCodeInstruction::kPushImmediate);
|
||||
|
@ -148,6 +148,14 @@ void Interpreter::disassemble(const ByteCodeFunction& f) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ByteCodeInstruction::kLoadSwizzleGlobal: {
|
||||
int count = READ8();
|
||||
printf("loadswizzleglobal %d", count);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
printf(", %d", READ8());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ByteCodeInstruction::kMultiplyF: printf("multiplyf"); break;
|
||||
case ByteCodeInstruction::kMultiplyS: printf("multiplys"); break;
|
||||
case ByteCodeInstruction::kMultiplyU: printf("multiplyu"); break;
|
||||
@ -341,6 +349,16 @@ void Interpreter::run(const ByteCodeFunction& f, Value* stack, Value args[], Val
|
||||
ip += count;
|
||||
break;
|
||||
}
|
||||
case ByteCodeInstruction::kLoadSwizzleGlobal: {
|
||||
int target = READ8();
|
||||
SkASSERT(target < (int) fGlobals.size());
|
||||
int count = READ8();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
PUSH(fGlobals[target + *(ip + i)]);
|
||||
}
|
||||
ip += count;
|
||||
break;
|
||||
}
|
||||
BINARY_OP(kMultiplyS, int32_t, fSigned, *)
|
||||
BINARY_OP(kMultiplyU, uint32_t, fUnsigned, *)
|
||||
BINARY_OP(kMultiplyF, float, fFloat, *)
|
||||
@ -497,7 +515,8 @@ void Interpreter::run(const ByteCodeFunction& f, Value* stack, Value args[], Val
|
||||
case ByteCodeInstruction::kLoadGlobal: {
|
||||
int target = READ8();
|
||||
SkASSERT(target < (int) fGlobals.size());
|
||||
PUSH(fGlobals[target]);
|
||||
memcpy(sp + 1, &fGlobals[target], count * sizeof(Value));
|
||||
sp += count;
|
||||
break;
|
||||
}
|
||||
case ByteCodeInstruction::kNegateS: {
|
||||
@ -538,6 +557,13 @@ void Interpreter::run(const ByteCodeFunction& f, Value* stack, Value args[], Val
|
||||
sp -= count;
|
||||
break;
|
||||
}
|
||||
case ByteCodeInstruction::kStoreGlobal: {
|
||||
int target = (sp - count)->fSigned;
|
||||
SkASSERT(target < (int)fGlobals.size());
|
||||
memcpy(&fGlobals[target], sp - count + 1, count * sizeof(Value));
|
||||
sp -= count;
|
||||
break;
|
||||
}
|
||||
VECTOR_BINARY_OP(kSubtractI, int32_t, fSigned, -)
|
||||
VECTOR_BINARY_OP(kSubtractF, float, fFloat, -)
|
||||
default:
|
||||
|
@ -269,6 +269,10 @@ DEF_TEST(SkSLInterpreterSwizzle, r) {
|
||||
DEF_TEST(SkSLInterpreterGlobal, r) {
|
||||
test(r, "int x; void main(inout half4 color) { x = 10; color.b = x; }", 1, 2, 3, 4, 1, 2, 10,
|
||||
4);
|
||||
test(r, "float4 x; void main(inout float4 color) { x = color * 2; color = x; }",
|
||||
1, 2, 3, 4, 2, 4, 6, 8);
|
||||
test(r, "float4 x; void main(inout float4 color) { x = float4(5, 6, 7, 8); color = x.wzyx; }",
|
||||
1, 2, 3, 4, 8, 7, 6, 5);
|
||||
}
|
||||
|
||||
DEF_TEST(SkSLInterpreterGeneric, r) {
|
||||
|
Loading…
Reference in New Issue
Block a user