blob: 0434bc1becbb236a96f87192ceb206ff1f91acbe [file] [log] [blame]
// Copyright 2024 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "src/tint/lang/spirv/reader/helper_test.h"
namespace tint::spirv::reader {
namespace {
std::string Preamble() {
return R"(
OpCapability Shader
%glsl = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %100 "main"
OpExecutionMode %100 LocalSize 1 1 1
%void = OpTypeVoid
%voidfn = OpTypeFunction %void
%uint = OpTypeInt 32 0
%int = OpTypeInt 32 1
%float = OpTypeFloat 32
%uint_10 = OpConstant %uint 10
%uint_15 = OpConstant %uint 15
%uint_20 = OpConstant %uint 20
%int_30 = OpConstant %int 30
%int_35 = OpConstant %int 35
%int_40 = OpConstant %int 40
%float_50 = OpConstant %float 50
%float_60 = OpConstant %float 60
%float_70 = OpConstant %float 70
%v2uint = OpTypeVector %uint 2
%v2int = OpTypeVector %int 2
%v2float = OpTypeVector %float 2
%v3float = OpTypeVector %float 3
%v4float = OpTypeVector %float 4
%mat2v2float = OpTypeMatrix %v2float 2
%mat3v3float = OpTypeMatrix %v3float 3
%mat4v4float = OpTypeMatrix %v4float 4
%v2uint_10_20 = OpConstantComposite %v2uint %uint_10 %uint_20
%v2uint_20_10 = OpConstantComposite %v2uint %uint_20 %uint_10
%v2uint_15_15 = OpConstantComposite %v2uint %uint_15 %uint_15
%v2int_30_40 = OpConstantComposite %v2int %int_30 %int_40
%v2int_40_30 = OpConstantComposite %v2int %int_40 %int_30
%v2int_35_35 = OpConstantComposite %v2int %int_35 %int_35
%v2float_50_60 = OpConstantComposite %v2float %float_50 %float_60
%v2float_60_50 = OpConstantComposite %v2float %float_60 %float_50
%v2float_70_70 = OpConstantComposite %v2float %float_70 %float_70
%v3float_50_60_70 = OpConstantComposite %v3float %float_50 %float_60 %float_70
%v3float_60_70_50 = OpConstantComposite %v3float %float_60 %float_70 %float_50
%v4float_50_50_50_50 = OpConstantComposite %v4float %float_50 %float_50 %float_50 %float_50
%mat2v2float_50_60 = OpConstantComposite %mat2v2float %v2float_50_60 %v2float_50_60
%mat3v3float_50_60_70 = OpConstantComposite %mat3v3float %v3float_50_60_70 %v3float_50_60_70 %v3float_50_60_70
%mat4v4float_50_50_50_50 = OpConstantComposite %mat4v4float %v4float_50_50_50_50 %v4float_50_50_50_50 %v4float_50_50_50_50 %v4float_50_50_50_50
%100 = OpFunction %void None %voidfn
%entry = OpLabel
)";
}
struct GlslStd450Case {
std::string opcode;
std::string wgsl_func;
};
inline std::ostream& operator<<(std::ostream& out, GlslStd450Case c) {
out << "GlslStd450Case(" << c.opcode << " " << c.wgsl_func << ")";
return out;
}
// Nomenclature:
// Float = scalar float
// Floating = scalar float or vector-of-float
// Float3 = 3-element vector of float
// Int = scalar signed int
// Inting = scalar int or vector-of-int
// Uint = scalar unsigned int
// Uinting = scalar unsigned or vector-of-unsigned
using SpirvReaderTest_GlslStd450_Float_Floating = SpirvReaderTestWithParam<GlslStd450Case>;
using SpirvReaderTest_GlslStd450_Float_FloatingFloating = SpirvReaderTestWithParam<GlslStd450Case>;
using SpirvReaderTest_GlslStd450_Floating_Floating = SpirvReaderTestWithParam<GlslStd450Case>;
using SpirvReaderTest_GlslStd450_Floating_FloatingFloating =
SpirvReaderTestWithParam<GlslStd450Case>;
using SpirvReaderTest_GlslStd450_Floating_FloatingFloatingFloating =
SpirvReaderTestWithParam<GlslStd450Case>;
using SpirvReaderTest_GlslStd450_Floating_FloatingInting = SpirvReaderTestWithParam<GlslStd450Case>;
using SpirvReaderTest_GlslStd450_Float3_Float3Float3 = SpirvReaderTestWithParam<GlslStd450Case>;
using SpirvReaderTest_GlslStd450_Inting_Inting = SpirvReaderTestWithParam<GlslStd450Case>;
using SpirvReaderTest_GlslStd450_Inting_Inting_SignednessCoercing =
SpirvReaderTestWithParam<GlslStd450Case>;
using SpirvReaderTest_GlslStd450_Inting_IntingInting = SpirvReaderTestWithParam<GlslStd450Case>;
using SpirvReaderTest_GlslStd450_Inting_IntingIntingInting =
SpirvReaderTestWithParam<GlslStd450Case>;
using SpirvReaderTest_GlslStd450_Uinting_Uinting = SpirvReaderTestWithParam<GlslStd450Case>;
using SpirvReaderTest_GlslStd450_Uinting_UintingUinting = SpirvReaderTestWithParam<GlslStd450Case>;
using SpirvReaderTest_GlslStd450_Uinting_UintingUintingUinting =
SpirvReaderTestWithParam<GlslStd450Case>;
TEST_P(SpirvReaderTest_GlslStd450_Float_Floating, Scalar) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %float %glsl )" +
GetParam().opcode + R"( %float_50
%2 = OpCopyObject %float %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:f32 = )" + GetParam().wgsl_func +
R"( 50.0f
%3:f32 = let %2
ret
}
}
)");
}
TEST_P(SpirvReaderTest_GlslStd450_Float_Floating, Vector) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %float %glsl )" +
GetParam().opcode + R"( %v2float_50_60
%2 = OpCopyObject %float %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:f32 = )" + GetParam().wgsl_func +
R"( vec2<f32>(50.0f, 60.0f)
%3:f32 = let %2
ret
}
}
)");
}
TEST_P(SpirvReaderTest_GlslStd450_Float_FloatingFloating, Scalar) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %float %glsl )" +
GetParam().opcode + R"( %float_50 %float_60
%2 = OpCopyObject %float %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:f32 = )" + GetParam().wgsl_func +
R"( 50.0f, 60.0f
%3:f32 = let %2
ret
}
}
)");
}
TEST_P(SpirvReaderTest_GlslStd450_Float_FloatingFloating, Vector) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %float %glsl )" +
GetParam().opcode + R"( %v2float_50_60 %v2float_60_50
%2 = OpCopyObject %float %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:f32 = )" + GetParam().wgsl_func +
R"( vec2<f32>(50.0f, 60.0f), vec2<f32>(60.0f, 50.0f)
%3:f32 = let %2
ret
}
}
)");
}
TEST_P(SpirvReaderTest_GlslStd450_Floating_Floating, Scalar) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %float %glsl )" +
GetParam().opcode + R"( %float_50
%2 = OpCopyObject %float %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:f32 = )" + GetParam().wgsl_func +
R"( 50.0f
%3:f32 = let %2
ret
}
})");
}
TEST_P(SpirvReaderTest_GlslStd450_Floating_Floating, Vector) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %v2float %glsl )" +
GetParam().opcode + R"( %v2float_50_60
%2 = OpCopyObject %v2float %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:vec2<f32> = )" +
GetParam().wgsl_func +
R"( vec2<f32>(50.0f, 60.0f)
%3:vec2<f32> = let %2
ret
}
}
)");
}
TEST_P(SpirvReaderTest_GlslStd450_Floating_FloatingFloating, Scalar) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %float %glsl )" +
GetParam().opcode + R"( %float_50 %float_60
%2 = OpCopyObject %float %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:f32 = )" + GetParam().wgsl_func +
R"( 50.0f, 60.0f
%3:f32 = let %2
ret
}
}
)");
}
TEST_P(SpirvReaderTest_GlslStd450_Floating_FloatingFloating, Vector) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %v2float %glsl )" +
GetParam().opcode + R"( %v2float_50_60 %v2float_60_50
%2 = OpCopyObject %v2float %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:vec2<f32> = )" +
GetParam().wgsl_func +
R"( vec2<f32>(50.0f, 60.0f), vec2<f32>(60.0f, 50.0f)
%3:vec2<f32> = let %2
ret
}
}
)");
}
TEST_P(SpirvReaderTest_GlslStd450_Floating_FloatingFloatingFloating, Scalar) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %float %glsl )" +
GetParam().opcode + R"( %float_50 %float_60 %float_70
%2 = OpCopyObject %float %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:f32 = )" + GetParam().wgsl_func +
R"( 50.0f, 60.0f, 70.0f
%3:f32 = let %2
ret
}
}
)");
}
TEST_P(SpirvReaderTest_GlslStd450_Floating_FloatingFloatingFloating, Vector) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %v2float %glsl )" +
GetParam().opcode +
R"( %v2float_50_60 %v2float_60_50 %v2float_70_70
%2 = OpCopyObject %v2float %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:vec2<f32> = )" +
GetParam().wgsl_func +
R"( vec2<f32>(50.0f, 60.0f), vec2<f32>(60.0f, 50.0f), vec2<f32>(70.0f)
%3:vec2<f32> = let %2
ret
}
}
)");
}
TEST_P(SpirvReaderTest_GlslStd450_Floating_FloatingInting, Scalar) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %float %glsl )" +
GetParam().opcode + R"( %float_50 %int_30
%2 = OpCopyObject %float %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:f32 = )" + GetParam().wgsl_func +
R"( 50.0f, 30i
%3:f32 = let %2
ret
}
}
)");
}
TEST_P(SpirvReaderTest_GlslStd450_Floating_FloatingInting, Vector) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %v2float %glsl )" +
GetParam().opcode +
R"( %v2float_50_60 %v2int_30_40
%2 = OpCopyObject %v2float %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:vec2<f32> = )" +
GetParam().wgsl_func +
R"( vec2<f32>(50.0f, 60.0f), vec2<i32>(30i, 40i)
%3:vec2<f32> = let %2
ret
}
}
)");
}
TEST_P(SpirvReaderTest_GlslStd450_Float3_Float3Float3, SpirvParser) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %v3float %glsl )" +
GetParam().opcode +
R"( %v3float_50_60_70 %v3float_60_70_50
%2 = OpCopyObject %v3float %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:vec3<f32> = )" +
GetParam().wgsl_func +
R"( vec3<f32>(50.0f, 60.0f, 70.0f), vec3<f32>(60.0f, 70.0f, 50.0f)
%3:vec3<f32> = let %2
ret
}
}
)");
}
INSTANTIATE_TEST_SUITE_P(SpirvReader,
SpirvReaderTest_GlslStd450_Float_Floating,
::testing::Values(GlslStd450Case{"Length", "length"}));
INSTANTIATE_TEST_SUITE_P(SpirvReader,
SpirvReaderTest_GlslStd450_Float_FloatingFloating,
::testing::Values(GlslStd450Case{"Distance", "distance"}));
INSTANTIATE_TEST_SUITE_P(SpirvReader,
SpirvReaderTest_GlslStd450_Floating_Floating,
::testing::ValuesIn(std::vector<GlslStd450Case>{
{"Acos", "acos"}, //
{"Asin", "asin"}, //
{"Atan", "atan"}, //
{"Ceil", "ceil"}, //
{"Cos", "cos"}, //
{"Cosh", "cosh"}, //
{"Degrees", "degrees"}, //
{"Exp", "exp"}, //
{"Exp2", "exp2"}, //
{"FAbs", "abs"}, //
{"FSign", "sign"}, //
{"Floor", "floor"}, //
{"Fract", "fract"}, //
{"InverseSqrt", "inverseSqrt"}, //
{"Log", "log"}, //
{"Log2", "log2"}, //
{"Radians", "radians"}, //
{"Round", "round"}, //
{"RoundEven", "round"}, //
{"Sin", "sin"}, //
{"Sinh", "sinh"}, //
{"Sqrt", "sqrt"}, //
{"Tan", "tan"}, //
{"Tanh", "tanh"}, //
{"Trunc", "trunc"}, //
}));
INSTANTIATE_TEST_SUITE_P(SpirvReader,
SpirvReaderTest_GlslStd450_Floating_FloatingFloating,
::testing::ValuesIn(std::vector<GlslStd450Case>{
{"Atan2", "atan2"},
{"NMax", "max"},
{"NMin", "min"},
{"FMax", "max"}, // WGSL max promises more for NaN
{"FMin", "min"}, // WGSL min promises more for NaN
{"Pow", "pow"},
{"Step", "step"},
}));
INSTANTIATE_TEST_SUITE_P(SpirvReader,
SpirvReaderTest_GlslStd450_Floating_FloatingInting,
::testing::Values(GlslStd450Case{"Ldexp", "ldexp"}));
// For ldexp with unsigned second argument, see below.
INSTANTIATE_TEST_SUITE_P(SpirvReader,
SpirvReaderTest_GlslStd450_Float3_Float3Float3,
::testing::Values(GlslStd450Case{"Cross", "cross"}));
INSTANTIATE_TEST_SUITE_P(SpirvReader,
SpirvReaderTest_GlslStd450_Floating_FloatingFloatingFloating,
::testing::ValuesIn(std::vector<GlslStd450Case>{
{"NClamp", "clamp"},
{"FClamp", "clamp"}, // WGSL FClamp promises more for NaN
{"Fma", "fma"},
{"FMix", "mix"},
{"SmoothStep", "smoothstep"}}));
TEST_P(SpirvReaderTest_GlslStd450_Inting_Inting, Scalar) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %int %glsl )" +
GetParam().opcode +
R"( %int_30
%2 = OpCopyObject %int %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:i32 = )" + GetParam().wgsl_func +
R"( 30i
%3:i32 = let %2
ret
}
}
)");
}
TEST_P(SpirvReaderTest_GlslStd450_Inting_Inting_SignednessCoercing, DISABLED_Scalar_UnsignedArg) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %int %glsl )" +
GetParam().opcode +
R"( %uint_10
%2 = OpCopyObject %int %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
let x_1 = )" + GetParam().wgsl_func +
R"((bitcast<i32>(u1));
}
}
)");
}
TEST_P(SpirvReaderTest_GlslStd450_Inting_Inting_SignednessCoercing,
DISABLED_Scalar_UnsignedResult) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %uint %glsl )" +
GetParam().opcode +
R"( %int_30
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
let x_1 = bitcast<u32>()" +
GetParam().wgsl_func + R"((i1));
}
}
)");
}
TEST_P(SpirvReaderTest_GlslStd450_Inting_Inting, Vector) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %v2int %glsl )" +
GetParam().opcode +
R"( %v2int_30_40
%2 = OpCopyObject %v2int %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:vec2<i32> = )" +
GetParam().wgsl_func +
R"( vec2<i32>(30i, 40i)
%3:vec2<i32> = let %2
ret
}
}
)");
}
TEST_P(SpirvReaderTest_GlslStd450_Inting_Inting_SignednessCoercing, DISABLED_Vector_UnsignedArg) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %v2int %glsl )" +
GetParam().opcode +
R"( %v2uint_10_20
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
let x_1 = )" + GetParam().wgsl_func +
R"((bitcast<vec2i>(v2u1));
}
}
)");
}
TEST_P(SpirvReaderTest_GlslStd450_Inting_Inting_SignednessCoercing,
DISABLED_Vector_UnsignedResult) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %v2uint %glsl )" +
GetParam().opcode +
R"( %v2int_30_40
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
let x_1 = bitcast<vec2u>()" +
GetParam().wgsl_func + R"((v2i1));
}
}
)");
}
TEST_P(SpirvReaderTest_GlslStd450_Inting_IntingInting, Scalar) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %int %glsl )" +
GetParam().opcode +
R"( %int_30 %int_35
%2 = OpCopyObject %int %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:i32 = )" + GetParam().wgsl_func +
R"( 30i, 35i
%3:i32 = let %2
ret
}
}
)");
}
TEST_P(SpirvReaderTest_GlslStd450_Inting_IntingInting, Vector) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %v2int %glsl )" +
GetParam().opcode +
R"( %v2int_30_40 %v2int_40_30
%2 = OpCopyObject %v2int %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:vec2<i32> = )" +
GetParam().wgsl_func +
R"( vec2<i32>(30i, 40i), vec2<i32>(40i, 30i)
%3:vec2<i32> = let %2
ret
}
}
)");
}
TEST_P(SpirvReaderTest_GlslStd450_Inting_IntingIntingInting, Scalar) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %int %glsl )" +
GetParam().opcode +
R"( %int_30 %int_35 %int_40
%2 = OpCopyObject %int %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:i32 = )" + GetParam().wgsl_func +
R"( 30i, 35i, 40i
%3:i32 = let %2
ret
}
}
)");
}
TEST_P(SpirvReaderTest_GlslStd450_Inting_IntingIntingInting, Vector) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %v2int %glsl )" +
GetParam().opcode +
R"( %v2int_30_40 %v2int_40_30 %v2int_35_35
%2 = OpCopyObject %v2int %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:vec2<i32> = )" +
GetParam().wgsl_func +
R"( vec2<i32>(30i, 40i), vec2<i32>(40i, 30i), vec2<i32>(35i)
%3:vec2<i32> = let %2
ret
}
}
)");
}
INSTANTIATE_TEST_SUITE_P(SpirvReader,
SpirvReaderTest_GlslStd450_Inting_Inting,
::testing::Values(GlslStd450Case{"SAbs", "abs"},
GlslStd450Case{"FindILsb", "firstTrailingBit"},
GlslStd450Case{"FindSMsb", "firstLeadingBit"},
GlslStd450Case{"SSign", "sign"}));
INSTANTIATE_TEST_SUITE_P(SpirvReader,
SpirvReaderTest_GlslStd450_Inting_Inting_SignednessCoercing,
::testing::Values(GlslStd450Case{"SSign", "sign"}));
INSTANTIATE_TEST_SUITE_P(SpirvReader,
SpirvReaderTest_GlslStd450_Inting_IntingInting,
::testing::Values(GlslStd450Case{"SMax", "max"},
GlslStd450Case{"SMin", "min"}));
INSTANTIATE_TEST_SUITE_P(SpirvReader,
SpirvReaderTest_GlslStd450_Inting_IntingIntingInting,
::testing::Values(GlslStd450Case{"SClamp", "clamp"}));
TEST_P(SpirvReaderTest_GlslStd450_Uinting_Uinting, Scalar) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %uint %glsl )" +
GetParam().opcode +
R"( %uint_10
%2 = OpCopyObject %uint %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:u32 = )" + GetParam().wgsl_func +
R"( 10u
%3:u32 = let %2
ret
}
}
)");
}
TEST_P(SpirvReaderTest_GlslStd450_Uinting_Uinting, Vector) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %v2uint %glsl )" +
GetParam().opcode +
R"( %v2uint_10_20
%2 = OpCopyObject %v2uint %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:vec2<u32> = )" +
GetParam().wgsl_func +
R"( vec2<u32>(10u, 20u)
%3:vec2<u32> = let %2
ret
}
}
)");
}
TEST_P(SpirvReaderTest_GlslStd450_Uinting_UintingUinting, Scalar) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %uint %glsl )" +
GetParam().opcode + R"( %uint_10 %uint_15
%2 = OpCopyObject %uint %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:u32 = )" + GetParam().wgsl_func +
R"( 10u, 15u
%3:u32 = let %2
ret
}
}
)");
}
TEST_P(SpirvReaderTest_GlslStd450_Uinting_UintingUinting, Vector) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %v2uint %glsl )" +
GetParam().opcode +
R"( %v2uint_10_20 %v2uint_20_10
%2 = OpCopyObject %v2uint %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:vec2<u32> = )" +
GetParam().wgsl_func +
R"( vec2<u32>(10u, 20u), vec2<u32>(20u, 10u)
%3:vec2<u32> = let %2
ret
}
}
)");
}
TEST_P(SpirvReaderTest_GlslStd450_Uinting_UintingUintingUinting, Scalar) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %uint %glsl )" +
GetParam().opcode + R"( %uint_10 %uint_15 %uint_20
%2 = OpCopyObject %uint %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:u32 = )" + GetParam().wgsl_func +
R"( 10u, 15u, 20u
%3:u32 = let %2
ret
}
}
)");
}
TEST_P(SpirvReaderTest_GlslStd450_Uinting_UintingUintingUinting, Vector) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %v2uint %glsl )" +
GetParam().opcode +
R"( %v2uint_10_20 %v2uint_20_10 %v2uint_15_15
%2 = OpCopyObject %v2uint %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:vec2<u32> = )" +
GetParam().wgsl_func +
R"( vec2<u32>(10u, 20u), vec2<u32>(20u, 10u), vec2<u32>(15u)
%3:vec2<u32> = let %2
ret
}
}
)");
}
INSTANTIATE_TEST_SUITE_P(SpirvReader,
SpirvReaderTest_GlslStd450_Uinting_Uinting,
::testing::Values(GlslStd450Case{"FindILsb", "firstTrailingBit"},
GlslStd450Case{"FindUMsb", "firstLeadingBit"}));
INSTANTIATE_TEST_SUITE_P(SpirvReader,
SpirvReaderTest_GlslStd450_Uinting_UintingUinting,
::testing::Values(GlslStd450Case{"UMax", "max"},
GlslStd450Case{"UMin", "min"}));
INSTANTIATE_TEST_SUITE_P(SpirvReader,
SpirvReaderTest_GlslStd450_Uinting_UintingUintingUinting,
::testing::Values(GlslStd450Case{"UClamp", "clamp"}));
// Test Normalize. WGSL does not have a scalar form of the normalize builtin.
// So we have to test it separately, as it does not fit the patterns tested
// above.
TEST_F(SpirvReaderTest, DISABLED_Normalize_Scalar) {
// Scalar normalize maps to sign.
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %float %glsl Normalize %float_50
%2 = OpCopyObject %float %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:f32 = sign 50.0f
%3:f32 = let %2
ret
}
}
)");
}
TEST_F(SpirvReaderTest, DISABLED_Normalize_Vector2) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %v2float %glsl Normalize %v2float_50_60
%2 = OpCopyObject %v2float %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:vec2<f32> = normalize vec2<f32>(50.0f, 60.0f)
%3:vec2<f32> = let %2
ret
}
}
)");
}
TEST_F(SpirvReaderTest, DISABLED_Normalize_Vector3) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %v3float %glsl Normalize %v3float_50_60_70
%2 = OpCopyObject %v3float %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:vec3<f32> = normalize vec3<f32>(50.0f, 60.0f, 70.0f)
%3:vec3<f32> = let %2
ret
}
}
)");
}
TEST_F(SpirvReaderTest, DISABLED_Normalize_Vector4) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %v4float %glsl Normalize %v4float_50_50_50_50
%2 = OpCopyObject %v4float %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:vec4<f32> = normalize vec4<f32>(50.0f)
%3:vec4<f32> = let %2
ret
}
}
)");
}
// Check that we convert signedness of operands and result type.
// This is needed for each of the integer-based extended instructions.
TEST_F(SpirvReaderTest, DISABLED_RectifyOperandsAndResult_SAbs) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %uint %glsl SAbs %uint_10
%2 = OpExtInst %v2uint %glsl SAbs %v2uint_10_20
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
let x_1 = bitcast<u32>(abs(bitcast<i32>(u1)));
let x_2 = bitcast<vec2u>(abs(bitcast<vec2i>(v2u1)));
}
}
)");
}
TEST_F(SpirvReaderTest, DISABLED_RectifyOperandsAndResult_SMax) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %uint %glsl SMax %uint_10 %uint_15
%2 = OpExtInst %v2uint %glsl SMax %v2uint_10_20 %v2uint_20_10
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
let x_1 = bitcast<u32>(max(bitcast<i32>(u1), bitcast<i32>(u2)));
let x_2 = bitcast<vec2u>(max(bitcast<vec2i>(v2u1), bitcast<vec2i>(v2u2)));
}
}
)");
}
TEST_F(SpirvReaderTest, DISABLED_RectifyOperandsAndResult_SMin) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %uint %glsl SMin %uint_10 %uint_15
%2 = OpExtInst %v2uint %glsl SMin %v2uint_10_20 %v2uint_20_10
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
let x_1 = bitcast<u32>(min(bitcast<i32>(u1), bitcast<i32>(u2)));
let x_2 = bitcast<vec2u>(min(bitcast<vec2i>(v2u1), bitcast<vec2i>(v2u2)));
}
}
)");
}
TEST_F(SpirvReaderTest, DISABLED_RectifyOperandsAndResult_SClamp) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %uint %glsl SClamp %uint_10 %int_35 %uint_20
%2 = OpExtInst %v2uint %glsl SClamp %v2uint_10_20 %v2int_40_30 %v2uint_15_15
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
let x_1 = bitcast<u32>(clamp(bitcast<i32>(u1), i2, bitcast<i32>(u3)));
let x_2 = bitcast<vec2u>(clamp(bitcast<vec2i>(v2u1), v2i2, bitcast<vec2i>(v2u3)));
}
}
)");
}
TEST_F(SpirvReaderTest, DISABLED_RectifyOperandsAndResult_UMax) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %int %glsl UMax %int_30 %int_35
%2 = OpExtInst %v2int %glsl UMax %v2int_30_40 %v2int_40_30
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
let x_1 = bitcast<i32>(max(bitcast<u32>(i1), bitcast<u32>(i2)));
let x_2 = bitcast<vec2i>(max(bitcast<vec2u>(v2i1), bitcast<vec2u>(v2i2)));
}
}
)");
}
TEST_F(SpirvReaderTest, DISABLED_RectifyOperandsAndResult_UMin) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %int %glsl UMin %int_30 %int_35
%2 = OpExtInst %v2int %glsl UMin %v2int_30_40 %v2int_40_30
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
let x_1 = bitcast<i32>(min(bitcast<u32>(i1), bitcast<u32>(i2)));
let x_2 = bitcast<vec2i>(min(bitcast<vec2u>(v2i1), bitcast<vec2u>(v2i2)));
}
}
)");
}
TEST_F(SpirvReaderTest, DISABLED_RectifyOperandsAndResult_UClamp) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %int %glsl UClamp %int_30 %uint_15 %int_40
%2 = OpExtInst %v2int %glsl UClamp %v2int_30_40 %v2uint_20_10 %v2int_35_35
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
let x_1 = bitcast<i32>(clamp(bitcast<u32>(i1), u2, bitcast<u32>(i3)));
let x_2 = bitcast<vec2i>(clamp(bitcast<vec2u>(v2i1), v2u2, bitcast<vec2u>(v2i3)));
}
}
)");
}
TEST_F(SpirvReaderTest, DISABLED_RectifyOperandsAndResult_FindILsb) {
// Check conversion of:
// signed results to unsigned result to match first arg.
// unsigned results to signed result to match first arg.
// This is the first extended instruction we've supported which goes both
// ways.
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %uint %glsl FindILsb %int_30
%2 = OpExtInst %v2uint %glsl FindILsb %v2int_30_40
%3 = OpExtInst %int %glsl FindILsb %uint_10
%4 = OpExtInst %v2int %glsl FindILsb %v2uint_10_20
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
let x_1 = bitcast<u32>(firstTrailingBit(i1));
let x_2 = bitcast<vec2u>(firstTrailingBit(v2i1));
let x_3 = bitcast<i32>(firstTrailingBit(u1));
let x_4 = bitcast<vec2i>(firstTrailingBit(v2u1));
}
}
)");
}
TEST_F(SpirvReaderTest, DISABLED_RectifyOperandsAndResult_FindSMsb) {
// Check signedness conversion of arguments and results.
// SPIR-V signed arg -> keep it
// signed result -> keep it
// unsigned result -> cast result to unsigned
//
// SPIR-V unsigned arg -> cast it to signed
// signed result -> keept it
// unsigned result -> cast result to unsigned
EXPECT_IR(Preamble() + R"(
; signed arg
; signed result
%1 = OpExtInst %int %glsl FindSMsb %int_30
%2 = OpExtInst %v2int %glsl FindSMsb %v2int_30_40
; signed arg
; unsigned result
%3 = OpExtInst %uint %glsl FindSMsb %int_30
%4 = OpExtInst %v2uint %glsl FindSMsb %v2int_30_40
; unsigned arg
; signed result
%5 = OpExtInst %int %glsl FindSMsb %uint_10
%6 = OpExtInst %v2int %glsl FindSMsb %v2uint_10_20
; unsigned arg
; unsigned result
%7 = OpExtInst %uint %glsl FindSMsb %uint_10
%8 = OpExtInst %v2uint %glsl FindSMsb %v2uint_10_20
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
let x_1 = firstLeadingBit(i1);
let x_2 = firstLeadingBit(v2i1);
let x_3 = bitcast<u32>(firstLeadingBit(i1));
let x_4 = bitcast<vec2u>(firstLeadingBit(v2i1));
let x_5 = firstLeadingBit(bitcast<i32>(u1));
let x_6 = firstLeadingBit(bitcast<vec2i>(v2u1));
let x_7 = bitcast<u32>(firstLeadingBit(bitcast<i32>(u1)));
let x_8 = bitcast<vec2u>(firstLeadingBit(bitcast<vec2i>(v2u1)));
}
}
)");
}
TEST_F(SpirvReaderTest, DISABLED_RectifyOperandsAndResult_FindUMsb) {
// Check signedness conversion of arguments and results.
// SPIR-V signed arg -> cast arg to unsigned
// signed result -> cast result to signed
// unsigned result -> keep it
//
// SPIR-V unsigned arg -> keep it
// signed result -> cast result to signed
// unsigned result -> keep it
EXPECT_IR(Preamble() + R"(
; signed arg
; signed result
%1 = OpExtInst %int %glsl FindUMsb %int_30
%2 = OpExtInst %v2int %glsl FindUMsb %v2int_30_40
; signed arg
; unsigned result
%3 = OpExtInst %uint %glsl FindUMsb %int_30
%4 = OpExtInst %v2uint %glsl FindUMsb %v2int_30_40
; unsigned arg
; signed result
%5 = OpExtInst %int %glsl FindUMsb %uint_10
%6 = OpExtInst %v2int %glsl FindUMsb %v2uint_10_20
; unsigned arg
; unsigned result
%7 = OpExtInst %uint %glsl FindUMsb %uint_10
%8 = OpExtInst %v2uint %glsl FindUMsb %v2uint_10_20
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
let x_1 = bitcast<i32>(firstLeadingBit(bitcast<u32>(i1)));
let x_2 = bitcast<vec2i>(firstLeadingBit(bitcast<vec2u>(v2i1)));
let x_3 = firstLeadingBit(bitcast<u32>(i1));
let x_4 = firstLeadingBit(bitcast<vec2u>(v2i1));
let x_5 = bitcast<i32>(firstLeadingBit(u1));
let x_6 = bitcast<vec2i>(firstLeadingBit(v2u1));
let x_7 = firstLeadingBit(u1);
let x_8 = firstLeadingBit(v2u1);
}
}
)");
}
struct DataPackingCase {
std::string opcode;
std::string wgsl_func;
uint32_t vec_size;
};
inline std::ostream& operator<<(std::ostream& out, DataPackingCase c) {
out << "DataPacking(" << c.opcode << ")";
return out;
}
using SpirvReaderTest_GlslStd450_DataPacking = SpirvReaderTestWithParam<DataPackingCase>;
TEST_P(SpirvReaderTest_GlslStd450_DataPacking, Valid) {
auto param = GetParam();
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %uint %glsl )" +
param.opcode +
(param.vec_size == 2 ? " %v2float_50_60" : " %v4float_50_50_50_50") + R"(
%2 = OpCopyObject %uint %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:u32 = )" + param.wgsl_func +
" vec" + std::to_string(param.vec_size) + "<f32>(50.0f" +
(param.vec_size == 4 ? "" : ", 60.0f") + R"()
%3:u32 = let %2
ret
}
}
)");
}
INSTANTIATE_TEST_SUITE_P(SpirvReader,
SpirvReaderTest_GlslStd450_DataPacking,
::testing::ValuesIn(std::vector<DataPackingCase>{
{"PackSnorm4x8", "pack4x8snorm", 4},
{"PackUnorm4x8", "pack4x8unorm", 4},
{"PackSnorm2x16", "pack2x16snorm", 2},
{"PackUnorm2x16", "pack2x16unorm", 2},
{"PackHalf2x16", "pack2x16float", 2}}));
using SpirvReaderTest_GlslStd450_DataUnpacking = SpirvReaderTestWithParam<DataPackingCase>;
TEST_P(SpirvReaderTest_GlslStd450_DataUnpacking, Valid) {
auto param = GetParam();
auto type = param.vec_size == 2 ? "%v2float" : "%v4float";
auto wgsl_type = "vec" + std::to_string(param.vec_size) + "<f32>";
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst )" +
type + std::string(" %glsl ") + param.opcode + R"( %uint_10
%2 = OpCopyObject )" +
type + R"( %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:)" + wgsl_type +
" = " + param.wgsl_func +
R"( 10u
%3:)" + wgsl_type +
R"( = let %2
ret
}
}
)");
}
INSTANTIATE_TEST_SUITE_P(SpirvReader,
SpirvReaderTest_GlslStd450_DataUnpacking,
::testing::ValuesIn(std::vector<DataPackingCase>{
{"UnpackSnorm4x8", "unpack4x8snorm", 4},
{"UnpackUnorm4x8", "unpack4x8unorm", 4},
{"UnpackSnorm2x16", "unpack2x16snorm", 2},
{"UnpackUnorm2x16", "unpack2x16unorm", 2},
{"UnpackHalf2x16", "unpack2x16float", 2}}));
TEST_F(SpirvReaderTest, DISABLED_GlslStd450_Refract_Scalar) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %float %glsl Refract %float_50 %float_60 %float_70
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
let x_1 = refract(vec2f(f1, 0.0f), vec2f(f2, 0.0f), f3).x;
}
}
)");
}
TEST_F(SpirvReaderTest, DISABLED_GlslStd450_Refract_Vector) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %v2float %glsl Refract %v2float_50_60 %v2float_60_50 %float_70
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
let x_1 = refract(v2f1, v2f2, f3);
}
}
)");
}
TEST_F(SpirvReaderTest, DISABLED_GlslStd450_FaceForward_Scalar) {
// The %99 sum only has one use. Ensure it is evaluated only once by
// making a let-declaration for it, since it is the normal operand to
// the builtin function, and code generation uses it twice.
EXPECT_IR(Preamble() + R"(
%99 = OpFAdd %float %float_50 %float_50 ; normal operand has only one use
%1 = OpExtInst %float %glsl FaceForward %99 %float_60 %float_70
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
let x_1 = select(-(x_99), x_99, ((f2 * f3) < 0.0f));
}
}
)");
}
TEST_F(SpirvReaderTest, DISABLED_GlslStd450_FaceForward_Vector) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %v2float %glsl FaceForward %v2float_50_60 %v2float_60_50 %v2float_70_70
%2 = OpCopyObject %v2float %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:vec2<f32> = faceForward vec2<f32>(50.0f, 60.0f), vec2<f32>(60.0f, 50.0f), vec2<f32>(70.0f)
%2:vec2<f32> = let %2
ret
}
}
)");
}
TEST_F(SpirvReaderTest, DISABLED_GlslStd450_Reflect_Scalar) {
EXPECT_IR(Preamble() + R"(
%98 = OpFAdd %float %float_50 %float_50 ; has only one use
%99 = OpFAdd %float %float_60 %float_60 ; has only one use
%1 = OpExtInst %float %glsl Reflect %98 %99
%2 = OpCopyObject %float %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:f32 = (x_98 - (2.0f * (x_99 * (x_99 * x_98))));
%3:f32 = let %2
}
}
)");
}
TEST_F(SpirvReaderTest, DISABLED_GlslStd450_Reflect_Vector) {
EXPECT_IR(Preamble() + R"(
%98 = OpFAdd %v2float %v2float_50_60 %v2float_50_60
%99 = OpFAdd %v2float %v2float_60_50 %v2float_60_50
%1 = OpExtInst %v2float %glsl Reflect %98 %99
%2 = OpCopyObject %v2float %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:vec2<f32> = add vec2<f32>(50.0f, 60.0f), vec2<f32>(50.0f, 60.0f)
%3:vec2<f32> = add vec2<f32>(60.0f, 50.0f), vec2<f32>(60.0f, 50.0f)
%4:vec2<f32> = reflect %2, %3
%5:vec2<f32> = let %4
ret
}
}
)");
}
// For ldexp with signed second argument, see above.
TEST_F(SpirvReaderTest, DISABLED_GlslStd450_Ldexp_Scalar_Float_Uint) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %float %glsl Ldexp %float_50 %uint_10
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
let x_1 = ldexp(f1, i32(u1));
}
}
)");
}
TEST_F(SpirvReaderTest, DISABLED_GlslStd450_Ldexp_Vector_Floatvec_Uintvec) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %v2float %glsl Ldexp %v2float_50_60 %v2uint_10_20
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
let x_1 = ldexp(v2f1, vec2i(v2u1));
}
}
)");
}
struct DeterminantData {
std::string in;
std::string out;
};
inline std::ostream& operator<<(std::ostream& out, DeterminantData c) {
out << "Determinant(" << c.in << ")";
return out;
}
using SpirvReaderTest_GlslStd450_Determinant = SpirvReaderTestWithParam<DeterminantData>;
TEST_P(SpirvReaderTest_GlslStd450_Determinant, DISABLED_Test) {
auto param = GetParam();
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %float %glsl Determinant %)" +
param.in + R"(
%2 = OpCopyObject %float %1
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:f32 = determinant )" +
param.out + R"(
%3:f32 = let %2
ret
}
}
)");
}
INSTANTIATE_TEST_SUITE_P(
SpirvReader,
SpirvReaderTest_GlslStd450_Determinant,
::testing::Values(DeterminantData{"m2x2f1", "mat2x2<f32>(vec2<f32>(50.0f, 60.0f))"},
DeterminantData{"m3x3f1", "mat3x3<f32>(vec3<f32>(50.0f, 60.0f, 70.0f))"},
DeterminantData{"m4x4f1", "mat4x4<f32>(vec4<f32>(50.0f))"}));
TEST_F(SpirvReaderTest, DISABLED_GlslStd450_MatrixInverse_mat2x2) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %mat2v2float %glsl MatrixInverse %mat2v2float_50_60
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
let s = (1.0f / determinant(m2x2f1));
let x_1 = mat2x2f(vec2f((s * m2x2f1[1u][1u]),
(-(s) * m2x2f1[0u][1u])),
vec2f((-(s) * m2x2f1[1u][0u]),
(s * m2x2f1[0u][0u])));
}
}
)");
}
TEST_F(SpirvReaderTest, DISABLED_GlslStd450_MatrixInverse_mat3x3) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %mat3v3float %glsl MatrixInverse %mat3v3float_50_60_70
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
let s = (1.0f / determinant(m3x3f1));
let x_1 = (s * mat3x3f(vec3f(((m3x3f1[1u][1u] * m3x3f1[2u][2u]) -
(m3x3f1[1u][2u] * m3x3f1[2u][1u])), ((m3x3f1[0u][2u] * m3x3f1[2u][1u]) - (m3x3f1[0u][1u]
* m3x3f1[2u][2u])), ((m3x3f1[0u][1u] * m3x3f1[1u][2u]) - (m3x3f1[0u][2u] *
m3x3f1[1u][1u]))), vec3f(((m3x3f1[1u][2u] * m3x3f1[2u][0u]) - (m3x3f1[1u][0u] *
m3x3f1[2u][2u])), ((m3x3f1[0u][0u] * m3x3f1[2u][2u]) - (m3x3f1[0u][2u] *
m3x3f1[2u][0u])), ((m3x3f1[0u][2u] * m3x3f1[1u][0u]) - (m3x3f1[0u][0u] *
m3x3f1[1u][2u]))), vec3f(((m3x3f1[1u][0u] * m3x3f1[2u][1u]) - (m3x3f1[1u][1u] *
m3x3f1[2u][0u])), ((m3x3f1[0u][1u] * m3x3f1[2u][0u]) - (m3x3f1[0u][0u] *
m3x3f1[2u][1u])), ((m3x3f1[0u][0u] * m3x3f1[1u][1u]) - (m3x3f1[0u][1u] *
m3x3f1[1u][0u])))));
}
}
)");
}
TEST_F(SpirvReaderTest, DISABLED_GlslStd450_MatrixInverse_mat4x4) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %mat4v4float %glsl MatrixInverse %mat4v4float_50_50_50_50
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
let s = (1.0f / determinant(m4x4f1));
let x_1 = (s * mat4x4f(vec4f((((m4x4f1[1u][1u] * ((m4x4f1[2u][2u] *
m4x4f1[3u][3u]) - (m4x4f1[2u][3u] * m4x4f1[3u][2u]))) - (m4x4f1[1u][2u] *
((m4x4f1[2u][1u] * m4x4f1[3u][3u]) - (m4x4f1[2u][3u] * m4x4f1[3u][1u])))) +
(m4x4f1[1u][3u] * ((m4x4f1[2u][1u] * m4x4f1[3u][2u]) - (m4x4f1[2u][2u] *
m4x4f1[3u][1u])))), (((-(m4x4f1[0u][1u]) * ((m4x4f1[2u][2u] * m4x4f1[3u][3u]) -
(m4x4f1[2u][3u] * m4x4f1[3u][2u]))) + (m4x4f1[0u][2u] * ((m4x4f1[2u][1u] *
m4x4f1[3u][3u]) - (m4x4f1[2u][3u] * m4x4f1[3u][1u])))) - (m4x4f1[0u][3u] *
((m4x4f1[2u][1u] * m4x4f1[3u][2u]) - (m4x4f1[2u][2u] * m4x4f1[3u][1u])))),
(((m4x4f1[0u][1u] * ((m4x4f1[1u][2u] * m4x4f1[3u][3u]) - (m4x4f1[1u][3u] *
m4x4f1[3u][2u]))) - (m4x4f1[0u][2u] * ((m4x4f1[1u][1u] * m4x4f1[3u][3u]) -
(m4x4f1[1u][3u] * m4x4f1[3u][1u])))) + (m4x4f1[0u][3u] * ((m4x4f1[1u][1u] *
m4x4f1[3u][2u]) - (m4x4f1[1u][2u] * m4x4f1[3u][1u])))), (((-(m4x4f1[0u][1u]) *
((m4x4f1[1u][2u] * m4x4f1[2u][3u]) - (m4x4f1[1u][3u] * m4x4f1[2u][2u]))) +
(m4x4f1[0u][2u] * ((m4x4f1[1u][1u] * m4x4f1[2u][3u]) - (m4x4f1[1u][3u] *
m4x4f1[2u][1u])))) - (m4x4f1[0u][3u] * ((m4x4f1[1u][1u] * m4x4f1[2u][2u]) -
(m4x4f1[1u][2u] * m4x4f1[2u][1u]))))), vec4f((((-(m4x4f1[1u][0u]) * ((m4x4f1[2u][2u]
* m4x4f1[3u][3u]) - (m4x4f1[2u][3u] * m4x4f1[3u][2u]))) + (m4x4f1[1u][2u] *
((m4x4f1[2u][0u] * m4x4f1[3u][3u]) - (m4x4f1[2u][3u] * m4x4f1[3u][0u])))) -
(m4x4f1[1u][3u] * ((m4x4f1[2u][0u] * m4x4f1[3u][2u]) - (m4x4f1[2u][2u] *
m4x4f1[3u][0u])))), (((m4x4f1[0u][0u] * ((m4x4f1[2u][2u] * m4x4f1[3u][3u]) -
(m4x4f1[2u][3u] * m4x4f1[3u][2u]))) - (m4x4f1[0u][2u] * ((m4x4f1[2u][0u] *
m4x4f1[3u][3u]) - (m4x4f1[2u][3u] * m4x4f1[3u][0u])))) + (m4x4f1[0u][3u] *
((m4x4f1[2u][0u] * m4x4f1[3u][2u]) - (m4x4f1[2u][2u] * m4x4f1[3u][0u])))),
(((-(m4x4f1[0u][0u]) * ((m4x4f1[1u][2u] * m4x4f1[3u][3u]) - (m4x4f1[1u][3u] *
m4x4f1[3u][2u]))) + (m4x4f1[0u][2u] * ((m4x4f1[1u][0u] * m4x4f1[3u][3u]) -
(m4x4f1[1u][3u] * m4x4f1[3u][0u])))) - (m4x4f1[0u][3u] * ((m4x4f1[1u][0u] *
m4x4f1[3u][2u]) - (m4x4f1[1u][2u] * m4x4f1[3u][0u])))), (((m4x4f1[0u][0u] *
((m4x4f1[1u][2u] * m4x4f1[2u][3u]) - (m4x4f1[1u][3u] * m4x4f1[2u][2u]))) -
(m4x4f1[0u][2u] * ((m4x4f1[1u][0u] * m4x4f1[2u][3u]) - (m4x4f1[1u][3u] *
m4x4f1[2u][0u])))) + (m4x4f1[0u][3u] * ((m4x4f1[1u][0u] * m4x4f1[2u][2u]) -
(m4x4f1[1u][2u] * m4x4f1[2u][0u]))))), vec4f((((m4x4f1[1u][0u] * ((m4x4f1[2u][1u] *
m4x4f1[3u][3u]) - (m4x4f1[2u][3u] * m4x4f1[3u][1u]))) - (m4x4f1[1u][1u] *
((m4x4f1[2u][0u] * m4x4f1[3u][3u]) - (m4x4f1[2u][3u] * m4x4f1[3u][0u])))) +
(m4x4f1[1u][3u] * ((m4x4f1[2u][0u] * m4x4f1[3u][1u]) - (m4x4f1[2u][1u] *
m4x4f1[3u][0u])))), (((-(m4x4f1[0u][0u]) * ((m4x4f1[2u][1u] * m4x4f1[3u][3u]) -
(m4x4f1[2u][3u] * m4x4f1[3u][1u]))) + (m4x4f1[0u][1u] * ((m4x4f1[2u][0u] *
m4x4f1[3u][3u]) - (m4x4f1[2u][3u] * m4x4f1[3u][0u])))) - (m4x4f1[0u][3u] *
((m4x4f1[2u][0u] * m4x4f1[3u][1u]) - (m4x4f1[2u][1u] * m4x4f1[3u][0u])))),
(((m4x4f1[0u][0u] * ((m4x4f1[1u][1u] * m4x4f1[3u][3u]) - (m4x4f1[1u][3u] *
m4x4f1[3u][1u]))) - (m4x4f1[0u][1u] * ((m4x4f1[1u][0u] * m4x4f1[3u][3u]) -
(m4x4f1[1u][3u] * m4x4f1[3u][0u])))) + (m4x4f1[0u][3u] * ((m4x4f1[1u][0u] *
m4x4f1[3u][1u]) - (m4x4f1[1u][1u] * m4x4f1[3u][0u])))), (((-(m4x4f1[0u][0u]) *
((m4x4f1[1u][1u] * m4x4f1[2u][3u]) - (m4x4f1[1u][3u] * m4x4f1[2u][1u]))) +
(m4x4f1[0u][1u] * ((m4x4f1[1u][0u] * m4x4f1[2u][3u]) - (m4x4f1[1u][3u] *
m4x4f1[2u][0u])))) - (m4x4f1[0u][3u] * ((m4x4f1[1u][0u] * m4x4f1[2u][1u]) -
(m4x4f1[1u][1u] * m4x4f1[2u][0u]))))), vec4f((((-(m4x4f1[1u][0u]) * ((m4x4f1[2u][1u]
* m4x4f1[3u][2u]) - (m4x4f1[2u][2u] * m4x4f1[3u][1u]))) + (m4x4f1[1u][1u] *
((m4x4f1[2u][0u] * m4x4f1[3u][2u]) - (m4x4f1[2u][2u] * m4x4f1[3u][0u])))) -
(m4x4f1[1u][2u] * ((m4x4f1[2u][0u] * m4x4f1[3u][1u]) - (m4x4f1[2u][1u] *
m4x4f1[3u][0u])))), (((m4x4f1[0u][0u] * ((m4x4f1[2u][1u] * m4x4f1[3u][2u]) -
(m4x4f1[2u][2u] * m4x4f1[3u][1u]))) - (m4x4f1[0u][1u] * ((m4x4f1[2u][0u] *
m4x4f1[3u][2u]) - (m4x4f1[2u][2u] * m4x4f1[3u][0u])))) + (m4x4f1[0u][2u] *
((m4x4f1[2u][0u] * m4x4f1[3u][1u]) - (m4x4f1[2u][1u] * m4x4f1[3u][0u])))),
(((-(m4x4f1[0u][0u]) * ((m4x4f1[1u][1u] * m4x4f1[3u][2u]) - (m4x4f1[1u][2u] *
m4x4f1[3u][1u]))) + (m4x4f1[0u][1u] * ((m4x4f1[1u][0u] * m4x4f1[3u][2u]) -
(m4x4f1[1u][2u] * m4x4f1[3u][0u])))) - (m4x4f1[0u][2u] * ((m4x4f1[1u][0u] *
m4x4f1[3u][1u]) - (m4x4f1[1u][1u] * m4x4f1[3u][0u])))), (((m4x4f1[0u][0u] *
((m4x4f1[1u][1u] * m4x4f1[2u][2u]) - (m4x4f1[1u][2u] * m4x4f1[2u][1u]))) -
(m4x4f1[0u][1u] * ((m4x4f1[1u][0u] * m4x4f1[2u][2u]) - (m4x4f1[1u][2u] *
m4x4f1[2u][0u])))) + (m4x4f1[0u][2u] * ((m4x4f1[1u][0u] * m4x4f1[2u][1u]) -
(m4x4f1[1u][1u] * m4x4f1[2u][0u])))))));
}
}
)");
}
TEST_F(SpirvReaderTest, DISABLED_GlslStd450_MatrixInverse_MultipleInScope) {
EXPECT_IR(Preamble() + R"(
%1 = OpExtInst %mat2v2float %glsl MatrixInverse %mat2v2float_50_60
%2 = OpExtInst %mat2v2float %glsl MatrixInverse %mat2v2float_50_60
OpReturn
OpFunctionEnd
)",
R"(
%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
let s = (1.0f / determinant(m2x2f1));
let x_1 = mat2x2f(vec2f((s * m2x2f1[1u][1u]), (-(s) *
m2x2f1[0u][1u])), vec2f((-(s) * m2x2f1[1u][0u]), (s * m2x2f1[0u][0u])));
let s_1 = (1.0f / determinant(m2x2f1));
let x_2 = mat2x2f(vec2f((s_1 * m2x2f1[1u][1u]), (-(s_1) *
m2x2f1[0u][1u])), vec2f((-(s_1) * m2x2f1[1u][0u]), (s_1 * m2x2f1[0u][0u])));
}
}
)");
}
} // namespace
} // namespace tint::spirv::reader