[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>
This commit is contained in:
dan sinclair 2020-09-21 15:52:10 +00:00 committed by Commit Bot service account
parent 64f9cdec68
commit 43d17780ca
3 changed files with 83 additions and 11 deletions

View File

@ -43,6 +43,7 @@
#include "src/ast/type/f32_type.h" #include "src/ast/type/f32_type.h"
#include "src/ast/type/i32_type.h" #include "src/ast/type/i32_type.h"
#include "src/ast/type/matrix_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/pointer_type.h"
#include "src/ast/type/sampled_texture_type.h" #include "src/ast/type/sampled_texture_type.h"
#include "src/ast/type/storage_texture_type.h" #include "src/ast/type/storage_texture_type.h"
@ -617,16 +618,25 @@ bool TypeDeterminer::DetermineIntrinsic(const std::string& name,
ast::type::TextureType* texture = ast::type::TextureType* texture =
texture_param->result_type()->UnwrapPtrIfNeeded()->AsTexture(); 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); set_error(expr->source(), "invalid texture for " + name);
return false; 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( expr->func()->set_result_type(
ctx_.type_mgr().Get(std::make_unique<ast::type::VectorType>( ctx_.type_mgr().Get(std::make_unique<ast::type::VectorType>(type, 4)));
texture->IsStorage() ? texture->AsStorage()->type()
: texture->AsSampled()->type(),
4)));
return true; return true;
} }
if (name == "dot") { if (name == "dot") {

View File

@ -1538,12 +1538,16 @@ uint32_t Builder::GenerateTextureIntrinsic(const std::string& name,
// TODO: Remove the LOD param from textureLoad on storage textures when // TODO: Remove the LOD param from textureLoad on storage textures when
// https://github.com/gpuweb/gpuweb/pull/1032 gets merged. // https://github.com/gpuweb/gpuweb/pull/1032 gets merged.
if (name == "textureLoad") { if (name == "textureLoad") {
auto spirv_params = {std::move(wgsl_params[0]), std::vector<Operand> spirv_params = {
std::move(wgsl_params[1]), std::move(wgsl_params[0]), std::move(wgsl_params[1]),
std::move(wgsl_params[2]), std::move(wgsl_params[2]), std::move(wgsl_params[3])};
std::move(wgsl_params[3]), if (texture_type->IsMultisampled()) {
Operand::Int(SpvImageOperandsLodMask), spirv_params.push_back(Operand::Int(SpvImageOperandsSampleMask));
std::move(wgsl_params[4])}; } else {
spirv_params.push_back(Operand::Int(SpvImageOperandsLodMask));
}
spirv_params.push_back(std::move(wgsl_params[4]));
auto op = spv::Op::OpImageFetch; auto op = spv::Op::OpImageFetch;
if (texture_type->IsStorage()) { if (texture_type->IsStorage()) {
op = spv::Op::OpImageRead; op = spv::Op::OpImageRead;

View File

@ -25,6 +25,7 @@
#include "src/ast/type/f32_type.h" #include "src/ast/type/f32_type.h"
#include "src/ast/type/i32_type.h" #include "src/ast/type/i32_type.h"
#include "src/ast/type/matrix_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/sampled_texture_type.h"
#include "src/ast/type/sampler_type.h" #include "src/ast/type/sampler_type.h"
#include "src/ast/type/u32_type.h" #include "src/ast/type/u32_type.h"
@ -633,6 +634,63 @@ TEST_F(BuilderTest, Call_TextureLoad_Sampled_2d) {
)"); )");
} }
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) { TEST_F(BuilderTest, Call_TextureSample_1d) {
ast::type::F32Type f32; ast::type::F32Type f32;