Implement normalize intrinsic in RP codegen.
We implement normalize as `x / length(x)`, which matches the SkVM
implementation.
A zero-length vector will return nan; the GLSL docs don't specify
what should happen in this case: http://screen/3TsNoijNDxN5xQZ
Change-Id: I4c57e54fdbc0d986bb8d1adb52ec0889f9d9846b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/657816
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
diff --git a/src/sksl/codegen/SkSLRasterPipelineBuilder.cpp b/src/sksl/codegen/SkSLRasterPipelineBuilder.cpp
index fcc5d93..45cdacd 100644
--- a/src/sksl/codegen/SkSLRasterPipelineBuilder.cpp
+++ b/src/sksl/codegen/SkSLRasterPipelineBuilder.cpp
@@ -397,7 +397,7 @@
switch (count) {
case 3: this->swizzle(/*consumedSlots=*/1, {0, 0, 0, 0}); break;
case 2: this->swizzle(/*consumedSlots=*/1, {0, 0, 0}); break;
- case 1: this->push_clone(/*numSlots=*/1); break;
+ case 1: this->push_clone(/*numSlots=*/1); break;
default: break;
}
}
diff --git a/src/sksl/codegen/SkSLRasterPipelineCodeGenerator.cpp b/src/sksl/codegen/SkSLRasterPipelineCodeGenerator.cpp
index 6df0eb4..b1dc894 100644
--- a/src/sksl/codegen/SkSLRasterPipelineCodeGenerator.cpp
+++ b/src/sksl/codegen/SkSLRasterPipelineCodeGenerator.cpp
@@ -2564,6 +2564,20 @@
return this->pushExpression(arg0) &&
this->pushLengthIntrinsic(arg0.type().slotCount());
+ case IntrinsicKind::k_normalize_IntrinsicKind:
+ // Implement normalize as `x / length(x)`. First, push the expression.
+ if (!this->pushExpression(arg0)) {
+ return unsupported();
+ }
+ // Clone the expression and calculate its length.
+ fBuilder.push_clone(arg0.type().slotCount());
+ if (!this->pushLengthIntrinsic(arg0.type().slotCount())) {
+ return unsupported();
+ }
+ // Finally, vectorize the length and divide.
+ fBuilder.push_duplicates(arg0.type().slotCount() - 1);
+ return this->binaryOp(arg0.type(), kDivideOps);
+
case IntrinsicKind::k_not_IntrinsicKind:
return this->pushPrefixExpression(OperatorKind::LOGICALNOT, arg0);
diff --git a/tests/SkSLTest.cpp b/tests/SkSLTest.cpp
index a98b1d5..e14bff1 100644
--- a/tests/SkSLTest.cpp
+++ b/tests/SkSLTest.cpp
@@ -641,7 +641,7 @@
SKSL_TEST(RP + VM + GPU, kApiLevel_T, FunctionReturnTypeMatch, "shared/FunctionReturnTypeMatch.sksl")
SKSL_TEST(RP + VM + GPU, kApiLevel_T, Functions, "shared/Functions.sksl")
SKSL_TEST(RP + VM + GPU, kApiLevel_T, FunctionPrototype, "shared/FunctionPrototype.sksl")
-SKSL_TEST(VM + GPU, kApiLevel_T, GeometricIntrinsics, "shared/GeometricIntrinsics.sksl")
+SKSL_TEST(RP + VM + GPU, kApiLevel_T, GeometricIntrinsics, "shared/GeometricIntrinsics.sksl")
SKSL_TEST(RP + VM + GPU, kApiLevel_T, HelloWorld, "shared/HelloWorld.sksl")
SKSL_TEST(RP + VM + GPU, kApiLevel_T, Hex, "shared/Hex.sksl")
SKSL_TEST(RP + GPU_ES3, kNever, HexUnsigned, "shared/HexUnsigned.sksl")
diff --git a/tests/sksl/intrinsics/Normalize.skrp b/tests/sksl/intrinsics/Normalize.skrp
index 3ef3d71..1f2faa9 100644
--- a/tests/sksl/intrinsics/Normalize.skrp
+++ b/tests/sksl/intrinsics/Normalize.skrp
@@ -1,4 +1,77 @@
-### 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. copy_constant expectedVec(0) = 0x3F800000 (1.0)
+ 4. zero_3_slots_unmasked expectedVec(1..3) = 0
+ 5. copy_constant $0 = inputVal(0)
+ 6. copy_slot_unmasked $1 = $0
+ 7. abs_float $1 = abs($1)
+ 8. div_float $0 /= $1
+ 9. copy_slot_unmasked $1 = expectedVec(0)
+ 10. cmpeq_float $0 = equal($0, $1)
+ 11. copy_2_constants $1..2 = inputVal(0..1)
+ 12. copy_2_slots_unmasked $3..4 = $1..2
+ 13. copy_2_slots_unmasked $5..6 = $3..4
+ 14. dot_2_floats $3 = dot($3..4, $5..6)
+ 15. sqrt_float $3 = sqrt($3)
+ 16. copy_slot_unmasked $4 = $3
+ 17. div_2_floats $1..2 /= $3..4
+ 18. copy_2_slots_unmasked $3..4 = expectedVec(0..1)
+ 19. cmpeq_2_floats $1..2 = equal($1..2, $3..4)
+ 20. bitwise_and_int $1 &= $2
+ 21. bitwise_and_int $0 &= $1
+ 22. copy_3_constants $1..3 = inputVal(0..2)
+ 23. copy_3_slots_unmasked $4..6 = $1..3
+ 24. copy_3_slots_unmasked $7..9 = $4..6
+ 25. dot_3_floats $4 = dot($4..6, $7..9)
+ 26. sqrt_float $4 = sqrt($4)
+ 27. swizzle_3 $4..6 = ($4..6).xxx
+ 28. div_3_floats $1..3 /= $4..6
+ 29. copy_3_slots_unmasked $4..6 = expectedVec(0..2)
+ 30. cmpeq_3_floats $1..3 = equal($1..3, $4..6)
+ 31. bitwise_and_int $2 &= $3
+ 32. bitwise_and_int $1 &= $2
+ 33. bitwise_and_int $0 &= $1
+ 34. copy_4_constants $1..4 = inputVal
+ 35. copy_4_slots_unmasked $5..8 = $1..4
+ 36. copy_4_slots_unmasked $9..12 = $5..8
+ 37. dot_4_floats $5 = dot($5..8, $9..12)
+ 38. sqrt_float $5 = sqrt($5)
+ 39. swizzle_4 $5..8 = ($5..8).xxxx
+ 40. div_4_floats $1..4 /= $5..8
+ 41. copy_4_slots_unmasked $5..8 = expectedVec
+ 42. cmpeq_4_floats $1..4 = equal($1..4, $5..8)
+ 43. bitwise_and_2_ints $1..2 &= $3..4
+ 44. bitwise_and_int $1 &= $2
+ 45. bitwise_and_int $0 &= $1
+ 46. copy_constant $1 = 0x3F800000 (1.0)
+ 47. copy_slot_unmasked $2 = expectedVec(0)
+ 48. cmpeq_float $1 = equal($1, $2)
+ 49. bitwise_and_int $0 &= $1
+ 50. zero_slot_unmasked $1 = 0
+ 51. copy_constant $2 = 0x3F800000 (1.0)
+ 52. copy_4_slots_unmasked $3..6 = expectedVec
+ 53. swizzle_2 $3..4 = ($3..4).yx
+ 54. cmpeq_2_floats $1..2 = equal($1..2, $3..4)
+ 55. bitwise_and_int $1 &= $2
+ 56. bitwise_and_int $0 &= $1
+ 57. zero_slot_unmasked $1 = 0
+ 58. copy_constant $2 = 0x3F800000 (1.0)
+ 59. zero_slot_unmasked $3 = 0
+ 60. copy_4_slots_unmasked $4..7 = expectedVec
+ 61. swizzle_3 $4..6 = ($4..6).zxy
+ 62. cmpeq_3_floats $1..3 = equal($1..3, $4..6)
+ 63. bitwise_and_int $2 &= $3
+ 64. bitwise_and_int $1 &= $2
+ 65. bitwise_and_int $0 &= $1
+ 66. copy_constant $1 = 0x3F800000 (1.0)
+ 67. zero_3_slots_unmasked $2..4 = 0
+ 68. copy_4_slots_unmasked $5..8 = expectedVec
+ 69. cmpeq_4_floats $1..4 = equal($1..4, $5..8)
+ 70. bitwise_and_2_ints $1..2 &= $3..4
+ 71. bitwise_and_int $1 &= $2
+ 72. bitwise_and_int $0 &= $1
+ 73. swizzle_4 $0..3 = ($0..3).xxxx
+ 74. copy_4_constants $4..7 = colorRed
+ 75. copy_4_constants $8..11 = colorGreen
+ 76. mix_4_ints $0..3 = mix($4..7, $8..11, $0..3)
+ 77. load_src src.rgba = $0..3
diff --git a/tests/sksl/shared/GeometricIntrinsics.skrp b/tests/sksl/shared/GeometricIntrinsics.skrp
index 3ef3d71..9b52364 100644
--- a/tests/sksl/shared/GeometricIntrinsics.skrp
+++ b/tests/sksl/shared/GeometricIntrinsics.skrp
@@ -1,4 +1,47 @@
-### 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. copy_constant _0_x = 0x3F800000 (1.0)
+ 4. copy_slot_unmasked $0 = _0_x
+ 5. abs_float $0 = abs($0)
+ 6. copy_slot_unmasked _0_x = $0
+ 7. copy_constant $1 = 0x40000000 (2.0)
+ 8. sub_float $0 -= $1
+ 9. abs_float $0 = abs($0)
+ 10. copy_slot_unmasked _0_x = $0
+ 11. copy_constant $1 = 0x40000000 (2.0)
+ 12. mul_float $0 *= $1
+ 13. copy_slot_unmasked _0_x = $0
+ 14. copy_slot_unmasked $1 = $0
+ 15. abs_float $1 = abs($1)
+ 16. div_float $0 /= $1
+ 17. copy_slot_unmasked _0_x = $0
+ 18. copy_constant _1_x(0) = 0x3F800000 (1.0)
+ 19. copy_constant _1_x(1) = 0x40000000 (2.0)
+ 20. copy_2_slots_unmasked $0..1 = _1_x
+ 21. copy_2_slots_unmasked $2..3 = $0..1
+ 22. dot_2_floats $0 = dot($0..1, $2..3)
+ 23. sqrt_float $0 = sqrt($0)
+ 24. copy_slot_unmasked $1 = $0
+ 25. copy_2_slots_unmasked _1_x = $0..1
+ 26. copy_constant $2 = 0x40400000 (3.0)
+ 27. copy_constant $3 = 0x40800000 (4.0)
+ 28. sub_2_floats $0..1 -= $2..3
+ 29. copy_2_slots_unmasked $2..3 = $0..1
+ 30. dot_2_floats $0 = dot($0..1, $2..3)
+ 31. sqrt_float $0 = sqrt($0)
+ 32. copy_slot_unmasked $1 = $0
+ 33. copy_2_slots_unmasked _1_x = $0..1
+ 34. copy_constant $2 = 0x40400000 (3.0)
+ 35. copy_constant $3 = 0x40800000 (4.0)
+ 36. dot_2_floats $0 = dot($0..1, $2..3)
+ 37. copy_slot_unmasked $1 = $0
+ 38. copy_2_slots_unmasked _1_x = $0..1
+ 39. copy_2_slots_unmasked $2..3 = $0..1
+ 40. copy_2_slots_unmasked $4..5 = $2..3
+ 41. dot_2_floats $2 = dot($2..3, $4..5)
+ 42. sqrt_float $2 = sqrt($2)
+ 43. copy_slot_unmasked $3 = $2
+ 44. div_2_floats $0..1 /= $2..3
+ 45. copy_2_slots_unmasked _1_x = $0..1
+ 46. copy_4_constants $0..3 = colorGreen
+ 47. load_src src.rgba = $0..3