[spirv-writer] Simplify the texture intrinsic tests
This CL removes the complete coverage of the possible input formats
infavor of simpler testing of a few of the inputs. This should be
sufficient coverage and makes the tests easier to read.
The incorrect OpConstantNull for the samplers and textures has also been
removed.
Change-Id: I9cd7d6299f0454bb8e2019968e0422221e4ec183
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/28581
Reviewed-by: Ryan Harrison <rharrison@chromium.org>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
diff --git a/src/writer/spirv/builder.cc b/src/writer/spirv/builder.cc
index 050fd13..795e16d 100644
--- a/src/writer/spirv/builder.cc
+++ b/src/writer/spirv/builder.cc
@@ -597,7 +597,7 @@
Operand::Int(ConvertStorageClass(sc))};
if (var->has_constructor()) {
ops.push_back(Operand::Int(init_id));
- } else {
+ } else if (!var->type()->IsTexture() && !var->type()->IsSampler()) {
// If we don't have a constructor and we're an Output or Private variable
// then WGSL requires an initializer.
if (var->storage_class() == ast::StorageClass::kPrivate ||
diff --git a/src/writer/spirv/builder_intrinsic_test.cc b/src/writer/spirv/builder_intrinsic_test.cc
index e950da4..0efcdf3 100644
--- a/src/writer/spirv/builder_intrinsic_test.cc
+++ b/src/writer/spirv/builder_intrinsic_test.cc
@@ -16,7 +16,10 @@
#include "gtest/gtest.h"
#include "src/ast/call_expression.h"
+#include "src/ast/float_literal.h"
#include "src/ast/identifier_expression.h"
+#include "src/ast/scalar_constructor_expression.h"
+#include "src/ast/sint_literal.h"
#include "src/ast/type/bool_type.h"
#include "src/ast/type/depth_texture_type.h"
#include "src/ast/type/f32_type.h"
@@ -26,6 +29,7 @@
#include "src/ast/type/sampler_type.h"
#include "src/ast/type/u32_type.h"
#include "src/ast/type/vector_type.h"
+#include "src/ast/type_constructor_expression.h"
#include "src/ast/variable.h"
#include "src/context.h"
#include "src/type_determiner.h"
@@ -413,860 +417,743 @@
)");
}
-enum class TextureType { kF32, kI32, kU32 };
-inline std::ostream& operator<<(std::ostream& out, TextureType data) {
- if (data == TextureType::kF32) {
- out << "f32";
- } else if (data == TextureType::kI32) {
- out << "i32";
- } else {
- out << "u32";
- }
- return out;
-}
-
-struct TextureTestParams {
- ast::type::TextureDimension dim;
- TextureType type = TextureType::kF32;
- ast::type::ImageFormat format = ast::type::ImageFormat::kR16Float;
-};
-inline std::ostream& operator<<(std::ostream& out, TextureTestParams data) {
- out << data.dim << "_" << data.type;
- return out;
-}
-
-class Builder_TextureOperation
- : public testing::TestWithParam<TextureTestParams> {
- public:
- Builder_TextureOperation()
- : td_(std::make_unique<TypeDeterminer>(&ctx_, &mod_)),
- b_(std::make_unique<Builder>(&mod_)) {}
-
- TypeDeterminer* td() const { return td_.get(); }
- Context* ctx() { return &ctx_; }
- Builder* b() const { return b_.get(); }
-
- std::unique_ptr<ast::type::Type> get_coords_type(
- ast::type::TextureDimension dim,
- ast::type::Type* type) {
- if (dim == ast::type::TextureDimension::k1d) {
- if (type->IsI32()) {
- return std::make_unique<ast::type::I32Type>();
- } else if (type->IsU32()) {
- return std::make_unique<ast::type::U32Type>();
- } else {
- return std::make_unique<ast::type::F32Type>();
- }
- } else if (dim == ast::type::TextureDimension::k1dArray ||
- dim == ast::type::TextureDimension::k2d) {
- return std::make_unique<ast::type::VectorType>(type, 2);
- } else if (dim == ast::type::TextureDimension::kCubeArray) {
- return std::make_unique<ast::type::VectorType>(type, 4);
- } else {
- return std::make_unique<ast::type::VectorType>(type, 3);
- }
- }
-
- void add_call_param(std::string name,
- ast::type::Type* type,
- ast::ExpressionList* call_params) {
- variables_.push_back(
- std::make_unique<ast::Variable>(name, ast::StorageClass::kNone, type));
- td()->RegisterVariableForTesting(variables_.back().get());
-
- call_params->push_back(std::make_unique<ast::IdentifierExpression>(name));
- ASSERT_TRUE(b()->GenerateGlobalVariable(variables_.back().get()))
- << b()->error();
- }
-
- std::unique_ptr<ast::type::Type> subtype(TextureType type) {
- if (type == TextureType::kF32) {
- return std::make_unique<ast::type::F32Type>();
- }
- if (type == TextureType::kI32) {
- return std::make_unique<ast::type::I32Type>();
- }
- return std::make_unique<ast::type::U32Type>();
- }
-
- std::string texture_line(
- ast::type::TextureDimension dim,
- bool unknown_format,
- TextureType type,
- uint32_t depth_literal,
- uint32_t sampled_literal,
- ast::type::ImageFormat format = ast::type::ImageFormat::kR8Unorm) {
- std::string res = "%6 = OpTypeImage ";
-
- if (type == TextureType::kF32) {
- res += "%1 ";
- } else if (type == TextureType::kU32) {
- res += "%2 ";
- } else {
- res += "%3 ";
- }
-
- if (dim == ast::type::TextureDimension::k1d ||
- dim == ast::type::TextureDimension::k1dArray) {
- res += "1D ";
- } else if (dim == ast::type::TextureDimension::k3d) {
- res += "3D ";
- } else if (dim == ast::type::TextureDimension::kCube ||
- dim == ast::type::TextureDimension::kCubeArray) {
- res += "Cube ";
- } else {
- res += "2D ";
- }
-
- res += std::to_string(depth_literal) + " ";
-
- if (dim == ast::type::TextureDimension::k1dArray ||
- dim == ast::type::TextureDimension::k2dArray ||
- dim == ast::type::TextureDimension::kCubeArray) {
- res += "1 ";
- } else {
- res += "0 ";
- }
-
- res += "0 ";
- res += std::to_string(sampled_literal) + " ";
-
- if (unknown_format) {
- res += "Unknown\n";
- } else if (format == ast::type::ImageFormat::kR16Float) {
- res += "R16f\n";
- } else if (format == ast::type::ImageFormat::kR16Sint) {
- res += "R16i\n";
- } else {
- res += "R8\n";
- }
-
- return res;
- }
-
- private:
- Context ctx_;
- ast::Module mod_;
- std::unique_ptr<TypeDeterminer> td_;
- std::unique_ptr<Builder> b_;
- std::vector<std::unique_ptr<ast::Variable>> variables_;
-};
-
-class Builder_TextureLoad : public Builder_TextureOperation {
- public:
- std::string generate_type_str(ast::type::TextureDimension dim,
- ast::type::ImageFormat format,
- bool unknown_format,
- TextureType type,
- uint32_t depth_literal,
- uint32_t sampled_literal,
- uint32_t type_id,
- uint32_t coords_length) {
- std::string type_str = R"(%1 = OpTypeFloat 32
-%2 = OpTypeInt 32 0
-%3 = OpTypeInt 32 1
-)";
-
- type_str += texture_line(dim, unknown_format, type, depth_literal,
- sampled_literal, format);
-
- type_str += R"(%5 = OpTypePointer Private %6
-%7 = OpConstantNull %6
-%4 = OpVariable %5 Private %7
-)";
-
- if (coords_length > 1) {
- type_str += "%10 = OpTypeVector %3 " + std::to_string(coords_length) +
- "\n" +
- R"(%9 = OpTypePointer Private %10
-%11 = OpConstantNull %10
-%8 = OpVariable %9 Private %11
-%13 = OpTypePointer Private %3
-%14 = OpConstantNull %3
-%12 = OpVariable %13 Private %14
-%16 = OpTypeVector %)" +
- std::to_string(type_id) + " 4\n";
- } else {
- type_str += R"(%9 = OpTypePointer Private %3
-%10 = OpConstantNull %3
-%8 = OpVariable %9 Private %10
-%11 = OpVariable %9 Private %10
-%13 = OpTypeVector %)" +
- std::to_string(type_id) + " 4\n";
- }
-
- return type_str;
- }
-
- std::string generate_ops_str(uint32_t coords_length, std::string op_name) {
- if (coords_length == 1) {
- return R"(%14 = OpLoad %6 %4
-%15 = OpLoad %3 %8
-%16 = OpLoad %3 %11
-%12 = )" + op_name +
- R"( %13 %14 %15 Lod %16
-)";
- }
-
- return R"(%17 = OpLoad %6 %4
-%18 = OpLoad %10 %8
-%19 = OpLoad %3 %12
-%15 = )" + op_name +
- R"( %16 %17 %18 Lod %19
-)";
- }
-};
-
-TEST_P(Builder_TextureLoad, StorageReadonly) {
- auto dim = GetParam().dim;
- auto type = GetParam().type;
- auto format = GetParam().format;
-
+TEST_F(BuilderTest, Call_TextureLoad_Storage_RO_1d) {
ast::type::F32Type f32;
- b()->GenerateTypeIfNeeded(&f32);
- ast::type::U32Type u32;
- b()->GenerateTypeIfNeeded(&u32);
ast::type::I32Type i32;
- b()->GenerateTypeIfNeeded(&i32);
+ ast::type::StorageTextureType s(ast::type::TextureDimension::k1d,
+ ast::type::StorageAccess::kRead,
+ ast::type::ImageFormat::kR16Float);
- uint32_t type_id = 1;
- if (type == TextureType::kU32) {
- type_id = 2;
- } else if (type == TextureType::kI32) {
- type_id = 3;
- }
+ Context ctx;
+ ast::Module mod;
+ TypeDeterminer td(&ctx, &mod);
+ Builder b(&mod);
- auto coords_type = get_coords_type(dim, &i32);
+ ASSERT_TRUE(td.DetermineStorageTextureSubtype(&s)) << td.error();
- uint32_t coords_length = 1;
- if (coords_type->IsVector()) {
- coords_length = coords_type->AsVector()->size();
- }
+ b.push_function(Function{});
- auto* texture_type =
- ctx()->type_mgr().Get(std::make_unique<ast::type::StorageTextureType>(
- dim, ast::type::StorageAccess::kRead, format));
-
- EXPECT_TRUE(td()->Determine());
+ ast::Variable tex("texture", ast::StorageClass::kNone, &s);
+ td.RegisterVariableForTesting(&tex);
+ ASSERT_TRUE(b.GenerateGlobalVariable(&tex)) << b.error();
ast::ExpressionList call_params;
- b()->push_function(Function{});
-
- add_call_param("texture", texture_type, &call_params);
- add_call_param("coords", coords_type.get(), &call_params);
- add_call_param("lod", &i32, &call_params);
+ call_params.push_back(std::make_unique<ast::IdentifierExpression>("texture"));
+ call_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 1.0)));
+ call_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::SintLiteral>(&i32, 2)));
ast::CallExpression expr(
std::make_unique<ast::IdentifierExpression>("textureLoad"),
std::move(call_params));
- EXPECT_TRUE(td()->DetermineResultType(&expr));
+ EXPECT_TRUE(td.DetermineResultType(&expr)) << td.error();
+ EXPECT_EQ(b.GenerateExpression(&expr), 5u) << b.error();
- if (coords_length > 1) {
- EXPECT_EQ(b()->GenerateExpression(&expr), 15u) << b()->error();
- } else {
- EXPECT_EQ(b()->GenerateExpression(&expr), 12u) << b()->error();
- }
+ EXPECT_EQ(DumpInstructions(b.types()),
+ R"(%4 = OpTypeFloat 32
+%3 = OpTypeImage %4 1D 0 0 0 2 R16f
+%2 = OpTypePointer Private %3
+%1 = OpVariable %2 Private
+%6 = OpTypeVector %4 4
+%8 = OpConstant %4 1
+%9 = OpTypeInt 32 1
+%10 = OpConstant %9 2
+)");
- EXPECT_EQ(DumpInstructions(b()->types()),
- generate_type_str(dim, format, false, type, 0, 2, type_id,
- coords_length));
-
- EXPECT_EQ(DumpInstructions(b()->functions()[0].instructions()),
- generate_ops_str(coords_length, "OpImageRead"));
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ R"(%7 = OpLoad %3 %1
+%5 = OpImageRead %6 %7 %8 Lod %10
+)");
}
-TEST_P(Builder_TextureLoad, Sampled) {
- auto dim = GetParam().dim;
- auto type = GetParam().type;
- auto format = GetParam().format;
-
+TEST_F(BuilderTest, Call_TextureLoad_Storage_RO_2d) {
ast::type::F32Type f32;
- b()->GenerateTypeIfNeeded(&f32);
- ast::type::U32Type u32;
- b()->GenerateTypeIfNeeded(&u32);
ast::type::I32Type i32;
- b()->GenerateTypeIfNeeded(&i32);
+ ast::type::VectorType vec2(&f32, 2);
+ ast::type::StorageTextureType s(ast::type::TextureDimension::k2d,
+ ast::type::StorageAccess::kRead,
+ ast::type::ImageFormat::kR16Float);
- uint32_t type_id = 1;
- if (type == TextureType::kU32) {
- type_id = 2;
- } else if (type == TextureType::kI32) {
- type_id = 3;
- }
+ Context ctx;
+ ast::Module mod;
+ TypeDeterminer td(&ctx, &mod);
+ Builder b(&mod);
- auto coords_type = get_coords_type(dim, &i32);
+ ASSERT_TRUE(td.DetermineStorageTextureSubtype(&s)) << td.error();
- uint32_t coords_length = 1;
- if (coords_type->IsVector()) {
- coords_length = coords_type->AsVector()->size();
- }
+ b.push_function(Function{});
- std::unique_ptr<ast::type::Type> s = subtype(type);
- auto* texture_type = ctx()->type_mgr().Get(
- std::make_unique<ast::type::SampledTextureType>(dim, s.get()));
+ ast::Variable tex("texture", ast::StorageClass::kNone, &s);
+ td.RegisterVariableForTesting(&tex);
+ ASSERT_TRUE(b.GenerateGlobalVariable(&tex)) << b.error();
- EXPECT_TRUE(td()->Determine());
+ ast::ExpressionList vals;
+ vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 1.0)));
+ vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
ast::ExpressionList call_params;
- b()->push_function(Function{});
-
- add_call_param("texture", texture_type, &call_params);
- add_call_param("coords", coords_type.get(), &call_params);
- add_call_param("lod", &i32, &call_params);
+ call_params.push_back(std::make_unique<ast::IdentifierExpression>("texture"));
+ call_params.push_back(
+ std::make_unique<ast::TypeConstructorExpression>(&vec2, std::move(vals)));
+ call_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::SintLiteral>(&i32, 2)));
ast::CallExpression expr(
std::make_unique<ast::IdentifierExpression>("textureLoad"),
std::move(call_params));
- EXPECT_TRUE(td()->DetermineResultType(&expr));
+ EXPECT_TRUE(td.DetermineResultType(&expr)) << td.error();
+ EXPECT_EQ(b.GenerateExpression(&expr), 5u) << b.error();
- if (coords_length > 1) {
- EXPECT_EQ(b()->GenerateExpression(&expr), 15u) << b()->error();
- } else {
- EXPECT_EQ(b()->GenerateExpression(&expr), 12u) << b()->error();
- }
+ EXPECT_EQ(DumpInstructions(b.types()),
+ R"(%4 = OpTypeFloat 32
+%3 = OpTypeImage %4 2D 0 0 0 2 R16f
+%2 = OpTypePointer Private %3
+%1 = OpVariable %2 Private
+%6 = OpTypeVector %4 4
+%8 = OpTypeVector %4 2
+%9 = OpConstant %4 1
+%10 = OpConstant %4 2
+%11 = OpConstantComposite %8 %9 %10
+%12 = OpTypeInt 32 1
+%13 = OpConstant %12 2
+)");
- EXPECT_EQ(
- DumpInstructions(b()->types()),
- generate_type_str(dim, format, true, type, 0, 1, type_id, coords_length));
-
- EXPECT_EQ(DumpInstructions(b()->functions()[0].instructions()),
- generate_ops_str(coords_length, "OpImageFetch"));
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ R"(%7 = OpLoad %3 %1
+%5 = OpImageRead %6 %7 %11 Lod %13
+)");
}
-INSTANTIATE_TEST_SUITE_P(
- BuilderTest,
- Builder_TextureLoad,
- testing::Values(
- TextureTestParams{ast::type::TextureDimension::k1d, TextureType::kF32,
- ast::type::ImageFormat::kR16Float},
- TextureTestParams{ast::type::TextureDimension::k1d, TextureType::kI32,
- ast::type::ImageFormat::kR16Sint},
- TextureTestParams{ast::type::TextureDimension::k1d, TextureType::kU32,
- ast::type::ImageFormat::kR8Unorm},
- TextureTestParams{ast::type::TextureDimension::k1dArray,
- TextureType::kF32, ast::type::ImageFormat::kR16Float},
- TextureTestParams{ast::type::TextureDimension::k1dArray,
- TextureType::kI32, ast::type::ImageFormat::kR16Sint},
- TextureTestParams{ast::type::TextureDimension::k1dArray,
- TextureType::kU32, ast::type::ImageFormat::kR8Unorm},
- TextureTestParams{ast::type::TextureDimension::k2d, TextureType::kF32,
- ast::type::ImageFormat::kR16Float},
- TextureTestParams{ast::type::TextureDimension::k2d, TextureType::kI32,
- ast::type::ImageFormat::kR16Sint},
- TextureTestParams{ast::type::TextureDimension::k2d, TextureType::kU32,
- ast::type::ImageFormat::kR8Unorm},
- TextureTestParams{ast::type::TextureDimension::k2dArray,
- TextureType::kF32, ast::type::ImageFormat::kR16Float},
- TextureTestParams{ast::type::TextureDimension::k2dArray,
- TextureType::kI32, ast::type::ImageFormat::kR16Sint},
- TextureTestParams{ast::type::TextureDimension::k2dArray,
- TextureType::kU32, ast::type::ImageFormat::kR8Unorm},
- TextureTestParams{ast::type::TextureDimension::k3d, TextureType::kF32,
- ast::type::ImageFormat::kR16Float},
- TextureTestParams{ast::type::TextureDimension::k3d, TextureType::kI32,
- ast::type::ImageFormat::kR16Sint},
- TextureTestParams{ast::type::TextureDimension::k3d, TextureType::kU32,
- ast::type::ImageFormat::kR8Unorm}));
-
-class Builder_SampledTextureOperation : public Builder_TextureOperation {
- public:
- std::string generate_type_str(ast::type::TextureDimension dim,
- bool unknown_format,
- TextureType type,
- uint32_t depth_literal,
- uint32_t sampled_literal,
- uint32_t type_id,
- uint32_t coords_length,
- bool optional_operand) {
- std::string type_str = R"(%1 = OpTypeFloat 32
-%2 = OpTypeInt 32 0
-%3 = OpTypeInt 32 1
-)";
-
- type_str +=
- texture_line(dim, unknown_format, type, depth_literal, sampled_literal);
-
- type_str += R"(%5 = OpTypePointer Private %6
-%7 = OpConstantNull %6
-%4 = OpVariable %5 Private %7
-%10 = OpTypeSampler
-%9 = OpTypePointer Private %10
-%11 = OpConstantNull %10
-%8 = OpVariable %9 Private %11
-)";
-
- if (coords_length > 1) {
- type_str += "%14 = OpTypeVector %3 " + std::to_string(coords_length) +
- R"(
-%13 = OpTypePointer Private %14
-%15 = OpConstantNull %14
-%12 = OpVariable %13 Private %15
-)";
-
- } else {
- type_str += R"(%13 = OpTypePointer Private %3
-%14 = OpConstantNull %3
-%12 = OpVariable %13 Private %14
-)";
- }
-
- if (coords_length > 1 && optional_operand) {
- type_str += R"(%17 = OpTypePointer Private %1
-%18 = OpConstantNull %1
-%16 = OpVariable %17 Private %18
-%20 = OpTypeVector %)" +
- std::to_string(type_id) + R"( 4
-%25 = OpTypeSampledImage %6
-)";
- } else if (coords_length > 1 && !optional_operand) {
- type_str += R"(%17 = OpTypeVector %)" + std::to_string(type_id) + R"( 4
-%21 = OpTypeSampledImage %6
-)";
- } else if (coords_length == 1 && optional_operand) {
- type_str += R"(%16 = OpTypePointer Private %1
-%17 = OpConstantNull %1
-%15 = OpVariable %16 Private %17
-%19 = OpTypeVector %)" +
- std::to_string(type_id) + R"( 4
-%24 = OpTypeSampledImage %6
-)";
- } else {
- type_str += R"(%16 = OpTypeVector %)" + std::to_string(type_id) + R"( 4
-%20 = OpTypeSampledImage %6
-)";
- }
-
- return type_str;
- }
-
- std::string generate_ops_str(uint32_t coords_length,
- std::string op_name,
- std::string optional_operand) {
- if (coords_length > 1 && optional_operand == "") {
- return R"(%18 = OpLoad %6 %4
-%19 = OpLoad %10 %8
-%20 = OpLoad %14 %12
-%22 = OpSampledImage %21 %18 %19
-%16 = )" + op_name +
- R"( %17 %22 %20
-)";
- }
-
- if (coords_length == 1 && optional_operand == "") {
- return R"(%17 = OpLoad %6 %4
-%18 = OpLoad %10 %8
-%19 = OpLoad %3 %12
-%21 = OpSampledImage %20 %17 %18
-%15 = )" + op_name +
- R"( %16 %21 %19
-)";
- }
-
- if (coords_length > 1 && optional_operand != "") {
- return R"(%21 = OpLoad %6 %4
-%22 = OpLoad %10 %8
-%23 = OpLoad %14 %12
-%24 = OpLoad %1 %16
-%26 = OpSampledImage %25 %21 %22
-%19 = )" + op_name +
- " %20 %26 %23 " + optional_operand + " %24\n";
- }
-
- return R"(%20 = OpLoad %6 %4
-%21 = OpLoad %10 %8
-%22 = OpLoad %3 %12
-%23 = OpLoad %1 %15
-%25 = OpSampledImage %24 %20 %21
-%18 = )" + op_name +
- " %19 %25 %22 " + optional_operand + " %23\n";
- }
-};
-
-TEST_P(Builder_SampledTextureOperation, TextureSample) {
- auto dim = GetParam().dim;
- auto type = GetParam().type;
-
+TEST_F(BuilderTest, Call_TextureLoad_Sampled_1d) {
ast::type::F32Type f32;
- b()->GenerateTypeIfNeeded(&f32);
- ast::type::U32Type u32;
- b()->GenerateTypeIfNeeded(&u32);
ast::type::I32Type i32;
- b()->GenerateTypeIfNeeded(&i32);
+ ast::type::SampledTextureType s(ast::type::TextureDimension::k1d, &f32);
- uint32_t type_id = 1;
- if (type == TextureType::kU32) {
- type_id = 2;
- } else if (type == TextureType::kI32) {
- type_id = 3;
- }
+ Context ctx;
+ ast::Module mod;
+ TypeDeterminer td(&ctx, &mod);
+ Builder b(&mod);
- auto coords_type = get_coords_type(dim, &i32);
+ b.push_function(Function{});
- uint32_t coords_length = 1;
- if (coords_type->IsVector()) {
- coords_length = coords_type->AsVector()->size();
- }
-
- auto sampler_type = std::make_unique<ast::type::SamplerType>(
- ast::type::SamplerKind::kSampler);
- std::unique_ptr<ast::type::Type> s = subtype(type);
- auto* texture_type = ctx()->type_mgr().Get(
- std::make_unique<ast::type::SampledTextureType>(dim, s.get()));
-
- EXPECT_TRUE(td()->Determine());
+ ast::Variable tex("texture", ast::StorageClass::kNone, &s);
+ td.RegisterVariableForTesting(&tex);
+ ASSERT_TRUE(b.GenerateGlobalVariable(&tex)) << b.error();
ast::ExpressionList call_params;
- b()->push_function(Function{});
+ call_params.push_back(std::make_unique<ast::IdentifierExpression>("texture"));
+ call_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 1.0)));
+ call_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::SintLiteral>(&i32, 2)));
- add_call_param("texture", texture_type, &call_params);
- add_call_param("sampler", sampler_type.get(), &call_params);
- add_call_param("coords", coords_type.get(), &call_params);
+ ast::CallExpression expr(
+ std::make_unique<ast::IdentifierExpression>("textureLoad"),
+ std::move(call_params));
+
+ EXPECT_TRUE(td.DetermineResultType(&expr)) << td.error();
+ EXPECT_EQ(b.GenerateExpression(&expr), 5u) << b.error();
+
+ EXPECT_EQ(DumpInstructions(b.types()),
+ R"(%4 = OpTypeFloat 32
+%3 = OpTypeImage %4 1D 0 0 0 1 Unknown
+%2 = OpTypePointer Private %3
+%1 = OpVariable %2 Private
+%6 = OpTypeVector %4 4
+%8 = OpConstant %4 1
+%9 = OpTypeInt 32 1
+%10 = OpConstant %9 2
+)");
+
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ R"(%7 = OpLoad %3 %1
+%5 = OpImageFetch %6 %7 %8 Lod %10
+)");
+}
+
+TEST_F(BuilderTest, Call_TextureLoad_Sampled_2d) {
+ ast::type::F32Type f32;
+ ast::type::I32Type i32;
+ ast::type::VectorType vec2(&f32, 2);
+ ast::type::SampledTextureType s(ast::type::TextureDimension::k2d, &f32);
+
+ Context ctx;
+ ast::Module mod;
+ TypeDeterminer td(&ctx, &mod);
+ Builder b(&mod);
+
+ b.push_function(Function{});
+
+ ast::Variable tex("texture", ast::StorageClass::kNone, &s);
+ td.RegisterVariableForTesting(&tex);
+ ASSERT_TRUE(b.GenerateGlobalVariable(&tex)) << b.error();
+
+ ast::ExpressionList vals;
+ vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 1.0)));
+ vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+
+ ast::ExpressionList call_params;
+ call_params.push_back(std::make_unique<ast::IdentifierExpression>("texture"));
+ call_params.push_back(
+ std::make_unique<ast::TypeConstructorExpression>(&vec2, std::move(vals)));
+ call_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::SintLiteral>(&i32, 2)));
+
+ ast::CallExpression expr(
+ std::make_unique<ast::IdentifierExpression>("textureLoad"),
+ std::move(call_params));
+
+ EXPECT_TRUE(td.DetermineResultType(&expr)) << td.error();
+ EXPECT_EQ(b.GenerateExpression(&expr), 5u) << b.error();
+
+ EXPECT_EQ(DumpInstructions(b.types()),
+ R"(%4 = OpTypeFloat 32
+%3 = OpTypeImage %4 2D 0 0 0 1 Unknown
+%2 = OpTypePointer Private %3
+%1 = OpVariable %2 Private
+%6 = OpTypeVector %4 4
+%8 = OpTypeVector %4 2
+%9 = OpConstant %4 1
+%10 = OpConstant %4 2
+%11 = OpConstantComposite %8 %9 %10
+%12 = OpTypeInt 32 1
+%13 = OpConstant %12 2
+)");
+
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ R"(%7 = OpLoad %3 %1
+%5 = OpImageFetch %6 %7 %11 Lod %13
+)");
+}
+
+TEST_F(BuilderTest, Call_TextureSample_1d) {
+ ast::type::F32Type f32;
+
+ ast::type::SamplerType s(ast::type::SamplerKind::kSampler);
+ ast::type::SampledTextureType t(ast::type::TextureDimension::k1d, &s);
+
+ Context ctx;
+ ast::Module mod;
+ TypeDeterminer td(&ctx, &mod);
+ Builder b(&mod);
+
+ b.push_function(Function{});
+
+ ast::Variable tex("texture", ast::StorageClass::kNone, &t);
+ td.RegisterVariableForTesting(&tex);
+ ASSERT_TRUE(b.GenerateGlobalVariable(&tex)) << b.error();
+
+ ast::Variable sampler("sampler", ast::StorageClass::kNone, &s);
+ td.RegisterVariableForTesting(&sampler);
+ ASSERT_TRUE(b.GenerateGlobalVariable(&sampler)) << b.error();
+
+ ast::ExpressionList call_params;
+ call_params.push_back(std::make_unique<ast::IdentifierExpression>("texture"));
+ call_params.push_back(std::make_unique<ast::IdentifierExpression>("sampler"));
+ call_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 1.0)));
ast::CallExpression expr(
std::make_unique<ast::IdentifierExpression>("textureSample"),
std::move(call_params));
- EXPECT_TRUE(td()->DetermineResultType(&expr));
+ EXPECT_TRUE(td.DetermineResultType(&expr)) << td.error();
+ EXPECT_EQ(b.GenerateExpression(&expr), 7u) << b.error();
+ EXPECT_EQ(DumpInstructions(b.types()),
+ R"(%4 = OpTypeSampler
+%3 = OpTypeImage %4 1D 0 0 0 1 Unknown
+%2 = OpTypePointer Private %3
+%1 = OpVariable %2 Private
+%6 = OpTypePointer Private %4
+%5 = OpVariable %6 Private
+%8 = OpTypeVector %4 4
+%11 = OpTypeFloat 32
+%12 = OpConstant %11 1
+%13 = OpTypeSampledImage %3
+)");
- if (coords_length > 1) {
- EXPECT_EQ(b()->GenerateExpression(&expr), 16u) << b()->error();
- } else {
- EXPECT_EQ(b()->GenerateExpression(&expr), 15u) << b()->error();
- }
-
- EXPECT_EQ(
- DumpInstructions(b()->types()),
- generate_type_str(dim, true, type, 0, 1, type_id, coords_length, false));
-
- EXPECT_EQ(DumpInstructions(b()->functions()[0].instructions()),
- generate_ops_str(coords_length, "OpImageSampleImplicitLod", ""));
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ R"(%9 = OpLoad %3 %1
+%10 = OpLoad %4 %5
+%14 = OpSampledImage %13 %9 %10
+%7 = OpImageSampleImplicitLod %8 %14 %12
+)");
}
-TEST_P(Builder_SampledTextureOperation, TextureSampleLevel) {
- auto dim = GetParam().dim;
- auto type = GetParam().type;
-
+TEST_F(BuilderTest, Call_TextureSample_2d) {
ast::type::F32Type f32;
- b()->GenerateTypeIfNeeded(&f32);
- ast::type::U32Type u32;
- b()->GenerateTypeIfNeeded(&u32);
- ast::type::I32Type i32;
- b()->GenerateTypeIfNeeded(&i32);
+ ast::type::VectorType vec2(&f32, 2);
- uint32_t type_id = 1;
- if (type == TextureType::kU32) {
- type_id = 2;
- } else if (type == TextureType::kI32) {
- type_id = 3;
- }
+ ast::type::SamplerType s(ast::type::SamplerKind::kSampler);
+ ast::type::SampledTextureType t(ast::type::TextureDimension::k2d, &s);
- auto coords_type = get_coords_type(dim, &i32);
+ Context ctx;
+ ast::Module mod;
+ TypeDeterminer td(&ctx, &mod);
+ Builder b(&mod);
- uint32_t coords_length = 1;
- if (coords_type->IsVector()) {
- coords_length = coords_type->AsVector()->size();
- }
+ b.push_function(Function{});
- auto sampler_type = std::make_unique<ast::type::SamplerType>(
- ast::type::SamplerKind::kSampler);
- std::unique_ptr<ast::type::Type> s = subtype(type);
- auto* texture_type = ctx()->type_mgr().Get(
- std::make_unique<ast::type::SampledTextureType>(dim, s.get()));
+ ast::Variable tex("texture", ast::StorageClass::kNone, &t);
+ td.RegisterVariableForTesting(&tex);
+ ASSERT_TRUE(b.GenerateGlobalVariable(&tex)) << b.error();
- EXPECT_TRUE(td()->Determine());
+ ast::Variable sampler("sampler", ast::StorageClass::kNone, &s);
+ td.RegisterVariableForTesting(&sampler);
+ ASSERT_TRUE(b.GenerateGlobalVariable(&sampler)) << b.error();
+
+ ast::ExpressionList vals;
+ vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 1.0)));
+ vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
ast::ExpressionList call_params;
- b()->push_function(Function{});
+ call_params.push_back(std::make_unique<ast::IdentifierExpression>("texture"));
+ call_params.push_back(std::make_unique<ast::IdentifierExpression>("sampler"));
+ call_params.push_back(
+ std::make_unique<ast::TypeConstructorExpression>(&vec2, std::move(vals)));
- add_call_param("texture", texture_type, &call_params);
- add_call_param("sampler", sampler_type.get(), &call_params);
- add_call_param("coords", coords_type.get(), &call_params);
- add_call_param("lod", &f32, &call_params);
+ ast::CallExpression expr(
+ std::make_unique<ast::IdentifierExpression>("textureSample"),
+ std::move(call_params));
+
+ EXPECT_TRUE(td.DetermineResultType(&expr)) << td.error();
+ EXPECT_EQ(b.GenerateExpression(&expr), 7u) << b.error();
+ EXPECT_EQ(DumpInstructions(b.types()),
+ R"(%4 = OpTypeSampler
+%3 = OpTypeImage %4 2D 0 0 0 1 Unknown
+%2 = OpTypePointer Private %3
+%1 = OpVariable %2 Private
+%6 = OpTypePointer Private %4
+%5 = OpVariable %6 Private
+%8 = OpTypeVector %4 4
+%12 = OpTypeFloat 32
+%11 = OpTypeVector %12 2
+%13 = OpConstant %12 1
+%14 = OpConstant %12 2
+%15 = OpConstantComposite %11 %13 %14
+%16 = OpTypeSampledImage %3
+)");
+
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ R"(%9 = OpLoad %3 %1
+%10 = OpLoad %4 %5
+%17 = OpSampledImage %16 %9 %10
+%7 = OpImageSampleImplicitLod %8 %17 %15
+)");
+}
+
+TEST_F(BuilderTest, Call_TextureSampleLevel_1d) {
+ ast::type::F32Type f32;
+
+ ast::type::SamplerType s(ast::type::SamplerKind::kSampler);
+ ast::type::SampledTextureType t(ast::type::TextureDimension::k1d, &f32);
+
+ Context ctx;
+ ast::Module mod;
+ TypeDeterminer td(&ctx, &mod);
+ Builder b(&mod);
+
+ b.push_function(Function{});
+
+ ast::Variable tex("texture", ast::StorageClass::kNone, &t);
+ td.RegisterVariableForTesting(&tex);
+ ASSERT_TRUE(b.GenerateGlobalVariable(&tex)) << b.error();
+
+ ast::Variable sampler("sampler", ast::StorageClass::kNone, &s);
+ td.RegisterVariableForTesting(&sampler);
+ ASSERT_TRUE(b.GenerateGlobalVariable(&sampler)) << b.error();
+
+ ast::ExpressionList call_params;
+ call_params.push_back(std::make_unique<ast::IdentifierExpression>("texture"));
+ call_params.push_back(std::make_unique<ast::IdentifierExpression>("sampler"));
+ call_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 1.0)));
+ call_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
ast::CallExpression expr(
std::make_unique<ast::IdentifierExpression>("textureSampleLevel"),
std::move(call_params));
- EXPECT_TRUE(td()->DetermineResultType(&expr));
+ EXPECT_TRUE(td.DetermineResultType(&expr)) << td.error();
+ EXPECT_EQ(b.GenerateExpression(&expr), 8u) << b.error();
- if (coords_length > 1) {
- EXPECT_EQ(b()->GenerateExpression(&expr), 19u) << b()->error();
- } else {
- EXPECT_EQ(b()->GenerateExpression(&expr), 18u) << b()->error();
- }
+ EXPECT_EQ(DumpInstructions(b.types()),
+ R"(%4 = OpTypeFloat 32
+%3 = OpTypeImage %4 1D 0 0 0 1 Unknown
+%2 = OpTypePointer Private %3
+%1 = OpVariable %2 Private
+%7 = OpTypeSampler
+%6 = OpTypePointer Private %7
+%5 = OpVariable %6 Private
+%9 = OpTypeVector %4 4
+%12 = OpConstant %4 1
+%13 = OpConstant %4 2
+%14 = OpTypeSampledImage %3
+)");
- EXPECT_EQ(
- DumpInstructions(b()->types()),
- generate_type_str(dim, true, type, 0, 1, type_id, coords_length, true));
-
- EXPECT_EQ(DumpInstructions(b()->functions()[0].instructions()),
- generate_ops_str(coords_length, "OpImageSampleExplicitLod", "Lod"));
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ R"(%10 = OpLoad %3 %1
+%11 = OpLoad %7 %5
+%15 = OpSampledImage %14 %10 %11
+%8 = OpImageSampleExplicitLod %9 %15 %12 Lod %13
+)");
}
-TEST_P(Builder_SampledTextureOperation, TextureSampleBias) {
- auto dim = GetParam().dim;
- auto type = GetParam().type;
-
+TEST_F(BuilderTest, Call_TextureSampleLevel_2d) {
ast::type::F32Type f32;
- b()->GenerateTypeIfNeeded(&f32);
- ast::type::U32Type u32;
- b()->GenerateTypeIfNeeded(&u32);
- ast::type::I32Type i32;
- b()->GenerateTypeIfNeeded(&i32);
+ ast::type::VectorType vec2(&f32, 2);
- uint32_t type_id = 1;
- if (type == TextureType::kU32) {
- type_id = 2;
- } else if (type == TextureType::kI32) {
- type_id = 3;
- }
+ ast::type::SamplerType s(ast::type::SamplerKind::kSampler);
+ ast::type::SampledTextureType t(ast::type::TextureDimension::k2d, &f32);
- auto coords_type = get_coords_type(dim, &i32);
+ Context ctx;
+ ast::Module mod;
+ TypeDeterminer td(&ctx, &mod);
+ Builder b(&mod);
- uint32_t coords_length = 1;
- if (coords_type->IsVector()) {
- coords_length = coords_type->AsVector()->size();
- }
+ b.push_function(Function{});
- auto sampler_type = std::make_unique<ast::type::SamplerType>(
- ast::type::SamplerKind::kSampler);
- std::unique_ptr<ast::type::Type> s = subtype(type);
- auto* texture_type = ctx()->type_mgr().Get(
- std::make_unique<ast::type::SampledTextureType>(dim, s.get()));
+ ast::Variable tex("texture", ast::StorageClass::kNone, &t);
+ td.RegisterVariableForTesting(&tex);
+ ASSERT_TRUE(b.GenerateGlobalVariable(&tex)) << b.error();
- EXPECT_TRUE(td()->Determine());
+ ast::Variable sampler("sampler", ast::StorageClass::kNone, &s);
+ td.RegisterVariableForTesting(&sampler);
+ ASSERT_TRUE(b.GenerateGlobalVariable(&sampler)) << b.error();
+
+ ast::ExpressionList vals;
+ vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 1.0)));
+ vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
ast::ExpressionList call_params;
- b()->push_function(Function{});
+ call_params.push_back(std::make_unique<ast::IdentifierExpression>("texture"));
+ call_params.push_back(std::make_unique<ast::IdentifierExpression>("sampler"));
+ call_params.push_back(
+ std::make_unique<ast::TypeConstructorExpression>(&vec2, std::move(vals)));
+ call_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
- add_call_param("texture", texture_type, &call_params);
- add_call_param("sampler", sampler_type.get(), &call_params);
- add_call_param("coords", coords_type.get(), &call_params);
- add_call_param("bias", &f32, &call_params);
+ ast::CallExpression expr(
+ std::make_unique<ast::IdentifierExpression>("textureSampleLevel"),
+ std::move(call_params));
+
+ EXPECT_TRUE(td.DetermineResultType(&expr)) << td.error();
+ EXPECT_EQ(b.GenerateExpression(&expr), 8u) << b.error();
+
+ EXPECT_EQ(DumpInstructions(b.types()),
+ R"(%4 = OpTypeFloat 32
+%3 = OpTypeImage %4 2D 0 0 0 1 Unknown
+%2 = OpTypePointer Private %3
+%1 = OpVariable %2 Private
+%7 = OpTypeSampler
+%6 = OpTypePointer Private %7
+%5 = OpVariable %6 Private
+%9 = OpTypeVector %4 4
+%12 = OpTypeVector %4 2
+%13 = OpConstant %4 1
+%14 = OpConstant %4 2
+%15 = OpConstantComposite %12 %13 %14
+%16 = OpTypeSampledImage %3
+)");
+
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ R"(%10 = OpLoad %3 %1
+%11 = OpLoad %7 %5
+%17 = OpSampledImage %16 %10 %11
+%8 = OpImageSampleExplicitLod %9 %17 %15 Lod %14
+)");
+}
+
+TEST_F(BuilderTest, Call_TextureSampleBias_1d) {
+ ast::type::F32Type f32;
+
+ ast::type::SamplerType s(ast::type::SamplerKind::kSampler);
+ ast::type::SampledTextureType t(ast::type::TextureDimension::k1d, &f32);
+
+ Context ctx;
+ ast::Module mod;
+ TypeDeterminer td(&ctx, &mod);
+ Builder b(&mod);
+
+ b.push_function(Function{});
+
+ ast::Variable tex("texture", ast::StorageClass::kNone, &t);
+ td.RegisterVariableForTesting(&tex);
+ ASSERT_TRUE(b.GenerateGlobalVariable(&tex)) << b.error();
+
+ ast::Variable sampler("sampler", ast::StorageClass::kNone, &s);
+ td.RegisterVariableForTesting(&sampler);
+ ASSERT_TRUE(b.GenerateGlobalVariable(&sampler)) << b.error();
+
+ ast::ExpressionList call_params;
+ call_params.push_back(std::make_unique<ast::IdentifierExpression>("texture"));
+ call_params.push_back(std::make_unique<ast::IdentifierExpression>("sampler"));
+ call_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 1.0)));
+ call_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
ast::CallExpression expr(
std::make_unique<ast::IdentifierExpression>("textureSampleBias"),
std::move(call_params));
- EXPECT_TRUE(td()->DetermineResultType(&expr));
+ EXPECT_TRUE(td.DetermineResultType(&expr)) << td.error();
+ EXPECT_EQ(b.GenerateExpression(&expr), 8u) << b.error();
- if (coords_length > 1) {
- EXPECT_EQ(b()->GenerateExpression(&expr), 19u) << b()->error();
- } else {
- EXPECT_EQ(b()->GenerateExpression(&expr), 18u) << b()->error();
- }
+ EXPECT_EQ(DumpInstructions(b.types()),
+ R"(%4 = OpTypeFloat 32
+%3 = OpTypeImage %4 1D 0 0 0 1 Unknown
+%2 = OpTypePointer Private %3
+%1 = OpVariable %2 Private
+%7 = OpTypeSampler
+%6 = OpTypePointer Private %7
+%5 = OpVariable %6 Private
+%9 = OpTypeVector %4 4
+%12 = OpConstant %4 1
+%13 = OpConstant %4 2
+%14 = OpTypeSampledImage %3
+)");
- EXPECT_EQ(
- DumpInstructions(b()->types()),
- generate_type_str(dim, true, type, 0, 1, type_id, coords_length, true));
-
- EXPECT_EQ(
- DumpInstructions(b()->functions()[0].instructions()),
- generate_ops_str(coords_length, "OpImageSampleImplicitLod", "Bias"));
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ R"(%10 = OpLoad %3 %1
+%11 = OpLoad %7 %5
+%15 = OpSampledImage %14 %10 %11
+%8 = OpImageSampleImplicitLod %9 %15 %12 Bias %13
+)");
}
-INSTANTIATE_TEST_SUITE_P(
- BuilderTest,
- Builder_SampledTextureOperation,
- testing::Values(
- TextureTestParams{ast::type::TextureDimension::k1d, TextureType::kF32},
- TextureTestParams{ast::type::TextureDimension::k1d, TextureType::kI32},
- TextureTestParams{ast::type::TextureDimension::k1d, TextureType::kU32},
- TextureTestParams{ast::type::TextureDimension::k1dArray,
- TextureType::kF32},
- TextureTestParams{ast::type::TextureDimension::k1dArray,
- TextureType::kI32},
- TextureTestParams{ast::type::TextureDimension::k1dArray,
- TextureType::kU32},
- TextureTestParams{ast::type::TextureDimension::k2d, TextureType::kF32},
- TextureTestParams{ast::type::TextureDimension::k2d, TextureType::kI32},
- TextureTestParams{ast::type::TextureDimension::k2d, TextureType::kU32},
- TextureTestParams{ast::type::TextureDimension::k2dArray,
- TextureType::kF32},
- TextureTestParams{ast::type::TextureDimension::k2dArray,
- TextureType::kI32},
- TextureTestParams{ast::type::TextureDimension::k2dArray,
- TextureType::kU32},
- TextureTestParams{ast::type::TextureDimension::k3d, TextureType::kF32},
- TextureTestParams{ast::type::TextureDimension::k3d, TextureType::kI32},
- TextureTestParams{ast::type::TextureDimension::k3d,
- TextureType::kU32}));
-
-class Builder_DepthTextureOperation : public Builder_TextureOperation {
- public:
- std::string generate_type_str(ast::type::TextureDimension dim,
- uint32_t coords_length) {
- std::string type_str = R"(%1 = OpTypeFloat 32
-%2 = OpTypeInt 32 0
-%3 = OpTypeInt 32 1
-)";
-
- type_str += texture_line(dim, true, TextureType::kF32, 1, 1);
-
- type_str += R"(%5 = OpTypePointer Private %6
-%7 = OpConstantNull %6
-%4 = OpVariable %5 Private %7
-%10 = OpTypeSampler
-%9 = OpTypePointer Private %10
-%11 = OpConstantNull %10
-%8 = OpVariable %9 Private %11
-%14 = OpTypeVector %1 )" +
- std::to_string(coords_length) + R"(
-%13 = OpTypePointer Private %14
-%15 = OpConstantNull %14
-%12 = OpVariable %13 Private %15
-%17 = OpTypePointer Private %1
-%18 = OpConstantNull %1
-%16 = OpVariable %17 Private %18
-%24 = OpTypeSampledImage %6
-%26 = OpConstant %1 0
-)";
-
- return type_str;
- }
-
- std::string generate_ops_str() {
- return R"(%20 = OpLoad %6 %4
-%21 = OpLoad %10 %8
-%22 = OpLoad %14 %12
-%23 = OpLoad %1 %16
-%25 = OpSampledImage %24 %20 %21
-%19 = OpImageSampleDrefExplicitLod %1 %25 %22 %23 Lod %26
-)";
- }
-};
-
-TEST_P(Builder_DepthTextureOperation, TextureSampleCompare) {
- auto dim = GetParam().dim;
- auto type = GetParam().type;
-
+TEST_F(BuilderTest, Call_TextureSampleBias_2d) {
ast::type::F32Type f32;
- b()->GenerateTypeIfNeeded(&f32);
- ast::type::U32Type u32;
- b()->GenerateTypeIfNeeded(&u32);
- ast::type::I32Type i32;
- b()->GenerateTypeIfNeeded(&i32);
+ ast::type::VectorType vec2(&f32, 2);
- auto coords_type = get_coords_type(dim, &f32);
+ ast::type::SamplerType s(ast::type::SamplerKind::kSampler);
+ ast::type::SampledTextureType t(ast::type::TextureDimension::k1d, &f32);
- uint32_t coords_length = coords_type->AsVector()->size();
+ Context ctx;
+ ast::Module mod;
+ TypeDeterminer td(&ctx, &mod);
+ Builder b(&mod);
- auto sampler_type = std::make_unique<ast::type::SamplerType>(
- ast::type::SamplerKind::kComparisonSampler);
- std::unique_ptr<ast::type::Type> s = subtype(type);
- auto* texture_type =
- ctx()->type_mgr().Get(std::make_unique<ast::type::DepthTextureType>(dim));
+ b.push_function(Function{});
+
+ ast::Variable tex("texture", ast::StorageClass::kNone, &t);
+ td.RegisterVariableForTesting(&tex);
+ ASSERT_TRUE(b.GenerateGlobalVariable(&tex)) << b.error();
+
+ ast::Variable sampler("sampler", ast::StorageClass::kNone, &s);
+ td.RegisterVariableForTesting(&sampler);
+ ASSERT_TRUE(b.GenerateGlobalVariable(&sampler)) << b.error();
+
+ ast::ExpressionList vals;
+ vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 1.0)));
+ vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
ast::ExpressionList call_params;
- b()->push_function(Function{});
+ call_params.push_back(std::make_unique<ast::IdentifierExpression>("texture"));
+ call_params.push_back(std::make_unique<ast::IdentifierExpression>("sampler"));
+ call_params.push_back(
+ std::make_unique<ast::TypeConstructorExpression>(&vec2, std::move(vals)));
+ call_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
- add_call_param("texture", texture_type, &call_params);
- add_call_param("sampler", sampler_type.get(), &call_params);
- add_call_param("coords", coords_type.get(), &call_params);
- add_call_param("depth_reference", &f32, &call_params);
+ ast::CallExpression expr(
+ std::make_unique<ast::IdentifierExpression>("textureSampleBias"),
+ std::move(call_params));
+
+ EXPECT_TRUE(td.DetermineResultType(&expr)) << td.error();
+ EXPECT_EQ(b.GenerateExpression(&expr), 8u) << b.error();
+
+ EXPECT_EQ(DumpInstructions(b.types()),
+ R"(%4 = OpTypeFloat 32
+%3 = OpTypeImage %4 1D 0 0 0 1 Unknown
+%2 = OpTypePointer Private %3
+%1 = OpVariable %2 Private
+%7 = OpTypeSampler
+%6 = OpTypePointer Private %7
+%5 = OpVariable %6 Private
+%9 = OpTypeVector %4 4
+%12 = OpTypeVector %4 2
+%13 = OpConstant %4 1
+%14 = OpConstant %4 2
+%15 = OpConstantComposite %12 %13 %14
+%16 = OpTypeSampledImage %3
+)");
+
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ R"(%10 = OpLoad %3 %1
+%11 = OpLoad %7 %5
+%17 = OpSampledImage %16 %10 %11
+%8 = OpImageSampleImplicitLod %9 %17 %15 Bias %14
+)");
+}
+
+TEST_F(BuilderTest, Call_TextureSampleCompare) {
+ ast::type::F32Type f32;
+ ast::type::VectorType vec2(&f32, 2);
+
+ ast::type::SamplerType s(ast::type::SamplerKind::kComparisonSampler);
+ ast::type::DepthTextureType t(ast::type::TextureDimension::k2d);
+
+ Context ctx;
+ ast::Module mod;
+ TypeDeterminer td(&ctx, &mod);
+ Builder b(&mod);
+
+ b.push_function(Function{});
+
+ ast::Variable tex("texture", ast::StorageClass::kNone, &t);
+ td.RegisterVariableForTesting(&tex);
+ ASSERT_TRUE(b.GenerateGlobalVariable(&tex)) << b.error();
+
+ ast::Variable sampler("sampler", ast::StorageClass::kNone, &s);
+ td.RegisterVariableForTesting(&sampler);
+ ASSERT_TRUE(b.GenerateGlobalVariable(&sampler)) << b.error();
+
+ ast::ExpressionList vals;
+ vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 1.0)));
+ vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+
+ ast::ExpressionList call_params;
+ call_params.push_back(std::make_unique<ast::IdentifierExpression>("texture"));
+ call_params.push_back(std::make_unique<ast::IdentifierExpression>("sampler"));
+ call_params.push_back(
+ std::make_unique<ast::TypeConstructorExpression>(&vec2, std::move(vals)));
+ call_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
ast::CallExpression expr(
std::make_unique<ast::IdentifierExpression>("textureSampleCompare"),
std::move(call_params));
- EXPECT_TRUE(td()->DetermineResultType(&expr));
-
- EXPECT_EQ(b()->GenerateExpression(&expr), 19u) << b()->error();
-
- EXPECT_EQ(DumpInstructions(b()->types()),
- generate_type_str(dim, coords_length));
-
- EXPECT_EQ(DumpInstructions(b()->functions()[0].instructions()),
- generate_ops_str());
-}
-
-INSTANTIATE_TEST_SUITE_P(
- BuilderTest,
- Builder_DepthTextureOperation,
- testing::Values(TextureTestParams{ast::type::TextureDimension::k2d},
- TextureTestParams{ast::type::TextureDimension::k2dArray},
- TextureTestParams{ast::type::TextureDimension::kCube},
- TextureTestParams{
- ast::type::TextureDimension::kCubeArray}));
-
-// This tests that we do not push OpTypeSampledImage and float_0 type twice.
-TEST_F(Builder_TextureOperation, TextureSampleCompareTwice) {
- ast::type::F32Type f32;
- b()->GenerateTypeIfNeeded(&f32);
-
- auto coords_type = get_coords_type(ast::type::TextureDimension::k2d, &f32);
- auto sampler_type = std::make_unique<ast::type::SamplerType>(
- ast::type::SamplerKind::kComparisonSampler);
- auto* texture_type =
- ctx()->type_mgr().Get(std::make_unique<ast::type::DepthTextureType>(
- ast::type::TextureDimension::k2d));
-
- b()->push_function(Function{});
-
- ast::ExpressionList call_params_first;
- add_call_param("texture", texture_type, &call_params_first);
- add_call_param("sampler", sampler_type.get(), &call_params_first);
- add_call_param("coords", coords_type.get(), &call_params_first);
- add_call_param("depth_reference", &f32, &call_params_first);
-
- ast::ExpressionList call_params_second;
- add_call_param("texture", texture_type, &call_params_second);
- add_call_param("sampler", sampler_type.get(), &call_params_second);
- add_call_param("coords", coords_type.get(), &call_params_second);
- add_call_param("depth_reference", &f32, &call_params_second);
-
- ast::CallExpression expr_first(
- std::make_unique<ast::IdentifierExpression>("textureSampleCompare"),
- std::move(call_params_first));
- ast::CallExpression expr_second(
- std::make_unique<ast::IdentifierExpression>("textureSampleCompare"),
- std::move(call_params_second));
-
- EXPECT_TRUE(td()->DetermineResultType(&expr_first));
- EXPECT_TRUE(td()->DetermineResultType(&expr_second));
-
- EXPECT_EQ(b()->GenerateExpression(&expr_first), 21u) << b()->error();
- EXPECT_EQ(b()->GenerateExpression(&expr_second), 29u) << b()->error();
-
- EXPECT_EQ(DumpInstructions(b()->types()), R"(%1 = OpTypeFloat 32
-%4 = OpTypeImage %1 2D 1 0 0 1 Unknown
-%3 = OpTypePointer Private %4
-%5 = OpConstantNull %4
-%2 = OpVariable %3 Private %5
-%8 = OpTypeSampler
-%7 = OpTypePointer Private %8
-%9 = OpConstantNull %8
-%6 = OpVariable %7 Private %9
-%12 = OpTypeVector %1 2
-%11 = OpTypePointer Private %12
-%13 = OpConstantNull %12
-%10 = OpVariable %11 Private %13
-%15 = OpTypePointer Private %1
-%16 = OpConstantNull %1
-%14 = OpVariable %15 Private %16
-%17 = OpVariable %3 Private %5
-%18 = OpVariable %7 Private %9
-%19 = OpVariable %11 Private %13
-%20 = OpVariable %15 Private %16
-%26 = OpTypeSampledImage %4
-%28 = OpConstant %1 0
+ EXPECT_TRUE(td.DetermineResultType(&expr)) << td.error();
+ EXPECT_EQ(b.GenerateExpression(&expr), 8u) << b.error();
+ EXPECT_EQ(DumpInstructions(b.types()),
+ R"(%4 = OpTypeFloat 32
+%3 = OpTypeImage %4 2D 1 0 0 1 Unknown
+%2 = OpTypePointer Private %3
+%1 = OpVariable %2 Private
+%7 = OpTypeSampler
+%6 = OpTypePointer Private %7
+%5 = OpVariable %6 Private
+%11 = OpTypeVector %4 2
+%12 = OpConstant %4 1
+%13 = OpConstant %4 2
+%14 = OpConstantComposite %11 %12 %13
+%15 = OpTypeSampledImage %3
+%17 = OpConstant %4 0
)");
- EXPECT_EQ(DumpInstructions(b()->functions()[0].instructions()),
- R"(%22 = OpLoad %4 %17
-%23 = OpLoad %8 %18
-%24 = OpLoad %12 %19
-%25 = OpLoad %1 %20
-%27 = OpSampledImage %26 %22 %23
-%21 = OpImageSampleDrefExplicitLod %1 %27 %24 %25 Lod %28
-%30 = OpLoad %4 %17
-%31 = OpLoad %8 %18
-%32 = OpLoad %12 %19
-%33 = OpLoad %1 %20
-%34 = OpSampledImage %26 %30 %31
-%29 = OpImageSampleDrefExplicitLod %1 %34 %32 %33 Lod %28
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ R"(%9 = OpLoad %3 %1
+%10 = OpLoad %7 %5
+%16 = OpSampledImage %15 %9 %10
+%8 = OpImageSampleDrefExplicitLod %4 %16 %14 %13 Lod %17
+)");
+}
+
+// This tests that we do not push OpTypeSampledImage and float_0 type twice.
+TEST_F(BuilderTest, Call_TextureSampleCompare_Twice) {
+ ast::type::F32Type f32;
+ ast::type::VectorType vec2(&f32, 2);
+
+ ast::type::SamplerType s(ast::type::SamplerKind::kComparisonSampler);
+ ast::type::DepthTextureType t(ast::type::TextureDimension::k2d);
+
+ Context ctx;
+ ast::Module mod;
+ TypeDeterminer td(&ctx, &mod);
+ Builder b(&mod);
+
+ b.push_function(Function{});
+
+ ast::Variable tex("texture", ast::StorageClass::kNone, &t);
+ td.RegisterVariableForTesting(&tex);
+ ASSERT_TRUE(b.GenerateGlobalVariable(&tex)) << b.error();
+
+ ast::Variable sampler("sampler", ast::StorageClass::kNone, &s);
+ td.RegisterVariableForTesting(&sampler);
+ ASSERT_TRUE(b.GenerateGlobalVariable(&sampler)) << b.error();
+
+ ast::ExpressionList vals;
+ vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 1.0)));
+ vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+
+ ast::ExpressionList call_params;
+ call_params.push_back(std::make_unique<ast::IdentifierExpression>("texture"));
+ call_params.push_back(std::make_unique<ast::IdentifierExpression>("sampler"));
+ call_params.push_back(
+ std::make_unique<ast::TypeConstructorExpression>(&vec2, std::move(vals)));
+ call_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+
+ ast::CallExpression expr1(
+ std::make_unique<ast::IdentifierExpression>("textureSampleCompare"),
+ std::move(call_params));
+
+ vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 1.0)));
+ vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+
+ call_params.push_back(std::make_unique<ast::IdentifierExpression>("texture"));
+ call_params.push_back(std::make_unique<ast::IdentifierExpression>("sampler"));
+ call_params.push_back(
+ std::make_unique<ast::TypeConstructorExpression>(&vec2, std::move(vals)));
+ call_params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
+ std::make_unique<ast::FloatLiteral>(&f32, 2.0)));
+
+ ast::CallExpression expr2(
+ std::make_unique<ast::IdentifierExpression>("textureSampleCompare"),
+ std::move(call_params));
+
+ EXPECT_TRUE(td.DetermineResultType(&expr1)) << td.error();
+ EXPECT_TRUE(td.DetermineResultType(&expr2)) << td.error();
+
+ EXPECT_EQ(b.GenerateExpression(&expr1), 8u) << b.error();
+ EXPECT_EQ(b.GenerateExpression(&expr2), 18u) << b.error();
+
+ EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+%3 = OpTypeImage %4 2D 1 0 0 1 Unknown
+%2 = OpTypePointer Private %3
+%1 = OpVariable %2 Private
+%7 = OpTypeSampler
+%6 = OpTypePointer Private %7
+%5 = OpVariable %6 Private
+%11 = OpTypeVector %4 2
+%12 = OpConstant %4 1
+%13 = OpConstant %4 2
+%14 = OpConstantComposite %11 %12 %13
+%15 = OpTypeSampledImage %3
+%17 = OpConstant %4 0
+)");
+
+ EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ R"(%9 = OpLoad %3 %1
+%10 = OpLoad %7 %5
+%16 = OpSampledImage %15 %9 %10
+%8 = OpImageSampleDrefExplicitLod %4 %16 %14 %13 Lod %17
+%19 = OpLoad %3 %1
+%20 = OpLoad %7 %5
+%21 = OpSampledImage %15 %19 %20
+%18 = OpImageSampleDrefExplicitLod %4 %21 %14 %13 Lod %17
)");
}