Add support for Field lvalues.
This allows the code generator to compile assignment into struct
fields. However, non-lvalue field-access expressions have not been
implemented yet, so those assignments cannot be read back.
Surprisingly, we do have one test which now passes because it
meets these criteria.
Change-Id: I2bd46469c6b542d2fb41bce135e7cac43281fe3c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/639859
Commit-Queue: Arman Uguray <armansito@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Arman Uguray <armansito@google.com>
diff --git a/src/sksl/codegen/SkSLRasterPipelineCodeGenerator.cpp b/src/sksl/codegen/SkSLRasterPipelineCodeGenerator.cpp
index a33f5f3..c1d3533 100644
--- a/src/sksl/codegen/SkSLRasterPipelineCodeGenerator.cpp
+++ b/src/sksl/codegen/SkSLRasterPipelineCodeGenerator.cpp
@@ -37,6 +37,7 @@
#include "src/sksl/ir/SkSLDoStatement.h"
#include "src/sksl/ir/SkSLExpression.h"
#include "src/sksl/ir/SkSLExpressionStatement.h"
+#include "src/sksl/ir/SkSLFieldAccess.h"
#include "src/sksl/ir/SkSLForStatement.h"
#include "src/sksl/ir/SkSLFunctionCall.h"
#include "src/sksl/ir/SkSLFunctionDeclaration.h"
@@ -498,16 +499,12 @@
SlotMap in = fParent->getSlotMap(gen);
// Take a subset of the parent's slots.
+ // TODO(skia:13676): support non-constant indices
int numElements = fIndexedType.slotCount();
+ int startingIndex = numElements * fIndexExpr.as<Literal>().intValue();
SlotMap out;
- out.slots.resize(numElements);
- // TODO(skia:13676): support non-constant indices
- int startingIndex = numElements * fIndexExpr.as<Literal>().intValue();
- for (int count = 0; count < numElements; ++count) {
- out.slots[count] = in.slots[startingIndex + count];
- }
-
+ out.slots.push_back_n(numElements, &in.slots[startingIndex]);
return out;
}
@@ -520,6 +517,40 @@
const Type& fIndexedType;
};
+class FieldLValue final : public LValue {
+public:
+ FieldLValue(std::unique_ptr<LValue> p, const FieldAccess& fieldAccess)
+ : fParent(std::move(p)) {
+ // Calculate the slot range of this field in the parent.
+ SkSpan<const Type::Field> fields = fieldAccess.base()->type().fields();
+ const int fieldIndex = fieldAccess.fieldIndex();
+
+ fInitialSlot = 0;
+ for (int index = 0; index < fieldIndex; ++index) {
+ fInitialSlot += fields[index].fType->slotCount();
+ }
+ fNumSlots = fields[fieldIndex].fType->slotCount();
+ }
+
+ SlotMap getSlotMap(Generator* gen) const override {
+ // Get the slot map from the base expression.
+ SlotMap in = fParent->getSlotMap(gen);
+
+ // Take a subset of the parent's slots.
+ SlotMap out;
+ out.slots.push_back_n(fNumSlots, &in.slots[fInitialSlot]);
+ return out;
+ }
+
+ bool isUniform() const override {
+ return fParent->isUniform();
+ }
+
+ std::unique_ptr<LValue> fParent;
+ int fInitialSlot = 0;
+ int fNumSlots = 0;
+};
+
std::unique_ptr<LValue> LValue::Make(const Expression& e) {
if (e.is<VariableReference>()) {
return std::make_unique<VariableLValue>(e.as<VariableReference>().variable());
@@ -529,6 +560,11 @@
return std::make_unique<SwizzleLValue>(std::move(base), e.as<Swizzle>().components());
}
}
+ if (e.is<FieldAccess>()) {
+ if (std::unique_ptr<LValue> base = LValue::Make(*e.as<FieldAccess>().base())) {
+ return std::make_unique<FieldLValue>(std::move(base), e.as<FieldAccess>());
+ }
+ }
if (e.is<IndexExpression>()) {
const IndexExpression& indexExpr = e.as<IndexExpression>();
@@ -1226,11 +1262,11 @@
BuilderOp Generator::GetTypedOp(const SkSL::Type& type, const TypedOps& ops) {
switch (type.componentType().numberKind()) {
- case Type::NumberKind::kFloat: return ops.fFloatOp; break;
- case Type::NumberKind::kSigned: return ops.fSignedOp; break;
- case Type::NumberKind::kUnsigned: return ops.fUnsignedOp; break;
- case Type::NumberKind::kBoolean: return ops.fBooleanOp; break;
- default: SkUNREACHABLE;
+ case Type::NumberKind::kFloat: return ops.fFloatOp;
+ case Type::NumberKind::kSigned: return ops.fSignedOp;
+ case Type::NumberKind::kUnsigned: return ops.fUnsignedOp;
+ case Type::NumberKind::kBoolean: return ops.fBooleanOp;
+ default: return BuilderOp::unsupported;
}
}
diff --git a/tests/SkSLTest.cpp b/tests/SkSLTest.cpp
index c26491a..4ed3c35 100644
--- a/tests/SkSLTest.cpp
+++ b/tests/SkSLTest.cpp
@@ -609,7 +609,7 @@
SKSL_TEST(GPU_ES3, kNever, ArrayConstructors, "shared/ArrayConstructors.sksl")
SKSL_TEST(RP + VM + GPU_ES3, kNever, ArrayFollowedByScalar, "shared/ArrayFollowedByScalar.sksl")
SKSL_TEST(VM + GPU, kApiLevel_T, ArrayTypes, "shared/ArrayTypes.sksl")
-SKSL_TEST(VM + GPU, kApiLevel_T, Assignment, "shared/Assignment.sksl")
+SKSL_TEST(RP + VM + GPU, kApiLevel_T, Assignment, "shared/Assignment.sksl")
SKSL_TEST(RP + VM + GPU, kApiLevel_T, CastsRoundTowardZero, "shared/CastsRoundTowardZero.sksl")
SKSL_TEST(RP + VM + GPU, kApiLevel_T, CommaMixedTypes, "shared/CommaMixedTypes.sksl")
SKSL_TEST(RP + VM + GPU, kApiLevel_T, CommaSideEffects, "shared/CommaSideEffects.sksl")
diff --git a/tests/sksl/shared/Assignment.skrp b/tests/sksl/shared/Assignment.skrp
index 3ef3d71..feb42d8 100644
--- a/tests/sksl/shared/Assignment.skrp
+++ b/tests/sksl/shared/Assignment.skrp
@@ -1,4 +1,157 @@
-### Compilation failed:
-
-error: code is not supported
-1 error
+ 1. store_src_rg coords = src.rg
+ 2. init_lane_masks CondMask = LoopMask = RetMask = true
+ 3. zero_4_slots_unmasked globalVar = 0
+ 4. zero_4_slots_unmasked globalStruct.f, globalStruct.af[0], globalStruct.af[1], globalStruct.af[2] = 0
+ 5. zero_4_slots_unmasked globalStruct.af[3], globalStruct.af[4], globalStruct.h4(0..1) = 0
+ 6. zero_4_slots_unmasked globalStruct.h4(2..3), globalStruct.ah4[0](0..1) = 0
+ 7. zero_4_slots_unmasked globalStruct.ah4[0](2..3), globalStruct.ah4[1](0..1) = 0
+ 8. zero_4_slots_unmasked globalStruct.ah4[1](2..3), globalStruct.ah4[2](0..1) = 0
+ 9. zero_4_slots_unmasked globalStruct.ah4[2](2..3), globalStruct.ah4[3](0..1) = 0
+ 10. zero_4_slots_unmasked globalStruct.ah4[3](2..3), globalStruct.ah4[4](0..1) = 0
+ 11. zero_2_slots_unmasked globalStruct.ah4[4](2..3) = 0
+ 12. zero_slot_unmasked i = 0
+ 13. zero_slot_unmasked $0 = 0
+ 14. copy_slot_unmasked i = $0
+ 15. zero_4_slots_unmasked i4 = 0
+ 16. copy_constant $0 = 0x00000001 (1.401298e-45)
+ 17. copy_constant $1 = 0x00000002 (2.802597e-45)
+ 18. copy_constant $2 = 0x00000003 (4.203895e-45)
+ 19. copy_constant $3 = 0x00000004 (5.605194e-45)
+ 20. copy_4_slots_unmasked i4 = $0..3
+ 21. zero_4_slots_unmasked f3x3(0..3) = 0
+ 22. zero_4_slots_unmasked f3x3(4..7) = 0
+ 23. zero_slot_unmasked f3x3(8) = 0
+ 24. copy_constant $0 = 0x3F800000 (1.0)
+ 25. copy_constant $1 = 0x40000000 (2.0)
+ 26. copy_constant $2 = 0x40400000 (3.0)
+ 27. copy_constant $3 = 0x40800000 (4.0)
+ 28. copy_constant $4 = 0x40A00000 (5.0)
+ 29. copy_constant $5 = 0x40C00000 (6.0)
+ 30. copy_constant $6 = 0x40E00000 (7.0)
+ 31. copy_constant $7 = 0x41000000 (8.0)
+ 32. copy_constant $8 = 0x41100000 (9.0)
+ 33. copy_4_slots_unmasked f3x3(0..3) = $0..3
+ 34. copy_4_slots_unmasked f3x3(4..7) = $4..7
+ 35. copy_slot_unmasked f3x3(8) = $8
+ 36. zero_4_slots_unmasked x = 0
+ 37. zero_slot_unmasked $0 = 0
+ 38. copy_slot_unmasked x(3) = $0
+ 39. zero_2_slots_unmasked $0..1 = 0
+ 40. copy_slot_unmasked x(1) = $0
+ 41. copy_slot_unmasked x(0) = $1
+ 42. zero_slot_unmasked ai[0] = 0
+ 43. zero_slot_unmasked $0 = 0
+ 44. copy_slot_unmasked ai[0] = $0
+ 45. zero_4_slots_unmasked ai4[0] = 0
+ 46. copy_constant $0 = 0x00000001 (1.401298e-45)
+ 47. copy_constant $1 = 0x00000002 (2.802597e-45)
+ 48. copy_constant $2 = 0x00000003 (4.203895e-45)
+ 49. copy_constant $3 = 0x00000004 (5.605194e-45)
+ 50. copy_4_slots_unmasked ai4[0] = $0..3
+ 51. zero_4_slots_unmasked ah3x3[0](0..3) = 0
+ 52. zero_4_slots_unmasked ah3x3[0](4..7) = 0
+ 53. zero_slot_unmasked ah3x3[0](8) = 0
+ 54. copy_constant $0 = 0x3F800000 (1.0)
+ 55. copy_constant $1 = 0x40000000 (2.0)
+ 56. copy_constant $2 = 0x40400000 (3.0)
+ 57. copy_constant $3 = 0x40800000 (4.0)
+ 58. copy_constant $4 = 0x40A00000 (5.0)
+ 59. copy_constant $5 = 0x40C00000 (6.0)
+ 60. copy_constant $6 = 0x40E00000 (7.0)
+ 61. copy_constant $7 = 0x41000000 (8.0)
+ 62. copy_constant $8 = 0x41100000 (9.0)
+ 63. copy_4_slots_unmasked ah3x3[0](0..3) = $0..3
+ 64. copy_4_slots_unmasked ah3x3[0](4..7) = $4..7
+ 65. copy_slot_unmasked ah3x3[0](8) = $8
+ 66. zero_4_slots_unmasked af4[0] = 0
+ 67. zero_slot_unmasked $0 = 0
+ 68. copy_slot_unmasked af4[0](0) = $0
+ 69. copy_constant $0 = 0x3F800000 (1.0)
+ 70. swizzle_4 $0..3 = ($0..3).xxxx
+ 71. copy_slot_unmasked af4[0](1) = $0
+ 72. copy_slot_unmasked af4[0](3) = $1
+ 73. copy_slot_unmasked af4[0](0) = $2
+ 74. copy_slot_unmasked af4[0](2) = $3
+ 75. zero_4_slots_unmasked s.f, s.af[0], s.af[1], s.af[2] = 0
+ 76. zero_4_slots_unmasked s.af[3], s.af[4], s.h4(0..1) = 0
+ 77. zero_4_slots_unmasked s.h4(2..3), s.ah4[0](0..1) = 0
+ 78. zero_4_slots_unmasked s.ah4[0](2..3), s.ah4[1](0..1) = 0
+ 79. zero_4_slots_unmasked s.ah4[1](2..3), s.ah4[2](0..1) = 0
+ 80. zero_4_slots_unmasked s.ah4[2](2..3), s.ah4[3](0..1) = 0
+ 81. zero_4_slots_unmasked s.ah4[3](2..3), s.ah4[4](0..1) = 0
+ 82. zero_2_slots_unmasked s.ah4[4](2..3) = 0
+ 83. zero_slot_unmasked $0 = 0
+ 84. copy_slot_unmasked s.f = $0
+ 85. zero_slot_unmasked $0 = 0
+ 86. copy_slot_unmasked s.af[1] = $0
+ 87. copy_constant $0 = 0x41100000 (9.0)
+ 88. swizzle_3 $0..2 = ($0..2).xxx
+ 89. copy_slot_unmasked s.h4(2) = $0
+ 90. copy_2_slots_unmasked s.h4(0..1) = $1..2
+ 91. copy_constant $0 = 0x40A00000 (5.0)
+ 92. copy_slot_unmasked $1 = $0
+ 93. copy_slot_unmasked s.ah4[2](1) = $0
+ 94. copy_slot_unmasked s.ah4[2](3) = $1
+ 95. zero_4_slots_unmasked $0..3 = 0
+ 96. copy_4_slots_unmasked globalVar = $0..3
+ 97. zero_slot_unmasked $0 = 0
+ 98. copy_slot_unmasked globalStruct.f = $0
+ 99. zero_slot_unmasked l = 0
+ 100. zero_slot_unmasked $0 = 0
+ 101. copy_slot_unmasked l = $0
+ 102. copy_2_slots_unmasked $0..1 = ai[0], ai4[0](0)
+ 103. add_int $0 += $1
+ 104. copy_slot_unmasked ai[0] = $0
+ 105. copy_constant $0 = 0x3F800000 (1.0)
+ 106. copy_slot_unmasked s.f = $0
+ 107. copy_constant $0 = 0x40000000 (2.0)
+ 108. copy_slot_unmasked s.af[0] = $0
+ 109. copy_constant $0 = 0x3F800000 (1.0)
+ 110. swizzle_4 $0..3 = ($0..3).xxxx
+ 111. copy_4_slots_unmasked s.h4 = $0..3
+ 112. copy_constant $0 = 0x40000000 (2.0)
+ 113. swizzle_4 $0..3 = ($0..3).xxxx
+ 114. copy_4_slots_unmasked s.ah4[0] = $0..3
+ 115. copy_slot_unmasked f = af4[0](0)
+ 116. copy_slot_unmasked $0 = f
+ 117. copy_slot_unmasked af4[0](0) = $0
+ 118. label label 0x00000000
+ 119. copy_slot_unmasked h = ah3x3[0](0)
+ 120. copy_slot_unmasked $0 = h
+ 121. copy_slot_unmasked ah3x3[0](0) = $0
+ 122. label label 0x00000001
+ 123. copy_slot_unmasked i₁ = i
+ 124. copy_slot_unmasked $0 = i₁
+ 125. copy_slot_unmasked i = $0
+ 126. label label 0x00000002
+ 127. copy_slot_unmasked i₁ = i4(1)
+ 128. copy_slot_unmasked $0 = i₁
+ 129. copy_slot_unmasked i4(1) = $0
+ 130. label label 0x00000003
+ 131. copy_slot_unmasked i₁ = ai[0]
+ 132. copy_slot_unmasked $0 = i₁
+ 133. copy_slot_unmasked ai[0] = $0
+ 134. label label 0x00000004
+ 135. copy_slot_unmasked i₁ = ai4[0](0)
+ 136. copy_slot_unmasked $0 = i₁
+ 137. copy_slot_unmasked ai4[0](0) = $0
+ 138. label label 0x00000005
+ 139. copy_slot_unmasked h = x(1)
+ 140. copy_slot_unmasked $0 = h
+ 141. copy_slot_unmasked x(1) = $0
+ 142. label label 0x00000006
+ 143. copy_slot_unmasked f = s.f
+ 144. copy_slot_unmasked $0 = f
+ 145. copy_slot_unmasked s.f = $0
+ 146. label label 0x00000007
+ 147. copy_slot_unmasked h = l
+ 148. copy_slot_unmasked $0 = h
+ 149. copy_slot_unmasked l = $0
+ 150. label label 0x00000008
+ 151. copy_slot_unmasked f = f3x3(0)
+ 152. copy_slot_unmasked $0 = f
+ 153. copy_slot_unmasked f3x3(0) = $0
+ 154. label label 0x00000009
+ 155. copy_4_constants $0..3 = colorGreen
+ 156. copy_4_slots_unmasked [main].result = $0..3
+ 157. load_src src.rgba = [main].result