[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:
parent
64f9cdec68
commit
43d17780ca
|
@ -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 @@ bool TypeDeterminer::DetermineIntrinsic(const std::string& name,
|
|||
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") {
|
||||
|
|
|
@ -1538,12 +1538,16 @@ uint32_t Builder::GenerateTextureIntrinsic(const std::string& name,
|
|||
// 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;
|
||||
|
|
|
@ -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_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) {
|
||||
ast::type::F32Type f32;
|
||||
|
||||
|
|
Loading…
Reference in New Issue