diff --git a/src/cmake/testing.cmake b/src/cmake/testing.cmake index f7aced970..a2de5e315 100644 --- a/src/cmake/testing.cmake +++ b/src/cmake/testing.cmake @@ -274,7 +274,7 @@ macro (osl_add_all_tests) bug-param-duplicate bug-peep bug-return calculatenormal-reg cellnoise closure closure-array closure-layered closure-parameters closure-zero closure-conditional - color color-reg colorspace comparison + color color2 color4 color-reg colorspace comparison complement-reg compile-buffer compassign-bool compassign-reg component-range control-flow-reg connect-components @@ -402,7 +402,7 @@ macro (osl_add_all_tests) userdata userdata-defaults userdata-partial userdata-custom userdata-passthrough vararray-connect vararray-default vararray-deserialize vararray-param - vecctr vector vector-reg + vecctr vector vector2 vector4 vector-reg wavelength_color wavelength_color-reg Werror xml xml-reg ) # Only run the ocio test if the OIIO we are using has OCIO support diff --git a/src/doc/languagespec.tex b/src/doc/languagespec.tex index 7c90ed198..8f296c0f7 100644 --- a/src/doc/languagespec.tex +++ b/src/doc/languagespec.tex @@ -2759,7 +2759,7 @@ \subsection{Operator overloading} {\cf \bfseries >} & {\cf __operator__gt__} & \\ {\cf \bfseries >=} & {\cf __operator__ge__} & \\ {\cf \bfseries ==} & {\cf __operator__eq__} & \\ -{\cf \bfseries !=} & {\cf __operator__ne__} & \\[1.5ex] +{\cf \bfseries !=} & {\cf __operator__neq__} & \\[1.5ex] {\cf \bfseries \&} & {\cf __operator__bitand__} & \\ {\cf \bfseries \textasciicircum} & {\cf __operator__xor__} & \\ {\cf \bfseries |} & {\cf __operator__bitor__} & \\ diff --git a/src/doc/syntax.md b/src/doc/syntax.md index 24df8ddb6..0192e6052 100644 --- a/src/doc/syntax.md +++ b/src/doc/syntax.md @@ -518,7 +518,7 @@ Operator | Overload function name | notes `>` | `__operator__gt__` | `>=` | `__operator__ge__` | `==` | `__operator__eq__` | -`!=` | `__operator__ne__` | +`!=` | `__operator__neq__` | `\&` | `__operator__bitand__` | `^` | `__operator__xor__` | `\|` | `__operator__bitor__` | diff --git a/src/shaders/color2.h b/src/shaders/color2.h index 2f9f94192..ca7bef3c4 100644 --- a/src/shaders/color2.h +++ b/src/shaders/color2.h @@ -26,7 +26,7 @@ color2 __operator__neg__(color2 a) color2 __operator__add__(color2 a, color2 b) { - return color2(a.r + a.r, b.a + b.a); + return color2(a.r + b.r, a.a + b.a); } color2 __operator__add__(color2 a, int b) @@ -66,17 +66,17 @@ color2 __operator__sub__(color2 a, float b) color2 __operator__sub__(int a, color2 b) { - return b - color2(a, a); + return color2(a,a) - b; } color2 __operator__sub__(float a, color2 b) { - return b - color2(a, a); + return color2(a,a) - b; } color2 __operator__mul__(color2 a, color2 b) { - return color2(a.r * a.r, b.a * b.a); + return color2(a.r * b.r, a.a * b.a); } color2 __operator__mul__(color2 a, int b) @@ -106,13 +106,13 @@ color2 __operator__div__(color2 a, color2 b) color2 __operator__div__(color2 a, int b) { - float b_inv = 1/b; + float b_inv = 1.0 / float(b); return a * color2(b_inv, b_inv); } color2 __operator__div__(color2 a, float b) { - float b_inv = 1/b; + float b_inv = 1.0 / b; return a * color2(b_inv, b_inv); } @@ -128,10 +128,10 @@ color2 __operator__div__(float a, color2 b) int __operator__eq__(color2 a, color2 b) { - return (a.r == a.r) && (b.a == b.a); + return (a.r == b.r) && (a.a == b.a); } -int __operator__ne__(color2 a, color2 b) +int __operator__neq__(color2 a, color2 b) { return (a.r != b.r) || (a.a != b.a); } @@ -231,8 +231,8 @@ color2 min(color2 a, float b) color2 fmod(color2 a, color2 b) { - return color2(fmod(a.r, a.r), - fmod(b.a, b.a)); + return color2(fmod(a.r, b.r), + fmod(a.a, b.a)); } color2 fmod(color2 a, int b) @@ -303,5 +303,3 @@ color2 atan2(color2 a, color2 b) return color2(atan2(a.r, b.r), atan2(a.a, b.a)); } - - diff --git a/src/shaders/color4.h b/src/shaders/color4.h index a7ed06ba7..84610f0f1 100644 --- a/src/shaders/color4.h +++ b/src/shaders/color4.h @@ -106,13 +106,13 @@ color4 __operator__div__(color4 a, color4 b) color4 __operator__div__(color4 a, int b) { - float b_inv = 1/b; + float b_inv = 1.0 / float(b); return a * color4(color(b_inv), b_inv); } color4 __operator__div__(color4 a, float b) { - float b_inv = 1/b; + float b_inv = 1.0 / b; return a * color4(color(b_inv), b_inv); } @@ -131,7 +131,7 @@ int __operator__eq__(color4 a, color4 b) return (a.rgb == b.rgb) && (a.a == b.a); } -int __operator__ne__(color4 a, color4 b) +int __operator__neq__(color4 a, color4 b) { return (a.rgb != b.rgb) || (a.a != b.a); } @@ -183,11 +183,6 @@ color4 mix(color4 a, color4 b, float x ) mix(a.a, b.a, x)); } -float dot(color4 a, color b) -{ - return dot(a.rgb, b); -} - color4 smoothstep(color4 edge0, color4 edge1, color4 c) { return color4(smoothstep(edge0.rgb, edge1.rgb, c.rgb), diff --git a/src/shaders/matrix33.h b/src/shaders/matrix33.h index d08406495..68f0f026e 100644 --- a/src/shaders/matrix33.h +++ b/src/shaders/matrix33.h @@ -7,6 +7,9 @@ #define MATRIX33_H +// matrix33 is just a trick to make what appears to be a 3x3 matrix, but +// underneath using a native OSL (4x4) matrix with appropriate zeroed extra +// components to make the math all work out equivalently. struct matrix33 { matrix m; @@ -159,6 +162,3 @@ normal transform(matrix33 a, normal b) { return transform(a.m, b); } - - - diff --git a/src/shaders/vector2.h b/src/shaders/vector2.h index b455a2468..f57307a66 100644 --- a/src/shaders/vector2.h +++ b/src/shaders/vector2.h @@ -105,13 +105,13 @@ vector2 __operator__div__(vector2 a, vector2 b) vector2 __operator__div__(vector2 a, int b) { - float b_inv = 1/b; + float b_inv = 1.0 / float(b); return a * vector2(b_inv, b_inv); } vector2 __operator__div__(vector2 a, float b) { - float b_inv = 1/b; + float b_inv = 1.0 / b; return a * vector2(b_inv, b_inv); } @@ -130,7 +130,7 @@ int __operator__eq__(vector2 a, vector2 b) return (a.x == b.x) && (a.y == b.y); } -int __operator__ne__(vector2 a, vector2 b) +int __operator__neq__(vector2 a, vector2 b) { return (a.x != b.x) || (a.y != b.y); } @@ -221,25 +221,25 @@ vector2 max(vector2 a, vector2 b) max(a.y, b.y)); } -vector2 max(vector2 a, float b) +vector2 min(vector2 a, vector2 b) { - return max(a, vector2(b, b)); + return vector2 (min(a.x, b.x), + min(a.y, b.y)); } -vector2 normalize(vector2 a) +vector2 min(vector2 a, float b) { - return a / length(a); + return min(a, vector2(b, b)); } -vector2 min(vector2 a, vector2 b) +vector2 max(vector2 a, float b) { - return vector2 (min(a.x, a.x), - min(b.y, b.y)); + return max(a, vector2(b, b)); } -vector2 min(vector2 a, float b) +vector2 normalize(vector2 a) { - return min(a, vector2(b, b)); + return a / length(a); } vector2 mod(vector2 a, vector2 b) @@ -307,13 +307,11 @@ vector2 acos(vector2 a) vector2 atan2(vector2 a, float f) { return vector2(atan2(a.x, f), - atan2(a.y, f)); + atan2(a.y, f)); } vector2 atan2(vector2 a, vector2 b) { return vector2(atan2(a.x, b.x), - atan2(a.y, b.y)); + atan2(a.y, b.y)); } - - diff --git a/src/shaders/vector4.h b/src/shaders/vector4.h index 404d8d0eb..c30167bf9 100644 --- a/src/shaders/vector4.h +++ b/src/shaders/vector4.h @@ -108,13 +108,13 @@ vector4 __operator__div__(vector4 a, vector4 b) vector4 __operator__div__(vector4 a, int b) { - float b_inv = 1/b; + float b_inv = 1.0 / float(b); return a * vector4(b_inv, b_inv, b_inv, b_inv); } vector4 __operator__div__(vector4 a, float b) { - float b_inv = 1/b; + float b_inv = 1.0 / b; return a * vector4(b_inv, b_inv, b_inv, b_inv); } @@ -133,7 +133,7 @@ int __operator__eq__(vector4 a, vector4 b) return (a.x == b.x) && (a.y == b.y) && (a.z == b.z) && (a.w == b.w); } -int __operator__ne__(vector4 a, vector4 b) +int __operator__neq__(vector4 a, vector4 b) { return (a.x != b.x) || (a.y != b.y) || (a.z != b.z) || (a.w != b.w); } @@ -269,11 +269,6 @@ vector4 max(vector4 a, float b) return max(a, vector4(b, b, b, b)); } -vector4 normalize(vector4 a) -{ - return a / length(a); -} - vector4 min(vector4 a, vector4 b) { return vector4 (min(a.x, b.x), @@ -287,6 +282,11 @@ vector4 min(vector4 a, float b) return min(a, vector4(b, b, b, b)); } +vector4 normalize(vector4 a) +{ + return a / length(a); +} + vector4 fmod(vector4 a, vector4 b) { return vector4 (fmod(a.x, b.x), diff --git a/testsuite/color2/BATCHED b/testsuite/color2/BATCHED new file mode 100644 index 000000000..e69de29bb diff --git a/testsuite/color2/OPTIX b/testsuite/color2/OPTIX new file mode 100644 index 000000000..e69de29bb diff --git a/testsuite/color2/ref/out.txt b/testsuite/color2/ref/out.txt new file mode 100644 index 000000000..3376ac6a4 --- /dev/null +++ b/testsuite/color2/ref/out.txt @@ -0,0 +1,63 @@ +Compiled test.osl -> test.oso +parameter initialization: param1 = 0.5 1.5 +parameter initialization: param2 = 0.25 0.25 + +PASS: param1 == color2(0.5, 1.5) +PASS: -param1 == color2(-0.5, -1.5) +PASS: param1 != param2 +PASS: param1 + param2 == color2(0.75, 1.75) +PASS: param1 + 1 == color2(1.5, 2.5) +PASS: param1 + 1.0 == color2(1.5, 2.5) +PASS: 1 + param1 == color2(1.5, 2.5) +PASS: 1.0 + param1 == color2(1.5, 2.5) +PASS: param1 - param2 == color2(0.25, 1.25) +PASS: param1 - 1 == color2(-0.5, 0.5) +PASS: param1 - 1.0 == color2(-0.5, 0.5) +PASS: 1 - param1 == color2(0.5, -0.5) +PASS: 1.0 - param1 == color2(0.5, -0.5) +PASS: param1 * param2 == color2(0.125, 0.375) +PASS: param1 * 2 == color2(1.0, 3.0) +PASS: param1 * 2.0 == color2(1.0, 3.0) +PASS: 2 * param1 == color2(1.0, 3.0) +PASS: 2.0 * param1 == color2(1.0, 3.0) +PASS: param1 / param2 == color2(2.0, 6.0) +PASS: param1 / 2 == color2(0.25, 0.75) +PASS: param1 / 2.0 == color2(0.25, 0.75) +PASS: 2 / param1 == color2(4.0, 2.0/1.5) +PASS: 2.0 / param1 == color2(4.0, 2.0/1.5) +PASS: abs(color2(0.5, 1.5)) == color2(abs(xcomp(color2(0.5, 1.5))), abs(ycomp(color2(0.5, 1.5)))) +PASS: abs(color2(-0.5, -1.5)) == color2(abs(xcomp(color2(-0.5, -1.5))), abs(ycomp(color2(-0.5, -1.5)))) +PASS: ceil(color2(0.5, 1.5)) == color2(ceil(xcomp(color2(0.5, 1.5))), ceil(ycomp(color2(0.5, 1.5)))) +PASS: ceil(color2(-0.5, -1.5)) == color2(ceil(xcomp(color2(-0.5, -1.5))), ceil(ycomp(color2(-0.5, -1.5)))) +PASS: floor(color2(0.5, 1.5)) == color2(floor(xcomp(color2(0.5, 1.5))), floor(ycomp(color2(0.5, 1.5)))) +PASS: floor(color2(-0.5, -1.5)) == color2(floor(xcomp(color2(-0.5, -1.5))), floor(ycomp(color2(-0.5, -1.5)))) +PASS: sqrt(color2(0.5, 1.5)) == color2(sqrt(xcomp(color2(0.5, 1.5))), sqrt(ycomp(color2(0.5, 1.5)))) +PASS: exp(color2(0.5, 1.5)) == color2(exp(xcomp(color2(0.5, 1.5))), exp(ycomp(color2(0.5, 1.5)))) +PASS: log(color2(0.5, 1.5)) == color2(log(xcomp(color2(0.5, 1.5))), log(ycomp(color2(0.5, 1.5)))) +PASS: log2(color2(0.5, 1.5)) == color2(log2(xcomp(color2(0.5, 1.5))), log2(ycomp(color2(0.5, 1.5)))) +PASS: mix(color2(1.0, 2.0), color2(21.0, 22.0), 0.0) == color2(1.0, 2.0) +PASS: mix(color2(1.0, 2.0), color2(21.0, 22.0), 1.0) == color2(21.0, 22.0) +PASS: mix(color2(1.0, 2.0), color2(21.0, 22.0), 0.5) == color2(11.0, 12.0) +PASS: smoothstep(color2(1.0, 2.0), color2(3.0, 4.0), color2(0.0, 0.0)) == color2(0.0, 0.0) +PASS: smoothstep(color2(1.0, 2.0), color2(3.0, 4.0), color2(10.0, 10.0)) == color2(1.0, 1.0) +PASS: smoothstep(color2(1.0, 2.0), color2(3.0, 4.0), color2(2.0, 3.0)) == color2(0.5, 0.5) +PASS: clamp(color2(0.0, 0.0), color2(1.0, 2.0), color2(2.0, 3.0)) == color2(1.0, 2.0) +PASS: clamp(color2(10.0, 10.0), color2(1.0, 2.0), color2(2.0, 3.0)) == color2(2.0, 3.0) +PASS: clamp(color2(1.5, 2.5), color2(1.0, 2.0), color2(2.0, 3.0)) == color2(1.5, 2.5) +PASS: clamp(color2(0.25, 0.5), 1.0, 2.0) == color2(1.0, 1.0) +PASS: clamp(color2(2.25, 2.5), 1.0, 2.0) == color2(2.0, 2.0) +PASS: clamp(color2(1.25, 1.5), 1.0, 2.0) == color2(1.25, 1.5) +PASS: max(color2(1.0, 4.0), color2(2.0, 3.0)) == color2(2.0, 4.0) +PASS: min(color2(1.0, 4.0), color2(2.0, 3.0)) == color2(1.0, 3.0) +PASS: fmod(color2(5.0, 8.0), color2(2.0, 3.0)) == color2(fmod(xcomp(color2(5.0, 8.0)), xcomp(color2(2.0, 3.0))), fmod(ycomp(color2(5.0, 8.0)), ycomp(color2(2.0, 3.0)))) +PASS: pow(color2(2.0, 3.0), color2(2.5, 3.5)) == color2(pow(xcomp(color2(2.0, 3.0)), xcomp(color2(2.5, 3.5))), pow(ycomp(color2(2.0, 3.0)), ycomp(color2(2.5, 3.5)))) +PASS: sign(color2(0.5, -0.5)) == color2(sign(xcomp(color2(0.5, -0.5))), sign(ycomp(color2(0.5, -0.5)))) +PASS: sign(color2(-0.5, 0.5)) == color2(sign(xcomp(color2(-0.5, 0.5))), sign(ycomp(color2(-0.5, 0.5)))) +PASS: sin(color2(0.5, 1.5)) == color2(sin(xcomp(color2(0.5, 1.5))), sin(ycomp(color2(0.5, 1.5)))) +PASS: cos(color2(0.5, 1.5)) == color2(cos(xcomp(color2(0.5, 1.5))), cos(ycomp(color2(0.5, 1.5)))) +PASS: tan(color2(0.5, 1.5)) == color2(tan(xcomp(color2(0.5, 1.5))), tan(ycomp(color2(0.5, 1.5)))) +PASS: asin(color2(0.5, 0.25)) == color2(asin(xcomp(color2(0.5, 0.25))), asin(ycomp(color2(0.5, 0.25)))) +PASS: acos(color2(0.5, 0.25)) == color2(acos(xcomp(color2(0.5, 0.25))), acos(ycomp(color2(0.5, 0.25)))) +PASS: atan2(color2(0.5, 1.5), color2(1.0, 4.0)) == color2(atan2(xcomp(color2(0.5, 1.5)), xcomp(color2(1.0, 4.0))), atan2(ycomp(color2(0.5, 1.5)), ycomp(color2(1.0, 4.0)))) +PASS: atan2(color2(2.0, 0.5), 1.0) == color2(atan2(2.0, 1.0), atan2(0.5, 1.0)) + diff --git a/testsuite/color2/run.py b/testsuite/color2/run.py new file mode 100755 index 000000000..6836d5554 --- /dev/null +++ b/testsuite/color2/run.py @@ -0,0 +1,7 @@ +#!/usr/bin/env python + +# Copyright Contributors to the Open Shading Language project. +# SPDX-License-Identifier: BSD-3-Clause +# https://github.com/AcademySoftwareFoundation/OpenShadingLanguage + +command = testshade("test") diff --git a/testsuite/color2/test.osl b/testsuite/color2/test.osl new file mode 100644 index 000000000..482202722 --- /dev/null +++ b/testsuite/color2/test.osl @@ -0,0 +1,108 @@ +// Copyright Contributors to the Open Shading Language project. +// SPDX-License-Identifier: BSD-3-Clause +// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage + +#include "color2.h" +#include "../common/shaders/pretty.h" + +#define OSL_UNITTEST_VERBOSE 1 +#include "../common/shaders/osl-unittest.h" + +float xcomp(color2 v) { return v.r; } +float ycomp(color2 v) { return v.a; } + +#define TEST_UNARY_VAL(func, val) \ + OSL_CHECK_EQUAL(func(val), color2(func(xcomp(val)), func(ycomp(val)))) + +#define TEST_BINARY_VAL(func, valA, valB) \ + OSL_CHECK_EQUAL(func(valA, valB), color2(func(xcomp(valA), xcomp(valB)), \ + func(ycomp(valA), ycomp(valB)))) + +#define TEST_UNARY(func) \ + TEST_UNARY_VAL(func, color2(0.5, 1.5)) + +#define TEST_BINARY(func) \ + TEST_BINARY_VAL(func, color2(0.5, 1.5), color2(1.0, 4.0)) + + + +shader +test (color2 param1 = color2 (0.5, 1.5), + color2 param2 = color2 (0.25, 0.25) + ) +{ + printf("parameter initialization: param1 = %g %g\n", param1.r, param1.a); + printf("parameter initialization: param2 = %g %g\n", param2.r, param2.a); + printf("\n"); + + OSL_CHECK_EQUAL(param1, color2(0.5, 1.5)); + OSL_CHECK_EQUAL(-param1, color2(-0.5, -1.5)); + OSL_CHECK(param1 != param2); + + OSL_CHECK_EQUAL(param1 + param2, color2(0.75, 1.75)); + OSL_CHECK_EQUAL(param1 + 1, color2(1.5, 2.5)); + OSL_CHECK_EQUAL(param1 + 1.0, color2(1.5, 2.5)); + OSL_CHECK_EQUAL(1 + param1, color2(1.5, 2.5)); + OSL_CHECK_EQUAL(1.0 + param1, color2(1.5, 2.5)); + + OSL_CHECK_EQUAL(param1 - param2, color2(0.25, 1.25)); + OSL_CHECK_EQUAL(param1 - 1, color2(-0.5, 0.5)); + OSL_CHECK_EQUAL(param1 - 1.0, color2(-0.5, 0.5)); + OSL_CHECK_EQUAL(1 - param1, color2(0.5, -0.5)); + OSL_CHECK_EQUAL(1.0 - param1, color2(0.5, -0.5)); + + OSL_CHECK_EQUAL(param1 * param2, color2(0.125, 0.375)); + OSL_CHECK_EQUAL(param1 * 2, color2(1.0, 3.0)); + OSL_CHECK_EQUAL(param1 * 2.0, color2(1.0, 3.0)); + OSL_CHECK_EQUAL(2 * param1, color2(1.0, 3.0)); + OSL_CHECK_EQUAL(2.0 * param1, color2(1.0, 3.0)); + + OSL_CHECK_EQUAL(param1 / param2, color2(2.0, 6.0)); + OSL_CHECK_EQUAL(param1 / 2, color2(0.25, 0.75)); + OSL_CHECK_EQUAL(param1 / 2.0, color2(0.25, 0.75)); + OSL_CHECK_EQUAL(2 / param1, color2(4.0, 2.0/1.5)); + OSL_CHECK_EQUAL(2.0 / param1, color2(4.0, 2.0/1.5)); + + TEST_UNARY_VAL(abs, color2(0.5, 1.5)); + TEST_UNARY_VAL(abs, color2(-0.5, -1.5)); + TEST_UNARY_VAL(ceil, color2(0.5, 1.5)); + TEST_UNARY_VAL(ceil, color2(-0.5, -1.5)); + TEST_UNARY_VAL(floor, color2(0.5, 1.5)); + TEST_UNARY_VAL(floor, color2(-0.5, -1.5)); + + TEST_UNARY(sqrt); + TEST_UNARY(exp); + TEST_UNARY(log); + TEST_UNARY(log2); + + OSL_CHECK_EQUAL(mix(color2(1.0, 2.0), color2(21.0, 22.0), 0.0), color2(1.0, 2.0)); + OSL_CHECK_EQUAL(mix(color2(1.0, 2.0), color2(21.0, 22.0), 1.0), color2(21.0, 22.0)); + OSL_CHECK_EQUAL(mix(color2(1.0, 2.0), color2(21.0, 22.0), 0.5), color2(11.0, 12.0)); + + OSL_CHECK_EQUAL(smoothstep(color2(1.0, 2.0), color2(3.0, 4.0), color2(0.0, 0.0)), color2(0.0, 0.0)); + OSL_CHECK_EQUAL(smoothstep(color2(1.0, 2.0), color2(3.0, 4.0), color2(10.0, 10.0)), color2(1.0, 1.0)); + OSL_CHECK_EQUAL(smoothstep(color2(1.0, 2.0), color2(3.0, 4.0), color2(2.0, 3.0)), color2(0.5, 0.5)); + + OSL_CHECK_EQUAL(clamp(color2(0.0, 0.0), color2(1.0, 2.0), color2(2.0, 3.0)), color2(1.0, 2.0)); + OSL_CHECK_EQUAL(clamp(color2(10.0, 10.0), color2(1.0, 2.0), color2(2.0, 3.0)), color2(2.0, 3.0)); + OSL_CHECK_EQUAL(clamp(color2(1.5, 2.5), color2(1.0, 2.0), color2(2.0, 3.0)), color2(1.5, 2.5)); + + OSL_CHECK_EQUAL(clamp(color2(0.25, 0.5), 1.0, 2.0), color2(1.0, 1.0)); + OSL_CHECK_EQUAL(clamp(color2(2.25, 2.5), 1.0, 2.0), color2(2.0, 2.0)); + OSL_CHECK_EQUAL(clamp(color2(1.25, 1.5), 1.0, 2.0), color2(1.25, 1.5)); + + OSL_CHECK_EQUAL(max(color2(1.0, 4.0), color2(2.0, 3.0)), color2(2.0, 4.0)); + OSL_CHECK_EQUAL(min(color2(1.0, 4.0), color2(2.0, 3.0)), color2(1.0, 3.0)); + + TEST_BINARY_VAL(fmod, color2(5.0, 8.0), color2(2.0, 3.0)); + TEST_BINARY_VAL(pow, color2(2.0, 3.0), color2(2.5, 3.5)); + TEST_UNARY_VAL(sign, color2(0.5, -0.5)); + TEST_UNARY_VAL(sign, color2(-0.5, 0.5)); + TEST_UNARY(sin); + TEST_UNARY(cos); + TEST_UNARY(tan); + TEST_UNARY_VAL(asin, color2(0.5, 0.25)); + TEST_UNARY_VAL(acos, color2(0.5, 0.25)); + TEST_BINARY(atan2); + OSL_CHECK_EQUAL(atan2(color2(2.0, 0.5), 1.0), color2(atan2(2.0, 1.0), atan2(0.5, 1.0))); +} diff --git a/testsuite/color4/BATCHED b/testsuite/color4/BATCHED new file mode 100644 index 000000000..e69de29bb diff --git a/testsuite/color4/OPTIX b/testsuite/color4/OPTIX new file mode 100644 index 000000000..e69de29bb diff --git a/testsuite/color4/ref/out.txt b/testsuite/color4/ref/out.txt new file mode 100644 index 000000000..c9a9805c4 --- /dev/null +++ b/testsuite/color4/ref/out.txt @@ -0,0 +1,63 @@ +Compiled test.osl -> test.oso +parameter initialization: param1 = 0.5 1.5 2.5 3.5 +parameter initialization: param2 = 10 20 30 40 + +PASS: param1 == mkcolor4(0.5, 1.5, 2.5, 3.5) +PASS: -param1 == mkcolor4(-0.5, -1.5, -2.5, -3.5) +PASS: param1 != param2 +PASS: param1 + param2 == mkcolor4(10.5, 21.5, 32.5, 43.5) +PASS: param1 + 1 == mkcolor4(1.5, 2.5, 3.5, 4.5) +PASS: param1 + 1.0 == mkcolor4(1.5, 2.5, 3.5, 4.5) +PASS: 1 + param1 == mkcolor4(1.5, 2.5, 3.5, 4.5) +PASS: 1.0 + param1 == mkcolor4(1.5, 2.5, 3.5, 4.5) +PASS: param2 - param1 == mkcolor4(9.5, 18.5, 27.5, 36.5) +PASS: param1 - 1 == mkcolor4(-0.5, 0.5, 1.5, 2.5) +PASS: param1 - 1.0 == mkcolor4(-0.5, 0.5, 1.5, 2.5) +PASS: 1 - param1 == mkcolor4(0.5, -0.5, -1.5, -2.5) +PASS: 1.0 - param1 == mkcolor4(0.5, -0.5, -1.5, -2.5) +PASS: param1 * param2 == mkcolor4(5.0, 30.0, 75.0, 140.0) +PASS: param1 * 2 == mkcolor4(1.0, 3.0, 5.0, 7.0) +PASS: param1 * 2.0 == mkcolor4(1.0, 3.0, 5.0, 7.0) +PASS: 2 * param1 == mkcolor4(1.0, 3.0, 5.0, 7.0) +PASS: 2.0 * param1 == mkcolor4(1.0, 3.0, 5.0, 7.0) +PASS: param1 / param2 == mkcolor4(0.05, 1.5/20.0, 2.5/30.0, 3.5/40.0) +PASS: param1 / 2 == mkcolor4(0.25, 0.75, 1.25, 1.75) +PASS: param1 / 2.0 == mkcolor4(0.25, 0.75, 1.25, 1.75) +PASS: 2 / param1 == mkcolor4(4.0, 2.0/1.5, 2.0/2.5, 2.0/3.5) +PASS: 2.0 / param1 == mkcolor4(4.0, 2.0/1.5, 2.0/2.5, 2.0/3.5) +PASS: abs(mkcolor4(0.5, 1.5, 2.5, 3.5)) == mkcolor4(abs(xcomp(mkcolor4(0.5, 1.5, 2.5, 3.5))), abs(ycomp(mkcolor4(0.5, 1.5, 2.5, 3.5))), abs(zcomp(mkcolor4(0.5, 1.5, 2.5, 3.5))), abs(wcomp(mkcolor4(0.5, 1.5, 2.5, 3.5)))) +PASS: abs(mkcolor4(-0.5, -1.5, -2.5, -3.5)) == mkcolor4(abs(xcomp(mkcolor4(-0.5, -1.5, -2.5, -3.5))), abs(ycomp(mkcolor4(-0.5, -1.5, -2.5, -3.5))), abs(zcomp(mkcolor4(-0.5, -1.5, -2.5, -3.5))), abs(wcomp(mkcolor4(-0.5, -1.5, -2.5, -3.5)))) +PASS: ceil(mkcolor4(0.5, 1.5, 2.5, 3.5)) == mkcolor4(ceil(xcomp(mkcolor4(0.5, 1.5, 2.5, 3.5))), ceil(ycomp(mkcolor4(0.5, 1.5, 2.5, 3.5))), ceil(zcomp(mkcolor4(0.5, 1.5, 2.5, 3.5))), ceil(wcomp(mkcolor4(0.5, 1.5, 2.5, 3.5)))) +PASS: ceil(mkcolor4(-0.5, -1.5, -2.5, -3.5)) == mkcolor4(ceil(xcomp(mkcolor4(-0.5, -1.5, -2.5, -3.5))), ceil(ycomp(mkcolor4(-0.5, -1.5, -2.5, -3.5))), ceil(zcomp(mkcolor4(-0.5, -1.5, -2.5, -3.5))), ceil(wcomp(mkcolor4(-0.5, -1.5, -2.5, -3.5)))) +PASS: floor(mkcolor4(0.5, 1.5, 2.5, 3.5)) == mkcolor4(floor(xcomp(mkcolor4(0.5, 1.5, 2.5, 3.5))), floor(ycomp(mkcolor4(0.5, 1.5, 2.5, 3.5))), floor(zcomp(mkcolor4(0.5, 1.5, 2.5, 3.5))), floor(wcomp(mkcolor4(0.5, 1.5, 2.5, 3.5)))) +PASS: floor(mkcolor4(-0.5, -1.5, -2.5, -3.5)) == mkcolor4(floor(xcomp(mkcolor4(-0.5, -1.5, -2.5, -3.5))), floor(ycomp(mkcolor4(-0.5, -1.5, -2.5, -3.5))), floor(zcomp(mkcolor4(-0.5, -1.5, -2.5, -3.5))), floor(wcomp(mkcolor4(-0.5, -1.5, -2.5, -3.5)))) +PASS: sqrt(mkcolor4(0.5, 1.5, 2.5, 3.5)) == mkcolor4(sqrt(xcomp(mkcolor4(0.5, 1.5, 2.5, 3.5))), sqrt(ycomp(mkcolor4(0.5, 1.5, 2.5, 3.5))), sqrt(zcomp(mkcolor4(0.5, 1.5, 2.5, 3.5))), sqrt(wcomp(mkcolor4(0.5, 1.5, 2.5, 3.5)))) +PASS: exp(mkcolor4(0.5, 1.5, 2.5, 3.5)) == mkcolor4(exp(xcomp(mkcolor4(0.5, 1.5, 2.5, 3.5))), exp(ycomp(mkcolor4(0.5, 1.5, 2.5, 3.5))), exp(zcomp(mkcolor4(0.5, 1.5, 2.5, 3.5))), exp(wcomp(mkcolor4(0.5, 1.5, 2.5, 3.5)))) +PASS: log(mkcolor4(0.5, 1.5, 2.5, 3.5)) == mkcolor4(log(xcomp(mkcolor4(0.5, 1.5, 2.5, 3.5))), log(ycomp(mkcolor4(0.5, 1.5, 2.5, 3.5))), log(zcomp(mkcolor4(0.5, 1.5, 2.5, 3.5))), log(wcomp(mkcolor4(0.5, 1.5, 2.5, 3.5)))) +PASS: log2(mkcolor4(0.5, 1.5, 2.5, 3.5)) == mkcolor4(log2(xcomp(mkcolor4(0.5, 1.5, 2.5, 3.5))), log2(ycomp(mkcolor4(0.5, 1.5, 2.5, 3.5))), log2(zcomp(mkcolor4(0.5, 1.5, 2.5, 3.5))), log2(wcomp(mkcolor4(0.5, 1.5, 2.5, 3.5)))) +PASS: mix(mkcolor4(1.0, 2.0, 3.0, 4.0), mkcolor4(21.0, 22.0, 23.0, 24.0), 0.0) == mkcolor4(1.0, 2.0, 3.0, 4.0) +PASS: mix(mkcolor4(1.0, 2.0, 3.0, 4.0), mkcolor4(21.0, 22.0, 23.0, 24.0), 1.0) == mkcolor4(21.0, 22.0, 23.0, 24.0) +PASS: mix(mkcolor4(1.0, 2.0, 3.0, 4.0), mkcolor4(21.0, 22.0, 23.0, 24.0), 0.5) == mkcolor4(11.0, 12.0, 13.0, 14.0) +PASS: smoothstep(mkcolor4(1.0, 2.0, 3.0, 4.0), mkcolor4(11.0, 12.0, 13.0, 14.0), mkcolor4(0.0, 0.0, 0.0, 0.0)) == mkcolor4(0.0, 0.0, 0.0, 0.0) +PASS: smoothstep(mkcolor4(1.0, 2.0, 3.0, 4.0), mkcolor4(11.0, 12.0, 13.0, 14.0), mkcolor4(20.0, 20.0, 20.0, 20.0)) == mkcolor4(1.0, 1.0, 1.0, 1.0) +PASS: smoothstep(mkcolor4(1.0, 2.0, 3.0, 4.0), mkcolor4(11.0, 12.0, 13.0, 14.0), mkcolor4(6.0, 7.0, 8.0, 9.0)) == mkcolor4(0.5, 0.5, 0.5, 0.5) +PASS: clamp(mkcolor4(0.0, 0.0, 0.0, 0.0), mkcolor4(1.0, 2.0, 3.0, 4.0), mkcolor4(2.0, 3.0, 4.0, 5.0)) == mkcolor4(1.0, 2.0, 3.0, 4.0) +PASS: clamp(mkcolor4(10.0, 10.0, 10.0, 10.0), mkcolor4(1.0, 2.0, 3.0, 4.0), mkcolor4(2.0, 3.0, 4.0, 5.0)) == mkcolor4(2.0, 3.0, 4.0, 5.0) +PASS: clamp(mkcolor4(1.5, 2.5, 3.5, 4.5), mkcolor4(1.0, 2.0, 3.0, 4.0), mkcolor4(2.0, 3.0, 4.0, 5.0)) == mkcolor4(1.5, 2.5, 3.5, 4.5) +PASS: clamp(mkcolor4(0.25, 0.5, 0.75, 0.8), 1.0, 2.0) == mkcolor4(1.0, 1.0, 1.0, 1.0) +PASS: clamp(mkcolor4(2.25, 2.5, 3.5, 4.5), 1.0, 2.0) == mkcolor4(2.0, 2.0, 2.0, 2.0) +PASS: clamp(mkcolor4(1.25, 1.5, 1.75, 1.875), 1.0, 2.0) == mkcolor4(1.25, 1.5, 1.75, 1.875) +PASS: max(mkcolor4(1.0, 4.0, 2.0, 5.0), mkcolor4(2.0, 3.0, 3.5, 4.0)) == mkcolor4(2.0, 4.0, 3.5, 5.0) +PASS: min(mkcolor4(1.0, 4.0, 2.0, 5.0), mkcolor4(2.0, 3.0, 3.5, 4.0)) == mkcolor4(1.0, 3.0, 2.0, 4.0) +PASS: fmod(mkcolor4(5.0, 8.0, 10.0, 13.0), mkcolor4(2.0, 3.0, 4.0, 5.0)) == mkcolor4(fmod(xcomp(mkcolor4(5.0, 8.0, 10.0, 13.0)), xcomp(mkcolor4(2.0, 3.0, 4.0, 5.0))), fmod(ycomp(mkcolor4(5.0, 8.0, 10.0, 13.0)), ycomp(mkcolor4(2.0, 3.0, 4.0, 5.0))), fmod(zcomp(mkcolor4(5.0, 8.0, 10.0, 13.0)), zcomp(mkcolor4(2.0, 3.0, 4.0, 5.0))), fmod(wcomp(mkcolor4(5.0, 8.0, 10.0, 13.0)), wcomp(mkcolor4(2.0, 3.0, 4.0, 5.0)))) +PASS: pow(mkcolor4(2.0, 3.0, 4.0, 5.0), mkcolor4(-1.0, 2.0, 0.5, 3.0)) == mkcolor4(pow(xcomp(mkcolor4(2.0, 3.0, 4.0, 5.0)), xcomp(mkcolor4(-1.0, 2.0, 0.5, 3.0))), pow(ycomp(mkcolor4(2.0, 3.0, 4.0, 5.0)), ycomp(mkcolor4(-1.0, 2.0, 0.5, 3.0))), pow(zcomp(mkcolor4(2.0, 3.0, 4.0, 5.0)), zcomp(mkcolor4(-1.0, 2.0, 0.5, 3.0))), pow(wcomp(mkcolor4(2.0, 3.0, 4.0, 5.0)), wcomp(mkcolor4(-1.0, 2.0, 0.5, 3.0)))) +PASS: sign(mkcolor4(0.5, -0.6, 0.7, -0.8)) == mkcolor4(sign(xcomp(mkcolor4(0.5, -0.6, 0.7, -0.8))), sign(ycomp(mkcolor4(0.5, -0.6, 0.7, -0.8))), sign(zcomp(mkcolor4(0.5, -0.6, 0.7, -0.8))), sign(wcomp(mkcolor4(0.5, -0.6, 0.7, -0.8)))) +PASS: sign(mkcolor4(-0.5, 0.6, -0.7, 0.8)) == mkcolor4(sign(xcomp(mkcolor4(-0.5, 0.6, -0.7, 0.8))), sign(ycomp(mkcolor4(-0.5, 0.6, -0.7, 0.8))), sign(zcomp(mkcolor4(-0.5, 0.6, -0.7, 0.8))), sign(wcomp(mkcolor4(-0.5, 0.6, -0.7, 0.8)))) +PASS: sin(mkcolor4(0.5, 1.5, 2.5, 3.5)) == mkcolor4(sin(xcomp(mkcolor4(0.5, 1.5, 2.5, 3.5))), sin(ycomp(mkcolor4(0.5, 1.5, 2.5, 3.5))), sin(zcomp(mkcolor4(0.5, 1.5, 2.5, 3.5))), sin(wcomp(mkcolor4(0.5, 1.5, 2.5, 3.5)))) +PASS: cos(mkcolor4(0.5, 1.5, 2.5, 3.5)) == mkcolor4(cos(xcomp(mkcolor4(0.5, 1.5, 2.5, 3.5))), cos(ycomp(mkcolor4(0.5, 1.5, 2.5, 3.5))), cos(zcomp(mkcolor4(0.5, 1.5, 2.5, 3.5))), cos(wcomp(mkcolor4(0.5, 1.5, 2.5, 3.5)))) +PASS: tan(mkcolor4(0.5, 1.5, 2.5, 3.5)) == mkcolor4(tan(xcomp(mkcolor4(0.5, 1.5, 2.5, 3.5))), tan(ycomp(mkcolor4(0.5, 1.5, 2.5, 3.5))), tan(zcomp(mkcolor4(0.5, 1.5, 2.5, 3.5))), tan(wcomp(mkcolor4(0.5, 1.5, 2.5, 3.5)))) +PASS: asin(mkcolor4(0.5, 0.25, 0.75, 0.125)) == mkcolor4(asin(xcomp(mkcolor4(0.5, 0.25, 0.75, 0.125))), asin(ycomp(mkcolor4(0.5, 0.25, 0.75, 0.125))), asin(zcomp(mkcolor4(0.5, 0.25, 0.75, 0.125))), asin(wcomp(mkcolor4(0.5, 0.25, 0.75, 0.125)))) +PASS: acos(mkcolor4(0.5, 0.25, 0.75, 0.125)) == mkcolor4(acos(xcomp(mkcolor4(0.5, 0.25, 0.75, 0.125))), acos(ycomp(mkcolor4(0.5, 0.25, 0.75, 0.125))), acos(zcomp(mkcolor4(0.5, 0.25, 0.75, 0.125))), acos(wcomp(mkcolor4(0.5, 0.25, 0.75, 0.125)))) +PASS: atan2(mkcolor4(0.5, 1.5, 2.5, 3.5), mkcolor4(10.0, 20.0, 30.0, 40.0)) == mkcolor4(atan2(xcomp(mkcolor4(0.5, 1.5, 2.5, 3.5)), xcomp(mkcolor4(10.0, 20.0, 30.0, 40.0))), atan2(ycomp(mkcolor4(0.5, 1.5, 2.5, 3.5)), ycomp(mkcolor4(10.0, 20.0, 30.0, 40.0))), atan2(zcomp(mkcolor4(0.5, 1.5, 2.5, 3.5)), zcomp(mkcolor4(10.0, 20.0, 30.0, 40.0))), atan2(wcomp(mkcolor4(0.5, 1.5, 2.5, 3.5)), wcomp(mkcolor4(10.0, 20.0, 30.0, 40.0)))) +PASS: atan2(mkcolor4(2.0, 0.5, 1.0, 0.25), 1.0) == mkcolor4(atan2(2.0, 1.0), atan2(0.5, 1.0), atan2(1.0, 1.0), atan2(0.25, 1.0)) + diff --git a/testsuite/color4/run.py b/testsuite/color4/run.py new file mode 100755 index 000000000..6836d5554 --- /dev/null +++ b/testsuite/color4/run.py @@ -0,0 +1,7 @@ +#!/usr/bin/env python + +# Copyright Contributors to the Open Shading Language project. +# SPDX-License-Identifier: BSD-3-Clause +# https://github.com/AcademySoftwareFoundation/OpenShadingLanguage + +command = testshade("test") diff --git a/testsuite/color4/test.osl b/testsuite/color4/test.osl new file mode 100644 index 000000000..747def9c6 --- /dev/null +++ b/testsuite/color4/test.osl @@ -0,0 +1,122 @@ +// Copyright Contributors to the Open Shading Language project. +// SPDX-License-Identifier: BSD-3-Clause +// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage + +#include "color4.h" +#include "../common/shaders/pretty.h" + +#define OSL_UNITTEST_VERBOSE 1 +#include "../common/shaders/osl-unittest.h" + +color4 mkcolor4(float x, float y, float z, float w) { + return color4(color(x, y, z), w); +} + +float xcomp(color4 v) { return v.rgb.r; } +float ycomp(color4 v) { return v.rgb.g; } +float zcomp(color4 v) { return v.rgb.b; } +float wcomp(color4 v) { return v.a; } + +#define TEST_UNARY_VAL(func, val) \ + OSL_CHECK_EQUAL(func(val), mkcolor4(func(xcomp(val)), func(ycomp(val)), \ + func(zcomp(val)), func(wcomp(val)))) + +#define TEST_BINARY_VAL(func, valA, valB) \ + OSL_CHECK_EQUAL(func(valA, valB), \ + mkcolor4(func(xcomp(valA), xcomp(valB)), \ + func(ycomp(valA), ycomp(valB)), \ + func(zcomp(valA), zcomp(valB)), \ + func(wcomp(valA), wcomp(valB)))) + +#define TEST_UNARY(func) \ + TEST_UNARY_VAL(func, mkcolor4(0.5, 1.5, 2.5, 3.5)) + +#define TEST_BINARY(func) \ + TEST_BINARY_VAL(func, mkcolor4(0.5, 1.5, 2.5, 3.5), \ + mkcolor4(10.0, 20.0, 30.0, 40.0)) + + + +shader +test (color4 param1 = color4 ({0.5, 1.5, 2.5}, 3.5), + color4 param2 = color4 ({10.0, 20.0, 30.0}, 40.0) + ) +{ + printf("parameter initialization: param1 = %s\n", tostring(param1)); + printf("parameter initialization: param2 = %s\n", tostring(param2)); + printf("\n"); + + OSL_CHECK_EQUAL(param1, mkcolor4(0.5, 1.5, 2.5, 3.5)); + OSL_CHECK_EQUAL(-param1, mkcolor4(-0.5, -1.5, -2.5, -3.5)); + OSL_CHECK(param1 != param2); + + OSL_CHECK_EQUAL(param1 + param2, mkcolor4(10.5, 21.5, 32.5, 43.5)); + OSL_CHECK_EQUAL(param1 + 1, mkcolor4(1.5, 2.5, 3.5, 4.5)); + OSL_CHECK_EQUAL(param1 + 1.0, mkcolor4(1.5, 2.5, 3.5, 4.5)); + OSL_CHECK_EQUAL(1 + param1, mkcolor4(1.5, 2.5, 3.5, 4.5)); + OSL_CHECK_EQUAL(1.0 + param1, mkcolor4(1.5, 2.5, 3.5, 4.5)); + + OSL_CHECK_EQUAL(param2 - param1, mkcolor4(9.5, 18.5, 27.5, 36.5)); + OSL_CHECK_EQUAL(param1 - 1, mkcolor4(-0.5, 0.5, 1.5, 2.5)); + OSL_CHECK_EQUAL(param1 - 1.0, mkcolor4(-0.5, 0.5, 1.5, 2.5)); + OSL_CHECK_EQUAL(1 - param1, mkcolor4(0.5, -0.5, -1.5, -2.5)); + OSL_CHECK_EQUAL(1.0 - param1, mkcolor4(0.5, -0.5, -1.5, -2.5)); + + OSL_CHECK_EQUAL(param1 * param2, mkcolor4(5.0, 30.0, 75.0, 140.0)); + OSL_CHECK_EQUAL(param1 * 2, mkcolor4(1.0, 3.0, 5.0, 7.0)); + OSL_CHECK_EQUAL(param1 * 2.0, mkcolor4(1.0, 3.0, 5.0, 7.0)); + OSL_CHECK_EQUAL(2 * param1, mkcolor4(1.0, 3.0, 5.0, 7.0)); + OSL_CHECK_EQUAL(2.0 * param1, mkcolor4(1.0, 3.0, 5.0, 7.0)); + + OSL_CHECK_EQUAL(param1 / param2, mkcolor4(0.05, 1.5/20.0, 2.5/30.0, 3.5/40.0)); + OSL_CHECK_EQUAL(param1 / 2, mkcolor4(0.25, 0.75, 1.25, 1.75)); + OSL_CHECK_EQUAL(param1 / 2.0, mkcolor4(0.25, 0.75, 1.25, 1.75)); + OSL_CHECK_EQUAL(2 / param1, mkcolor4(4.0, 2.0/1.5, 2.0/2.5, 2.0/3.5)); + OSL_CHECK_EQUAL(2.0 / param1, mkcolor4(4.0, 2.0/1.5, 2.0/2.5, 2.0/3.5)); + + TEST_UNARY_VAL(abs, mkcolor4(0.5, 1.5, 2.5, 3.5)); + TEST_UNARY_VAL(abs, mkcolor4(-0.5, -1.5, -2.5, -3.5)); + TEST_UNARY_VAL(ceil, mkcolor4(0.5, 1.5, 2.5, 3.5)); + TEST_UNARY_VAL(ceil, mkcolor4(-0.5, -1.5, -2.5, -3.5)); + TEST_UNARY_VAL(floor, mkcolor4(0.5, 1.5, 2.5, 3.5)); + TEST_UNARY_VAL(floor, mkcolor4(-0.5, -1.5, -2.5, -3.5)); + + TEST_UNARY(sqrt); + TEST_UNARY(exp); + TEST_UNARY(log); + TEST_UNARY(log2); + + OSL_CHECK_EQUAL(mix(mkcolor4(1.0, 2.0, 3.0, 4.0), mkcolor4(21.0, 22.0, 23.0, 24.0), 0.0), mkcolor4(1.0, 2.0, 3.0, 4.0)); + OSL_CHECK_EQUAL(mix(mkcolor4(1.0, 2.0, 3.0, 4.0), mkcolor4(21.0, 22.0, 23.0, 24.0), 1.0), mkcolor4(21.0, 22.0, 23.0, 24.0)); + OSL_CHECK_EQUAL(mix(mkcolor4(1.0, 2.0, 3.0, 4.0), mkcolor4(21.0, 22.0, 23.0, 24.0), 0.5), mkcolor4(11.0, 12.0, 13.0, 14.0)); + + OSL_CHECK_EQUAL(smoothstep(mkcolor4(1.0, 2.0, 3.0, 4.0), mkcolor4(11.0, 12.0, 13.0, 14.0), mkcolor4(0.0, 0.0, 0.0, 0.0)), mkcolor4(0.0, 0.0, 0.0, 0.0)); + OSL_CHECK_EQUAL(smoothstep(mkcolor4(1.0, 2.0, 3.0, 4.0), mkcolor4(11.0, 12.0, 13.0, 14.0), mkcolor4(20.0, 20.0, 20.0, 20.0)), mkcolor4(1.0, 1.0, 1.0, 1.0)); + OSL_CHECK_EQUAL(smoothstep(mkcolor4(1.0, 2.0, 3.0, 4.0), mkcolor4(11.0, 12.0, 13.0, 14.0), mkcolor4(6.0, 7.0, 8.0, 9.0)), mkcolor4(0.5, 0.5, 0.5, 0.5)); + + OSL_CHECK_EQUAL(clamp(mkcolor4(0.0, 0.0, 0.0, 0.0), mkcolor4(1.0, 2.0, 3.0, 4.0), mkcolor4(2.0, 3.0, 4.0, 5.0)), mkcolor4(1.0, 2.0, 3.0, 4.0)); + OSL_CHECK_EQUAL(clamp(mkcolor4(10.0, 10.0, 10.0, 10.0), mkcolor4(1.0, 2.0, 3.0, 4.0), mkcolor4(2.0, 3.0, 4.0, 5.0)), mkcolor4(2.0, 3.0, 4.0, 5.0)); + OSL_CHECK_EQUAL(clamp(mkcolor4(1.5, 2.5, 3.5, 4.5), mkcolor4(1.0, 2.0, 3.0, 4.0), mkcolor4(2.0, 3.0, 4.0, 5.0)), mkcolor4(1.5, 2.5, 3.5, 4.5)); + + OSL_CHECK_EQUAL(clamp(mkcolor4(0.25, 0.5, 0.75, 0.8), 1.0, 2.0), mkcolor4(1.0, 1.0, 1.0, 1.0)); + OSL_CHECK_EQUAL(clamp(mkcolor4(2.25, 2.5, 3.5, 4.5), 1.0, 2.0), mkcolor4(2.0, 2.0, 2.0, 2.0)); + OSL_CHECK_EQUAL(clamp(mkcolor4(1.25, 1.5, 1.75, 1.875), 1.0, 2.0), mkcolor4(1.25, 1.5, 1.75, 1.875)); + + OSL_CHECK_EQUAL(max(mkcolor4(1.0, 4.0, 2.0, 5.0), mkcolor4(2.0, 3.0, 3.5, 4.0)), mkcolor4(2.0, 4.0, 3.5, 5.0)); + OSL_CHECK_EQUAL(min(mkcolor4(1.0, 4.0, 2.0, 5.0), mkcolor4(2.0, 3.0, 3.5, 4.0)), mkcolor4(1.0, 3.0, 2.0, 4.0)); + + TEST_BINARY_VAL(fmod, mkcolor4(5.0, 8.0, 10.0, 13.0), + mkcolor4(2.0, 3.0, 4.0, 5.0)); + TEST_BINARY_VAL(pow, mkcolor4(2.0, 3.0, 4.0, 5.0), mkcolor4(-1.0, 2.0, 0.5, 3.0)); + TEST_UNARY_VAL(sign, mkcolor4(0.5, -0.6, 0.7, -0.8)); + TEST_UNARY_VAL(sign, mkcolor4(-0.5, 0.6, -0.7, 0.8)); + TEST_UNARY(sin); + TEST_UNARY(cos); + TEST_UNARY(tan); + TEST_UNARY_VAL(asin, mkcolor4(0.5, 0.25, 0.75, 0.125)); + TEST_UNARY_VAL(acos, mkcolor4(0.5, 0.25, 0.75, 0.125)); + TEST_BINARY(atan2); + OSL_CHECK_EQUAL(atan2(mkcolor4(2.0, 0.5, 1.0, 0.25), 1.0), + mkcolor4(atan2(2.0, 1.0), atan2(0.5, 1.0), + atan2(1.0, 1.0), atan2(0.25, 1.0))); +} diff --git a/testsuite/common/shaders/osl-unittest.h b/testsuite/common/shaders/osl-unittest.h new file mode 100644 index 000000000..32ebff2c1 --- /dev/null +++ b/testsuite/common/shaders/osl-unittest.h @@ -0,0 +1,95 @@ +// Copyright Contributors to the Open Shading Language project. +// SPDX-License-Identifier: BSD-3-Clause +// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage + +#pragma once +#define OSL_UNITTEST_H + +// If OSL_UNITTEST_VERBOSE is defined to nonzero, then *passing* CHECK tests +// will echo a pass message. The default is for passing tests to be silent. +// You can override this (i.e. printing a message for each passed check) by +// defining OSL_UNITTEST_VERBOSE prior to including osl-unittest.h. +#ifndef OSL_UNITTEST_VERBOSE +# define OSL_UNITTEST_VERBOSE 0 +#endif + +// If OSL_UNITTEST_EXIT_ON_FAILURE is defined to nonzero, then failing CHECK +// tests will exit the entire shader. This is the default behavior. You can +// override this (i.e., print the failure message but continue running the +// rest of the shader) by defining OSL_UNITTEST_EXIT_ON_FAILURE prior to +// including osl-unittest.h. +#ifndef OSL_UNITTEST_EXIT_ON_FAILURE +# define OSL_UNITTEST_EXIT_ON_FAILURE 1 +#endif + + +string tostring(int x) { return format("%d", x); } +string tostring(float x) { return format("%g", x); } +string tostring(color x) { return format("%g", x); } +string tostring(point x) { return format("%g", x); } +string tostring(vector x) { return format("%g", x); } +string tostring(normal x) { return format("%g", x); } +string tostring(string x) { return x; } + +#ifdef COLOR2_H +string tostring(color2 x) { return format("%g %g", x.r, x.a); } +#endif + +#ifdef COLOR4_H +string tostring(color4 x) +{ + return format("%g %g %g %g", x.rgb.r, x.rgb.g, x.rgb.b, x.a); +} +#endif + +#ifdef VECTOR2_H +string tostring(vector2 x) { return format("%g %g", x.x, x.y); } +#endif + +#ifdef VECTOR4_H +string tostring(vector4 x) +{ + return format("%g %g %g %g", x.x, x.y, x.z, x.w); +} +#endif + + +// Macros to test conditions in shaders. +// +// A success by default will just silently move on, but if the symbol +// OSL_UNITTEST_VERBOSE is defined to be nonzero before this header is +// included, then it will print a "PASS" message. +// +// For a failure, a readable message is printed pinpointing the shader file +// and line and the expression that failed. Unless the shader defines +// OSL_UNITTEST_EXIT_ON_FAILURE to 0 before this header is included, a failure +// will exit the test shader after printing the error. + +// Check that expression x is true/nonzero. +#define OSL_CHECK(x) \ + do { \ + if ((x)) { \ + if (OSL_UNITTEST_VERBOSE) \ + printf("PASS: %s\n", #x); \ + } else { \ + printf("\nFAIL: %s:%d: %s\n\n", __FILE__, __LINE__, #x); \ + if (OSL_UNITTEST_EXIT_ON_FAILURE) \ + exit(); \ + } \ + } while (0) + + +// Check that two expressions are equal. For non-built-in types, this +// requires that a tostring() function is defined for that type. +#define OSL_CHECK_EQUAL(x,y) \ + do { \ + if ((x) == (y)) { \ + if (OSL_UNITTEST_VERBOSE) \ + printf("PASS: %s == %s\n", #x, #y); \ + } else { \ + printf("\nFAIL: %s:%d: %s (%s) == %s (%s)\n\n", \ + __FILE__, __LINE__, #x, tostring(x), #y, tostring(y)); \ + if (OSL_UNITTEST_EXIT_ON_FAILURE) \ + exit(); \ + } \ + } while (0) diff --git a/testsuite/common/shaders/pretty.h b/testsuite/common/shaders/pretty.h index 803ec4662..f20fe6fa1 100644 --- a/testsuite/common/shaders/pretty.h +++ b/testsuite/common/shaders/pretty.h @@ -2,6 +2,9 @@ // SPDX-License-Identifier: BSD-3-Clause // https://github.com/AcademySoftwareFoundation/OpenShadingLanguage +#pragma once +#define PRETTY_H + // pretty(x) rounds very small values to zero and turns -0 values into +0. // This is useful for testsuite to eliminate some pesky LSB errors that diff --git a/testsuite/vector2/BATCHED b/testsuite/vector2/BATCHED new file mode 100644 index 000000000..e69de29bb diff --git a/testsuite/vector2/OPTIX b/testsuite/vector2/OPTIX new file mode 100644 index 000000000..e69de29bb diff --git a/testsuite/vector2/ref/out.txt b/testsuite/vector2/ref/out.txt new file mode 100644 index 000000000..1ffe224ba --- /dev/null +++ b/testsuite/vector2/ref/out.txt @@ -0,0 +1,66 @@ +Compiled test.osl -> test.oso +parameter initialization: param1 = 0.5 1.5 +parameter initialization: param2 = 0.25 0.25 + +PASS: param1 == vector2(0.5, 1.5) +PASS: -param1 == vector2(-0.5, -1.5) +PASS: param1 != param2 +PASS: param1 + param2 == vector2(0.75, 1.75) +PASS: param1 + 1 == vector2(1.5, 2.5) +PASS: param1 + 1.0 == vector2(1.5, 2.5) +PASS: 1 + param1 == vector2(1.5, 2.5) +PASS: 1.0 + param1 == vector2(1.5, 2.5) +PASS: param1 - param2 == vector2(0.25, 1.25) +PASS: param1 - 1 == vector2(-0.5, 0.5) +PASS: param1 - 1.0 == vector2(-0.5, 0.5) +PASS: 1 - param1 == vector2(0.5, -0.5) +PASS: 1.0 - param1 == vector2(0.5, -0.5) +PASS: param1 * param2 == vector2(0.125, 0.375) +PASS: param1 * 2 == vector2(1.0, 3.0) +PASS: param1 * 2.0 == vector2(1.0, 3.0) +PASS: 2 * param1 == vector2(1.0, 3.0) +PASS: 2.0 * param1 == vector2(1.0, 3.0) +PASS: param1 / param2 == vector2(2.0, 6.0) +PASS: param1 / 2 == vector2(0.25, 0.75) +PASS: param1 / 2.0 == vector2(0.25, 0.75) +PASS: 2 / param1 == vector2(4.0, 2.0/1.5) +PASS: 2.0 / param1 == vector2(4.0, 2.0/1.5) +PASS: abs(vector2(0.5, 1.5)) == vector2(abs(xcomp(vector2(0.5, 1.5))), abs(ycomp(vector2(0.5, 1.5)))) +PASS: abs(vector2(-0.5, -1.5)) == vector2(abs(xcomp(vector2(-0.5, -1.5))), abs(ycomp(vector2(-0.5, -1.5)))) +PASS: ceil(vector2(0.5, 1.5)) == vector2(ceil(xcomp(vector2(0.5, 1.5))), ceil(ycomp(vector2(0.5, 1.5)))) +PASS: ceil(vector2(-0.5, -1.5)) == vector2(ceil(xcomp(vector2(-0.5, -1.5))), ceil(ycomp(vector2(-0.5, -1.5)))) +PASS: floor(vector2(0.5, 1.5)) == vector2(floor(xcomp(vector2(0.5, 1.5))), floor(ycomp(vector2(0.5, 1.5)))) +PASS: floor(vector2(-0.5, -1.5)) == vector2(floor(xcomp(vector2(-0.5, -1.5))), floor(ycomp(vector2(-0.5, -1.5)))) +PASS: sqrt(vector2(0.5, 1.5)) == vector2(sqrt(xcomp(vector2(0.5, 1.5))), sqrt(ycomp(vector2(0.5, 1.5)))) +PASS: exp(vector2(0.5, 1.5)) == vector2(exp(xcomp(vector2(0.5, 1.5))), exp(ycomp(vector2(0.5, 1.5)))) +PASS: log(vector2(0.5, 1.5)) == vector2(log(xcomp(vector2(0.5, 1.5))), log(ycomp(vector2(0.5, 1.5)))) +PASS: log2(vector2(0.5, 1.5)) == vector2(log2(xcomp(vector2(0.5, 1.5))), log2(ycomp(vector2(0.5, 1.5)))) +PASS: mix(vector2(1.0, 2.0), vector2(21.0, 22.0), 0.0) == vector2(1.0, 2.0) +PASS: mix(vector2(1.0, 2.0), vector2(21.0, 22.0), 1.0) == vector2(21.0, 22.0) +PASS: mix(vector2(1.0, 2.0), vector2(21.0, 22.0), 0.5) == vector2(11.0, 12.0) +PASS: dot(vector2(1.0, 2.0), vector2(3.0, 4.0)) == 11.0 +PASS: length(vector2(3.0, 4.0)) == 5.0 +PASS: smoothstep(vector2(1.0, 2.0), vector2(3.0, 4.0), vector2(0.0, 0.0)) == vector2(0.0, 0.0) +PASS: smoothstep(vector2(1.0, 2.0), vector2(3.0, 4.0), vector2(10.0, 10.0)) == vector2(1.0, 1.0) +PASS: smoothstep(vector2(1.0, 2.0), vector2(3.0, 4.0), vector2(2.0, 3.0)) == vector2(0.5, 0.5) +PASS: clamp(vector2(0.0, 0.0), vector2(1.0, 2.0), vector2(2.0, 3.0)) == vector2(1.0, 2.0) +PASS: clamp(vector2(10.0, 10.0), vector2(1.0, 2.0), vector2(2.0, 3.0)) == vector2(2.0, 3.0) +PASS: clamp(vector2(1.5, 2.5), vector2(1.0, 2.0), vector2(2.0, 3.0)) == vector2(1.5, 2.5) +PASS: clamp(vector2(0.25, 0.5), 1.0, 2.0) == vector2(1.0, 1.0) +PASS: clamp(vector2(2.25, 2.5), 1.0, 2.0) == vector2(2.0, 2.0) +PASS: clamp(vector2(1.25, 1.5), 1.0, 2.0) == vector2(1.25, 1.5) +PASS: max(vector2(1.0, 4.0), vector2(2.0, 3.0)) == vector2(2.0, 4.0) +PASS: min(vector2(1.0, 4.0), vector2(2.0, 3.0)) == vector2(1.0, 3.0) +PASS: normalize(vector2(1.0, -1.0)) == vector2(sqrt(2.0)/2, -sqrt(2.0)/2) +PASS: fmod(vector2(5.0, 8.0), vector2(2.0, 3.0)) == vector2(fmod(xcomp(vector2(5.0, 8.0)), xcomp(vector2(2.0, 3.0))), fmod(ycomp(vector2(5.0, 8.0)), ycomp(vector2(2.0, 3.0)))) +PASS: pow(vector2(2.0, 3.0), vector2(2.5, 3.5)) == vector2(pow(xcomp(vector2(2.0, 3.0)), xcomp(vector2(2.5, 3.5))), pow(ycomp(vector2(2.0, 3.0)), ycomp(vector2(2.5, 3.5)))) +PASS: sign(vector2(0.5, -0.5)) == vector2(sign(xcomp(vector2(0.5, -0.5))), sign(ycomp(vector2(0.5, -0.5)))) +PASS: sign(vector2(-0.5, 0.5)) == vector2(sign(xcomp(vector2(-0.5, 0.5))), sign(ycomp(vector2(-0.5, 0.5)))) +PASS: sin(vector2(0.5, 1.5)) == vector2(sin(xcomp(vector2(0.5, 1.5))), sin(ycomp(vector2(0.5, 1.5)))) +PASS: cos(vector2(0.5, 1.5)) == vector2(cos(xcomp(vector2(0.5, 1.5))), cos(ycomp(vector2(0.5, 1.5)))) +PASS: tan(vector2(0.5, 1.5)) == vector2(tan(xcomp(vector2(0.5, 1.5))), tan(ycomp(vector2(0.5, 1.5)))) +PASS: asin(vector2(0.5, 0.25)) == vector2(asin(xcomp(vector2(0.5, 0.25))), asin(ycomp(vector2(0.5, 0.25)))) +PASS: acos(vector2(0.5, 0.25)) == vector2(acos(xcomp(vector2(0.5, 0.25))), acos(ycomp(vector2(0.5, 0.25)))) +PASS: atan2(vector2(0.5, 1.5), vector2(1.0, 4.0)) == vector2(atan2(xcomp(vector2(0.5, 1.5)), xcomp(vector2(1.0, 4.0))), atan2(ycomp(vector2(0.5, 1.5)), ycomp(vector2(1.0, 4.0)))) +PASS: atan2(vector2(2.0, 0.5), 1.0) == vector2(atan2(2.0, 1.0), atan2(0.5, 1.0)) + diff --git a/testsuite/vector2/run.py b/testsuite/vector2/run.py new file mode 100755 index 000000000..6836d5554 --- /dev/null +++ b/testsuite/vector2/run.py @@ -0,0 +1,7 @@ +#!/usr/bin/env python + +# Copyright Contributors to the Open Shading Language project. +# SPDX-License-Identifier: BSD-3-Clause +# https://github.com/AcademySoftwareFoundation/OpenShadingLanguage + +command = testshade("test") diff --git a/testsuite/vector2/test.osl b/testsuite/vector2/test.osl new file mode 100644 index 000000000..11f3ca94d --- /dev/null +++ b/testsuite/vector2/test.osl @@ -0,0 +1,113 @@ +// Copyright Contributors to the Open Shading Language project. +// SPDX-License-Identifier: BSD-3-Clause +// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage + +#include "vector2.h" +#include "../common/shaders/pretty.h" + +#define OSL_UNITTEST_VERBOSE 1 +#include "../common/shaders/osl-unittest.h" + +float xcomp(vector2 v) { return v.x; } +float ycomp(vector2 v) { return v.y; } + +#define TEST_UNARY_VAL(func, val) \ + OSL_CHECK_EQUAL(func(val), vector2(func(xcomp(val)), func(ycomp(val)))) + +#define TEST_BINARY_VAL(func, valA, valB) \ + OSL_CHECK_EQUAL(func(valA, valB), vector2(func(xcomp(valA), xcomp(valB)), \ + func(ycomp(valA), ycomp(valB)))) + +#define TEST_UNARY(func) \ + TEST_UNARY_VAL(func, vector2(0.5, 1.5)) + +#define TEST_BINARY(func) \ + TEST_BINARY_VAL(func, vector2(0.5, 1.5), vector2(1.0, 4.0)) + + + +shader +test (vector2 param1 = vector2 (0.5, 1.5), + vector2 param2 = vector2 (0.25, 0.25) + ) +{ + printf("parameter initialization: param1 = %g %g\n", param1.x, param1.y); + printf("parameter initialization: param2 = %g %g\n", param2.x, param2.y); + printf("\n"); + + OSL_CHECK_EQUAL(param1, vector2(0.5, 1.5)); + OSL_CHECK_EQUAL(-param1, vector2(-0.5, -1.5)); + OSL_CHECK(param1 != param2); + + OSL_CHECK_EQUAL(param1 + param2, vector2(0.75, 1.75)); + OSL_CHECK_EQUAL(param1 + 1, vector2(1.5, 2.5)); + OSL_CHECK_EQUAL(param1 + 1.0, vector2(1.5, 2.5)); + OSL_CHECK_EQUAL(1 + param1, vector2(1.5, 2.5)); + OSL_CHECK_EQUAL(1.0 + param1, vector2(1.5, 2.5)); + + OSL_CHECK_EQUAL(param1 - param2, vector2(0.25, 1.25)); + OSL_CHECK_EQUAL(param1 - 1, vector2(-0.5, 0.5)); + OSL_CHECK_EQUAL(param1 - 1.0, vector2(-0.5, 0.5)); + OSL_CHECK_EQUAL(1 - param1, vector2(0.5, -0.5)); + OSL_CHECK_EQUAL(1.0 - param1, vector2(0.5, -0.5)); + + OSL_CHECK_EQUAL(param1 * param2, vector2(0.125, 0.375)); + OSL_CHECK_EQUAL(param1 * 2, vector2(1.0, 3.0)); + OSL_CHECK_EQUAL(param1 * 2.0, vector2(1.0, 3.0)); + OSL_CHECK_EQUAL(2 * param1, vector2(1.0, 3.0)); + OSL_CHECK_EQUAL(2.0 * param1, vector2(1.0, 3.0)); + + OSL_CHECK_EQUAL(param1 / param2, vector2(2.0, 6.0)); + OSL_CHECK_EQUAL(param1 / 2, vector2(0.25, 0.75)); + OSL_CHECK_EQUAL(param1 / 2.0, vector2(0.25, 0.75)); + OSL_CHECK_EQUAL(2 / param1, vector2(4.0, 2.0/1.5)); + OSL_CHECK_EQUAL(2.0 / param1, vector2(4.0, 2.0/1.5)); + + TEST_UNARY_VAL(abs, vector2(0.5, 1.5)); + TEST_UNARY_VAL(abs, vector2(-0.5, -1.5)); + TEST_UNARY_VAL(ceil, vector2(0.5, 1.5)); + TEST_UNARY_VAL(ceil, vector2(-0.5, -1.5)); + TEST_UNARY_VAL(floor, vector2(0.5, 1.5)); + TEST_UNARY_VAL(floor, vector2(-0.5, -1.5)); + + TEST_UNARY(sqrt); + TEST_UNARY(exp); + TEST_UNARY(log); + TEST_UNARY(log2); + + OSL_CHECK_EQUAL(mix(vector2(1.0, 2.0), vector2(21.0, 22.0), 0.0), vector2(1.0, 2.0)); + OSL_CHECK_EQUAL(mix(vector2(1.0, 2.0), vector2(21.0, 22.0), 1.0), vector2(21.0, 22.0)); + OSL_CHECK_EQUAL(mix(vector2(1.0, 2.0), vector2(21.0, 22.0), 0.5), vector2(11.0, 12.0)); + + OSL_CHECK_EQUAL(dot(vector2(1.0, 2.0), vector2(3.0, 4.0)), 11.0); + OSL_CHECK_EQUAL(length(vector2(3.0, 4.0)), 5.0); + + OSL_CHECK_EQUAL(smoothstep(vector2(1.0, 2.0), vector2(3.0, 4.0), vector2(0.0, 0.0)), vector2(0.0, 0.0)); + OSL_CHECK_EQUAL(smoothstep(vector2(1.0, 2.0), vector2(3.0, 4.0), vector2(10.0, 10.0)), vector2(1.0, 1.0)); + OSL_CHECK_EQUAL(smoothstep(vector2(1.0, 2.0), vector2(3.0, 4.0), vector2(2.0, 3.0)), vector2(0.5, 0.5)); + + OSL_CHECK_EQUAL(clamp(vector2(0.0, 0.0), vector2(1.0, 2.0), vector2(2.0, 3.0)), vector2(1.0, 2.0)); + OSL_CHECK_EQUAL(clamp(vector2(10.0, 10.0), vector2(1.0, 2.0), vector2(2.0, 3.0)), vector2(2.0, 3.0)); + OSL_CHECK_EQUAL(clamp(vector2(1.5, 2.5), vector2(1.0, 2.0), vector2(2.0, 3.0)), vector2(1.5, 2.5)); + + OSL_CHECK_EQUAL(clamp(vector2(0.25, 0.5), 1.0, 2.0), vector2(1.0, 1.0)); + OSL_CHECK_EQUAL(clamp(vector2(2.25, 2.5), 1.0, 2.0), vector2(2.0, 2.0)); + OSL_CHECK_EQUAL(clamp(vector2(1.25, 1.5), 1.0, 2.0), vector2(1.25, 1.5)); + + OSL_CHECK_EQUAL(max(vector2(1.0, 4.0), vector2(2.0, 3.0)), vector2(2.0, 4.0)); + OSL_CHECK_EQUAL(min(vector2(1.0, 4.0), vector2(2.0, 3.0)), vector2(1.0, 3.0)); + + OSL_CHECK_EQUAL(normalize(vector2(1.0, -1.0)), vector2(sqrt(2.0)/2, -sqrt(2.0)/2)); + + TEST_BINARY_VAL(fmod, vector2(5.0, 8.0), vector2(2.0, 3.0)); + TEST_BINARY_VAL(pow, vector2(2.0, 3.0), vector2(2.5, 3.5)); + TEST_UNARY_VAL(sign, vector2(0.5, -0.5)); + TEST_UNARY_VAL(sign, vector2(-0.5, 0.5)); + TEST_UNARY(sin); + TEST_UNARY(cos); + TEST_UNARY(tan); + TEST_UNARY_VAL(asin, vector2(0.5, 0.25)); + TEST_UNARY_VAL(acos, vector2(0.5, 0.25)); + TEST_BINARY(atan2); + OSL_CHECK_EQUAL(atan2(vector2(2.0, 0.5), 1.0), vector2(atan2(2.0, 1.0), atan2(0.5, 1.0))); +} diff --git a/testsuite/vector4/BATCHED b/testsuite/vector4/BATCHED new file mode 100644 index 000000000..e69de29bb diff --git a/testsuite/vector4/OPTIX b/testsuite/vector4/OPTIX new file mode 100644 index 000000000..e69de29bb diff --git a/testsuite/vector4/ref/out.txt b/testsuite/vector4/ref/out.txt new file mode 100644 index 000000000..9b663c8e3 --- /dev/null +++ b/testsuite/vector4/ref/out.txt @@ -0,0 +1,67 @@ +Compiled test.osl -> test.oso +parameter initialization: param1 = 0.5 1.5 2.5 3.5 +parameter initialization: param2 = 10 20 30 40 + +PASS: param1 == vector4(0.5, 1.5, 2.5, 3.5) +PASS: -param1 == vector4(-0.5, -1.5, -2.5, -3.5) +PASS: param1 != param2 +PASS: param1 + param2 == vector4(10.5, 21.5, 32.5, 43.5) +PASS: param1 + 1 == vector4(1.5, 2.5, 3.5, 4.5) +PASS: param1 + 1.0 == vector4(1.5, 2.5, 3.5, 4.5) +PASS: 1 + param1 == vector4(1.5, 2.5, 3.5, 4.5) +PASS: 1.0 + param1 == vector4(1.5, 2.5, 3.5, 4.5) +PASS: param2 - param1 == vector4(9.5, 18.5, 27.5, 36.5) +PASS: param1 - 1 == vector4(-0.5, 0.5, 1.5, 2.5) +PASS: param1 - 1.0 == vector4(-0.5, 0.5, 1.5, 2.5) +PASS: 1 - param1 == vector4(0.5, -0.5, -1.5, -2.5) +PASS: 1.0 - param1 == vector4(0.5, -0.5, -1.5, -2.5) +PASS: param1 * param2 == vector4(5.0, 30.0, 75.0, 140.0) +PASS: param1 * 2 == vector4(1.0, 3.0, 5.0, 7.0) +PASS: param1 * 2.0 == vector4(1.0, 3.0, 5.0, 7.0) +PASS: 2 * param1 == vector4(1.0, 3.0, 5.0, 7.0) +PASS: 2.0 * param1 == vector4(1.0, 3.0, 5.0, 7.0) +PASS: param1 / param2 == vector4(0.05, 1.5/20.0, 2.5/30.0, 3.5/40.0) +PASS: param1 / 2 == vector4(0.25, 0.75, 1.25, 1.75) +PASS: param1 / 2.0 == vector4(0.25, 0.75, 1.25, 1.75) +PASS: 2 / param1 == vector4(4.0, 2.0/1.5, 2.0/2.5, 2.0/3.5) +PASS: 2.0 / param1 == vector4(4.0, 2.0/1.5, 2.0/2.5, 2.0/3.5) +PASS: abs(vector4(0.5, 1.5, 2.5, 3.5)) == vector4(abs(xcomp(vector4(0.5, 1.5, 2.5, 3.5))), abs(ycomp(vector4(0.5, 1.5, 2.5, 3.5))), abs(zcomp(vector4(0.5, 1.5, 2.5, 3.5))), abs(wcomp(vector4(0.5, 1.5, 2.5, 3.5)))) +PASS: abs(vector4(-0.5, -1.5, -2.5, -3.5)) == vector4(abs(xcomp(vector4(-0.5, -1.5, -2.5, -3.5))), abs(ycomp(vector4(-0.5, -1.5, -2.5, -3.5))), abs(zcomp(vector4(-0.5, -1.5, -2.5, -3.5))), abs(wcomp(vector4(-0.5, -1.5, -2.5, -3.5)))) +PASS: ceil(vector4(0.5, 1.5, 2.5, 3.5)) == vector4(ceil(xcomp(vector4(0.5, 1.5, 2.5, 3.5))), ceil(ycomp(vector4(0.5, 1.5, 2.5, 3.5))), ceil(zcomp(vector4(0.5, 1.5, 2.5, 3.5))), ceil(wcomp(vector4(0.5, 1.5, 2.5, 3.5)))) +PASS: ceil(vector4(-0.5, -1.5, -2.5, -3.5)) == vector4(ceil(xcomp(vector4(-0.5, -1.5, -2.5, -3.5))), ceil(ycomp(vector4(-0.5, -1.5, -2.5, -3.5))), ceil(zcomp(vector4(-0.5, -1.5, -2.5, -3.5))), ceil(wcomp(vector4(-0.5, -1.5, -2.5, -3.5)))) +PASS: floor(vector4(0.5, 1.5, 2.5, 3.5)) == vector4(floor(xcomp(vector4(0.5, 1.5, 2.5, 3.5))), floor(ycomp(vector4(0.5, 1.5, 2.5, 3.5))), floor(zcomp(vector4(0.5, 1.5, 2.5, 3.5))), floor(wcomp(vector4(0.5, 1.5, 2.5, 3.5)))) +PASS: floor(vector4(-0.5, -1.5, -2.5, -3.5)) == vector4(floor(xcomp(vector4(-0.5, -1.5, -2.5, -3.5))), floor(ycomp(vector4(-0.5, -1.5, -2.5, -3.5))), floor(zcomp(vector4(-0.5, -1.5, -2.5, -3.5))), floor(wcomp(vector4(-0.5, -1.5, -2.5, -3.5)))) +PASS: sqrt(vector4(0.5, 1.5, 2.5, 3.5)) == vector4(sqrt(xcomp(vector4(0.5, 1.5, 2.5, 3.5))), sqrt(ycomp(vector4(0.5, 1.5, 2.5, 3.5))), sqrt(zcomp(vector4(0.5, 1.5, 2.5, 3.5))), sqrt(wcomp(vector4(0.5, 1.5, 2.5, 3.5)))) +PASS: exp(vector4(0.5, 1.5, 2.5, 3.5)) == vector4(exp(xcomp(vector4(0.5, 1.5, 2.5, 3.5))), exp(ycomp(vector4(0.5, 1.5, 2.5, 3.5))), exp(zcomp(vector4(0.5, 1.5, 2.5, 3.5))), exp(wcomp(vector4(0.5, 1.5, 2.5, 3.5)))) +PASS: log(vector4(0.5, 1.5, 2.5, 3.5)) == vector4(log(xcomp(vector4(0.5, 1.5, 2.5, 3.5))), log(ycomp(vector4(0.5, 1.5, 2.5, 3.5))), log(zcomp(vector4(0.5, 1.5, 2.5, 3.5))), log(wcomp(vector4(0.5, 1.5, 2.5, 3.5)))) +PASS: log2(vector4(0.5, 1.5, 2.5, 3.5)) == vector4(log2(xcomp(vector4(0.5, 1.5, 2.5, 3.5))), log2(ycomp(vector4(0.5, 1.5, 2.5, 3.5))), log2(zcomp(vector4(0.5, 1.5, 2.5, 3.5))), log2(wcomp(vector4(0.5, 1.5, 2.5, 3.5)))) +PASS: mix(vector4(1.0, 2.0, 3.0, 4.0), vector4(21.0, 22.0, 23.0, 24.0), 0.0) == vector4(1.0, 2.0, 3.0, 4.0) +PASS: mix(vector4(1.0, 2.0, 3.0, 4.0), vector4(21.0, 22.0, 23.0, 24.0), 1.0) == vector4(21.0, 22.0, 23.0, 24.0) +PASS: mix(vector4(1.0, 2.0, 3.0, 4.0), vector4(21.0, 22.0, 23.0, 24.0), 0.5) == vector4(11.0, 12.0, 13.0, 14.0) +PASS: vec4ToVec3(vector4(1.0, 2.0, 3.0, 1.0)) == vector(1.0, 2.0, 3.0) +PASS: dot(param1, param2) == 0.5*10.0 + 1.5*20.0 + 2.5*30.0 + 3.5*40.0 +PASS: length(vector4(3.0, 4.0, 5.0, 6.0)) == sqrt(3.0*3.0 + 4.0*4.0 + 5.0*5.0 + 6.0*6.0) +PASS: smoothstep(vector4(1.0, 2.0, 3.0, 4.0), vector4(11.0, 12.0, 13.0, 14.0), vector4(0.0, 0.0, 0.0, 0.0)) == vector4(0.0, 0.0, 0.0, 0.0) +PASS: smoothstep(vector4(1.0, 2.0, 3.0, 4.0), vector4(11.0, 12.0, 13.0, 14.0), vector4(20.0, 20.0, 20.0, 20.0)) == vector4(1.0, 1.0, 1.0, 1.0) +PASS: smoothstep(vector4(1.0, 2.0, 3.0, 4.0), vector4(11.0, 12.0, 13.0, 14.0), vector4(6.0, 7.0, 8.0, 9.0)) == vector4(0.5, 0.5, 0.5, 0.5) +PASS: clamp(vector4(0.0, 0.0, 0.0, 0.0), vector4(1.0, 2.0, 3.0, 4.0), vector4(2.0, 3.0, 4.0, 5.0)) == vector4(1.0, 2.0, 3.0, 4.0) +PASS: clamp(vector4(10.0, 10.0, 10.0, 10.0), vector4(1.0, 2.0, 3.0, 4.0), vector4(2.0, 3.0, 4.0, 5.0)) == vector4(2.0, 3.0, 4.0, 5.0) +PASS: clamp(vector4(1.5, 2.5, 3.5, 4.5), vector4(1.0, 2.0, 3.0, 4.0), vector4(2.0, 3.0, 4.0, 5.0)) == vector4(1.5, 2.5, 3.5, 4.5) +PASS: clamp(vector4(0.25, 0.5, 0.75, 0.8), 1.0, 2.0) == vector4(1.0, 1.0, 1.0, 1.0) +PASS: clamp(vector4(2.25, 2.5, 3.5, 4.5), 1.0, 2.0) == vector4(2.0, 2.0, 2.0, 2.0) +PASS: clamp(vector4(1.25, 1.5, 1.75, 1.875), 1.0, 2.0) == vector4(1.25, 1.5, 1.75, 1.875) +PASS: max(vector4(1.0, 4.0, 2.0, 5.0), vector4(2.0, 3.0, 3.5, 4.0)) == vector4(2.0, 4.0, 3.5, 5.0) +PASS: min(vector4(1.0, 4.0, 2.0, 5.0), vector4(2.0, 3.0, 3.5, 4.0)) == vector4(1.0, 3.0, 2.0, 4.0) +PASS: normalize(v) == v/length(v) +PASS: fmod(vector4(5.0, 8.0, 10.0, 13.0), vector4(2.0, 3.0, 4.0, 5.0)) == vector4(fmod(xcomp(vector4(5.0, 8.0, 10.0, 13.0)), xcomp(vector4(2.0, 3.0, 4.0, 5.0))), fmod(ycomp(vector4(5.0, 8.0, 10.0, 13.0)), ycomp(vector4(2.0, 3.0, 4.0, 5.0))), fmod(zcomp(vector4(5.0, 8.0, 10.0, 13.0)), zcomp(vector4(2.0, 3.0, 4.0, 5.0))), fmod(wcomp(vector4(5.0, 8.0, 10.0, 13.0)), wcomp(vector4(2.0, 3.0, 4.0, 5.0)))) +PASS: pow(vector4(2.0, 3.0, 4.0, 5.0), vector4(-1.0, 2.0, 0.5, 3.0)) == vector4(pow(xcomp(vector4(2.0, 3.0, 4.0, 5.0)), xcomp(vector4(-1.0, 2.0, 0.5, 3.0))), pow(ycomp(vector4(2.0, 3.0, 4.0, 5.0)), ycomp(vector4(-1.0, 2.0, 0.5, 3.0))), pow(zcomp(vector4(2.0, 3.0, 4.0, 5.0)), zcomp(vector4(-1.0, 2.0, 0.5, 3.0))), pow(wcomp(vector4(2.0, 3.0, 4.0, 5.0)), wcomp(vector4(-1.0, 2.0, 0.5, 3.0)))) +PASS: sign(vector4(0.5, -0.6, 0.7, -0.8)) == vector4(sign(xcomp(vector4(0.5, -0.6, 0.7, -0.8))), sign(ycomp(vector4(0.5, -0.6, 0.7, -0.8))), sign(zcomp(vector4(0.5, -0.6, 0.7, -0.8))), sign(wcomp(vector4(0.5, -0.6, 0.7, -0.8)))) +PASS: sign(vector4(-0.5, 0.6, -0.7, 0.8)) == vector4(sign(xcomp(vector4(-0.5, 0.6, -0.7, 0.8))), sign(ycomp(vector4(-0.5, 0.6, -0.7, 0.8))), sign(zcomp(vector4(-0.5, 0.6, -0.7, 0.8))), sign(wcomp(vector4(-0.5, 0.6, -0.7, 0.8)))) +PASS: sin(vector4(0.5, 1.5, 2.5, 3.5)) == vector4(sin(xcomp(vector4(0.5, 1.5, 2.5, 3.5))), sin(ycomp(vector4(0.5, 1.5, 2.5, 3.5))), sin(zcomp(vector4(0.5, 1.5, 2.5, 3.5))), sin(wcomp(vector4(0.5, 1.5, 2.5, 3.5)))) +PASS: cos(vector4(0.5, 1.5, 2.5, 3.5)) == vector4(cos(xcomp(vector4(0.5, 1.5, 2.5, 3.5))), cos(ycomp(vector4(0.5, 1.5, 2.5, 3.5))), cos(zcomp(vector4(0.5, 1.5, 2.5, 3.5))), cos(wcomp(vector4(0.5, 1.5, 2.5, 3.5)))) +PASS: tan(vector4(0.5, 1.5, 2.5, 3.5)) == vector4(tan(xcomp(vector4(0.5, 1.5, 2.5, 3.5))), tan(ycomp(vector4(0.5, 1.5, 2.5, 3.5))), tan(zcomp(vector4(0.5, 1.5, 2.5, 3.5))), tan(wcomp(vector4(0.5, 1.5, 2.5, 3.5)))) +PASS: asin(vector4(0.5, 0.25, 0.75, 0.125)) == vector4(asin(xcomp(vector4(0.5, 0.25, 0.75, 0.125))), asin(ycomp(vector4(0.5, 0.25, 0.75, 0.125))), asin(zcomp(vector4(0.5, 0.25, 0.75, 0.125))), asin(wcomp(vector4(0.5, 0.25, 0.75, 0.125)))) +PASS: acos(vector4(0.5, 0.25, 0.75, 0.125)) == vector4(acos(xcomp(vector4(0.5, 0.25, 0.75, 0.125))), acos(ycomp(vector4(0.5, 0.25, 0.75, 0.125))), acos(zcomp(vector4(0.5, 0.25, 0.75, 0.125))), acos(wcomp(vector4(0.5, 0.25, 0.75, 0.125)))) +PASS: atan2(vector4(0.5, 1.5, 2.5, 3.5), vector4(10.0, 20.0, 30.0, 40.0)) == vector4(atan2(xcomp(vector4(0.5, 1.5, 2.5, 3.5)), xcomp(vector4(10.0, 20.0, 30.0, 40.0))), atan2(ycomp(vector4(0.5, 1.5, 2.5, 3.5)), ycomp(vector4(10.0, 20.0, 30.0, 40.0))), atan2(zcomp(vector4(0.5, 1.5, 2.5, 3.5)), zcomp(vector4(10.0, 20.0, 30.0, 40.0))), atan2(wcomp(vector4(0.5, 1.5, 2.5, 3.5)), wcomp(vector4(10.0, 20.0, 30.0, 40.0)))) +PASS: atan2(vector4(2.0, 0.5, 1.0, 0.25), 1.0) == vector4(atan2(2.0, 1.0), atan2(0.5, 1.0), atan2(1.0, 1.0), atan2(0.25, 1.0)) + diff --git a/testsuite/vector4/run.py b/testsuite/vector4/run.py new file mode 100755 index 000000000..6836d5554 --- /dev/null +++ b/testsuite/vector4/run.py @@ -0,0 +1,7 @@ +#!/usr/bin/env python + +# Copyright Contributors to the Open Shading Language project. +# SPDX-License-Identifier: BSD-3-Clause +# https://github.com/AcademySoftwareFoundation/OpenShadingLanguage + +command = testshade("test") diff --git a/testsuite/vector4/test.osl b/testsuite/vector4/test.osl new file mode 100644 index 000000000..32018321e --- /dev/null +++ b/testsuite/vector4/test.osl @@ -0,0 +1,126 @@ +// Copyright Contributors to the Open Shading Language project. +// SPDX-License-Identifier: BSD-3-Clause +// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage + +#include "vector4.h" +#include "../common/shaders/pretty.h" + +#define OSL_UNITTEST_VERBOSE 1 +#include "../common/shaders/osl-unittest.h" + +float xcomp(vector4 v) { return v.x; } +float ycomp(vector4 v) { return v.y; } +float zcomp(vector4 v) { return v.z; } +float wcomp(vector4 v) { return v.w; } + +#define TEST_UNARY_VAL(func, val) \ + OSL_CHECK_EQUAL(func(val), vector4(func(xcomp(val)), func(ycomp(val)), \ + func(zcomp(val)), func(wcomp(val)))) + +#define TEST_BINARY_VAL(func, valA, valB) \ + OSL_CHECK_EQUAL(func(valA, valB), vector4(func(xcomp(valA), xcomp(valB)), \ + func(ycomp(valA), ycomp(valB)), \ + func(zcomp(valA), zcomp(valB)), \ + func(wcomp(valA), wcomp(valB)))) + +#define TEST_UNARY(func) \ + TEST_UNARY_VAL(func, vector4(0.5, 1.5, 2.5, 3.5)) + +#define TEST_BINARY(func) \ + TEST_BINARY_VAL(func, vector4(0.5, 1.5, 2.5, 3.5), \ + vector4(10.0, 20.0, 30.0, 40.0)) + + + +shader +test (vector4 param1 = vector4 (0.5, 1.5, 2.5, 3.5), + vector4 param2 = vector4 (10.0, 20.0, 30.0, 40.0) + ) +{ + printf("parameter initialization: param1 = %s\n", tostring(param1)); + printf("parameter initialization: param2 = %s\n", tostring(param2)); + printf("\n"); + + OSL_CHECK_EQUAL(param1, vector4(0.5, 1.5, 2.5, 3.5)); + OSL_CHECK_EQUAL(-param1, vector4(-0.5, -1.5, -2.5, -3.5)); + OSL_CHECK(param1 != param2); + + OSL_CHECK_EQUAL(param1 + param2, vector4(10.5, 21.5, 32.5, 43.5)); + OSL_CHECK_EQUAL(param1 + 1, vector4(1.5, 2.5, 3.5, 4.5)); + OSL_CHECK_EQUAL(param1 + 1.0, vector4(1.5, 2.5, 3.5, 4.5)); + OSL_CHECK_EQUAL(1 + param1, vector4(1.5, 2.5, 3.5, 4.5)); + OSL_CHECK_EQUAL(1.0 + param1, vector4(1.5, 2.5, 3.5, 4.5)); + + OSL_CHECK_EQUAL(param2 - param1, vector4(9.5, 18.5, 27.5, 36.5)); + OSL_CHECK_EQUAL(param1 - 1, vector4(-0.5, 0.5, 1.5, 2.5)); + OSL_CHECK_EQUAL(param1 - 1.0, vector4(-0.5, 0.5, 1.5, 2.5)); + OSL_CHECK_EQUAL(1 - param1, vector4(0.5, -0.5, -1.5, -2.5)); + OSL_CHECK_EQUAL(1.0 - param1, vector4(0.5, -0.5, -1.5, -2.5)); + + OSL_CHECK_EQUAL(param1 * param2, vector4(5.0, 30.0, 75.0, 140.0)); + OSL_CHECK_EQUAL(param1 * 2, vector4(1.0, 3.0, 5.0, 7.0)); + OSL_CHECK_EQUAL(param1 * 2.0, vector4(1.0, 3.0, 5.0, 7.0)); + OSL_CHECK_EQUAL(2 * param1, vector4(1.0, 3.0, 5.0, 7.0)); + OSL_CHECK_EQUAL(2.0 * param1, vector4(1.0, 3.0, 5.0, 7.0)); + + OSL_CHECK_EQUAL(param1 / param2, vector4(0.05, 1.5/20.0, 2.5/30.0, 3.5/40.0)); + OSL_CHECK_EQUAL(param1 / 2, vector4(0.25, 0.75, 1.25, 1.75)); + OSL_CHECK_EQUAL(param1 / 2.0, vector4(0.25, 0.75, 1.25, 1.75)); + OSL_CHECK_EQUAL(2 / param1, vector4(4.0, 2.0/1.5, 2.0/2.5, 2.0/3.5)); + OSL_CHECK_EQUAL(2.0 / param1, vector4(4.0, 2.0/1.5, 2.0/2.5, 2.0/3.5)); + + TEST_UNARY_VAL(abs, vector4(0.5, 1.5, 2.5, 3.5)); + TEST_UNARY_VAL(abs, vector4(-0.5, -1.5, -2.5, -3.5)); + TEST_UNARY_VAL(ceil, vector4(0.5, 1.5, 2.5, 3.5)); + TEST_UNARY_VAL(ceil, vector4(-0.5, -1.5, -2.5, -3.5)); + TEST_UNARY_VAL(floor, vector4(0.5, 1.5, 2.5, 3.5)); + TEST_UNARY_VAL(floor, vector4(-0.5, -1.5, -2.5, -3.5)); + + TEST_UNARY(sqrt); + TEST_UNARY(exp); + TEST_UNARY(log); + TEST_UNARY(log2); + + OSL_CHECK_EQUAL(mix(vector4(1.0, 2.0, 3.0, 4.0), vector4(21.0, 22.0, 23.0, 24.0), 0.0), vector4(1.0, 2.0, 3.0, 4.0)); + OSL_CHECK_EQUAL(mix(vector4(1.0, 2.0, 3.0, 4.0), vector4(21.0, 22.0, 23.0, 24.0), 1.0), vector4(21.0, 22.0, 23.0, 24.0)); + OSL_CHECK_EQUAL(mix(vector4(1.0, 2.0, 3.0, 4.0), vector4(21.0, 22.0, 23.0, 24.0), 0.5), vector4(11.0, 12.0, 13.0, 14.0)); + + OSL_CHECK_EQUAL(vec4ToVec3(vector4(1.0, 2.0, 3.0, 1.0)), vector(1.0, 2.0, 3.0)); + OSL_CHECK_EQUAL(dot(param1, param2), 0.5*10.0 + 1.5*20.0 + 2.5*30.0 + 3.5*40.0); + OSL_CHECK_EQUAL(length(vector4(3.0, 4.0, 5.0, 6.0)), sqrt(3.0*3.0 + 4.0*4.0 + 5.0*5.0 + 6.0*6.0)); + + OSL_CHECK_EQUAL(smoothstep(vector4(1.0, 2.0, 3.0, 4.0), vector4(11.0, 12.0, 13.0, 14.0), vector4(0.0, 0.0, 0.0, 0.0)), vector4(0.0, 0.0, 0.0, 0.0)); + OSL_CHECK_EQUAL(smoothstep(vector4(1.0, 2.0, 3.0, 4.0), vector4(11.0, 12.0, 13.0, 14.0), vector4(20.0, 20.0, 20.0, 20.0)), vector4(1.0, 1.0, 1.0, 1.0)); + OSL_CHECK_EQUAL(smoothstep(vector4(1.0, 2.0, 3.0, 4.0), vector4(11.0, 12.0, 13.0, 14.0), vector4(6.0, 7.0, 8.0, 9.0)), vector4(0.5, 0.5, 0.5, 0.5)); + + OSL_CHECK_EQUAL(clamp(vector4(0.0, 0.0, 0.0, 0.0), vector4(1.0, 2.0, 3.0, 4.0), vector4(2.0, 3.0, 4.0, 5.0)), vector4(1.0, 2.0, 3.0, 4.0)); + OSL_CHECK_EQUAL(clamp(vector4(10.0, 10.0, 10.0, 10.0), vector4(1.0, 2.0, 3.0, 4.0), vector4(2.0, 3.0, 4.0, 5.0)), vector4(2.0, 3.0, 4.0, 5.0)); + OSL_CHECK_EQUAL(clamp(vector4(1.5, 2.5, 3.5, 4.5), vector4(1.0, 2.0, 3.0, 4.0), vector4(2.0, 3.0, 4.0, 5.0)), vector4(1.5, 2.5, 3.5, 4.5)); + + OSL_CHECK_EQUAL(clamp(vector4(0.25, 0.5, 0.75, 0.8), 1.0, 2.0), vector4(1.0, 1.0, 1.0, 1.0)); + OSL_CHECK_EQUAL(clamp(vector4(2.25, 2.5, 3.5, 4.5), 1.0, 2.0), vector4(2.0, 2.0, 2.0, 2.0)); + OSL_CHECK_EQUAL(clamp(vector4(1.25, 1.5, 1.75, 1.875), 1.0, 2.0), vector4(1.25, 1.5, 1.75, 1.875)); + + OSL_CHECK_EQUAL(max(vector4(1.0, 4.0, 2.0, 5.0), vector4(2.0, 3.0, 3.5, 4.0)), vector4(2.0, 4.0, 3.5, 5.0)); + OSL_CHECK_EQUAL(min(vector4(1.0, 4.0, 2.0, 5.0), vector4(2.0, 3.0, 3.5, 4.0)), vector4(1.0, 3.0, 2.0, 4.0)); + + { + vector4 v = vector4(1.0, -1.0, 2.0, -2.0); + OSL_CHECK_EQUAL(normalize(v), v/length(v)); + } + + TEST_BINARY_VAL(fmod, vector4(5.0, 8.0, 10.0, 13.0), + vector4(2.0, 3.0, 4.0, 5.0)); + TEST_BINARY_VAL(pow, vector4(2.0, 3.0, 4.0, 5.0), vector4(-1.0, 2.0, 0.5, 3.0)); + TEST_UNARY_VAL(sign, vector4(0.5, -0.6, 0.7, -0.8)); + TEST_UNARY_VAL(sign, vector4(-0.5, 0.6, -0.7, 0.8)); + TEST_UNARY(sin); + TEST_UNARY(cos); + TEST_UNARY(tan); + TEST_UNARY_VAL(asin, vector4(0.5, 0.25, 0.75, 0.125)); + TEST_UNARY_VAL(acos, vector4(0.5, 0.25, 0.75, 0.125)); + TEST_BINARY(atan2); + OSL_CHECK_EQUAL(atan2(vector4(2.0, 0.5, 1.0, 0.25), 1.0), + vector4(atan2(2.0, 1.0), atan2(0.5, 1.0), + atan2(1.0, 1.0), atan2(0.25, 1.0))); +}