[spirv-writer] Add multisampled textureLoad test.
This CL adds a test for multisampled textureLoad and fixes up a few type
determiner issues for multisampled textures.
Bug: tint:237
Change-Id: I5c33797b197b6f092842b22aa93d2076b0779766
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/28582
Reviewed-by: Ryan Harrison <rharrison@chromium.org>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
diff --git a/src/type_determiner.cc b/src/type_determiner.cc
index 479382f..948b04c 100644
--- a/src/type_determiner.cc
+++ b/src/type_determiner.cc
@@ -43,6 +43,7 @@
#include "src/ast/type/f32_type.h"
#include "src/ast/type/i32_type.h"
#include "src/ast/type/matrix_type.h"
+#include "src/ast/type/multisampled_texture_type.h"
#include "src/ast/type/pointer_type.h"
#include "src/ast/type/sampled_texture_type.h"
#include "src/ast/type/storage_texture_type.h"
@@ -617,16 +618,25 @@
ast::type::TextureType* texture =
texture_param->result_type()->UnwrapPtrIfNeeded()->AsTexture();
- if (!texture->IsStorage() && !texture->IsSampled()) {
+ if (!texture->IsStorage() &&
+ !(texture->IsSampled() || texture->IsMultisampled())) {
set_error(expr->source(), "invalid texture for " + name);
return false;
}
+ ast::type::Type* type = nullptr;
+ if (texture->IsStorage()) {
+ type = texture->AsStorage()->type();
+ } else if (texture->IsSampled()) {
+ type = texture->AsSampled()->type();
+ } else if (texture->IsMultisampled()) {
+ type = texture->AsMultisampled()->type();
+ } else {
+ set_error(expr->source(), "unknown texture type for texture sampling");
+ return false;
+ }
expr->func()->set_result_type(
- ctx_.type_mgr().Get(std::make_unique<ast::type::VectorType>(
- texture->IsStorage() ? texture->AsStorage()->type()
- : texture->AsSampled()->type(),
- 4)));
+ ctx_.type_mgr().Get(std::make_unique<ast::type::VectorType>(type, 4)));
return true;
}
if (name == "dot") {
diff --git a/src/writer/spirv/builder.cc b/src/writer/spirv/builder.cc
index 795e16d..5bfdd9f 100644
--- a/src/writer/spirv/builder.cc
+++ b/src/writer/spirv/builder.cc
@@ -1538,12 +1538,16 @@
// TODO: Remove the LOD param from textureLoad on storage textures when
// https://github.com/gpuweb/gpuweb/pull/1032 gets merged.
if (name == "textureLoad") {
- auto spirv_params = {std::move(wgsl_params[0]),
- std::move(wgsl_params[1]),
- std::move(wgsl_params[2]),
- std::move(wgsl_params[3]),
- Operand::Int(SpvImageOperandsLodMask),
- std::move(wgsl_params[4])};
+ std::vector<Operand> spirv_params = {
+ std::move(wgsl_params[0]), std::move(wgsl_params[1]),
+ std::move(wgsl_params[2]), std::move(wgsl_params[3])};
+ if (texture_type->IsMultisampled()) {
+ spirv_params.push_back(Operand::Int(SpvImageOperandsSampleMask));
+ } else {
+ spirv_params.push_back(Operand::Int(SpvImageOperandsLodMask));
+ }
+ spirv_params.push_back(std::move(wgsl_params[4]));
+
auto op = spv::Op::OpImageFetch;
if (texture_type->IsStorage()) {
op = spv::Op::OpImageRead;
diff --git a/src/writer/spirv/builder_intrinsic_test.cc b/src/writer/spirv/builder_intrinsic_test.cc
index 0efcdf3..1fbc36b 100644
--- a/src/writer/spirv/builder_intrinsic_test.cc
+++ b/src/writer/spirv/builder_intrinsic_test.cc
@@ -25,6 +25,7 @@
#include "src/ast/type/f32_type.h"
#include "src/ast/type/i32_type.h"
#include "src/ast/type/matrix_type.h"
+#include "src/ast/type/multisampled_texture_type.h"
#include "src/ast/type/sampled_texture_type.h"
#include "src/ast/type/sampler_type.h"
#include "src/ast/type/u32_type.h"
@@ -633,6 +634,63 @@
)");
}
+TEST_F(BuilderTest, Call_TextureLoad_Multisampled_2d) {
+ ast::type::F32Type f32;
+ ast::type::I32Type i32;
+ ast::type::VectorType vec2(&f32, 2);
+ ast::type::MultisampledTextureType 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));
+
+ ASSERT_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 1 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 Sample %13
+)");
+}
+
TEST_F(BuilderTest, Call_TextureSample_1d) {
ast::type::F32Type f32;