[ast] Determining subtype of StorageTextureType
It's determined at the beginning of TypeDeterminer::Determine().
Bug: tint:141
Change-Id: I761199db0c9813dbd42c6cb4ecb3532d1a39f49f
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/27460
Commit-Queue: Tomek Ponitka <tommek@google.com>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/ast/type/storage_texture_type.cc b/src/ast/type/storage_texture_type.cc
index a61fc01..f3f3b9f 100644
--- a/src/ast/type/storage_texture_type.cc
+++ b/src/ast/type/storage_texture_type.cc
@@ -164,6 +164,14 @@
assert(IsValidStorageDimension(dim));
}
+void StorageTextureType::set_type(Type* const type) {
+ type_ = type;
+}
+
+Type* StorageTextureType::type() const {
+ return type_;
+}
+
StorageTextureType::StorageTextureType(StorageTextureType&&) = default;
StorageTextureType::~StorageTextureType() = default;
diff --git a/src/ast/type/storage_texture_type.h b/src/ast/type/storage_texture_type.h
index 2c27ffd..ae6c4fd 100644
--- a/src/ast/type/storage_texture_type.h
+++ b/src/ast/type/storage_texture_type.h
@@ -74,9 +74,10 @@
/// @param dim the dimensionality of the texture
/// @param access the access type for the texture
/// @param format the image format of the texture
- explicit StorageTextureType(TextureDimension dim,
- StorageAccess access,
- ImageFormat format);
+ StorageTextureType(TextureDimension dim,
+ StorageAccess access,
+ ImageFormat format);
+
/// Move constructor
StorageTextureType(StorageTextureType&&);
~StorageTextureType() override;
@@ -84,8 +85,11 @@
/// @returns true if the type is a storage texture type
bool IsStorage() const override;
- /// @returns the subtype of the sampled texture
- Type* type() const { return type_; }
+ /// @param type the subtype of the storage texture
+ void set_type(Type* const type);
+
+ /// @returns the subtype of the storage texture set with set_type
+ Type* type() const;
/// @returns the storage access
StorageAccess access() const { return storage_access_; }
diff --git a/src/ast/type/storage_texture_type_test.cc b/src/ast/type/storage_texture_type_test.cc
index 6c834a0..bc0f503 100644
--- a/src/ast/type/storage_texture_type_test.cc
+++ b/src/ast/type/storage_texture_type_test.cc
@@ -14,6 +14,9 @@
#include "src/ast/type/storage_texture_type.h"
+#include "src/ast/identifier_expression.h"
+#include "src/type_determiner.h"
+
#include "gtest/gtest.h"
namespace tint {
@@ -72,6 +75,48 @@
EXPECT_EQ(s.type_name(), "__storage_texture_read_2d_array_rgba32float");
}
+TEST_F(StorageTextureTypeTest, F32Type) {
+ Context ctx;
+ ast::type::Type* s = ctx.type_mgr().Get(std::make_unique<StorageTextureType>(
+ TextureDimension::k2dArray, StorageAccess::kRead,
+ ImageFormat::kRgba32Float));
+ ast::Module mod;
+ TypeDeterminer td(&ctx, &mod);
+
+ ASSERT_TRUE(td.Determine()) << td.error();
+ ASSERT_TRUE(s->IsTexture());
+ ASSERT_TRUE(s->AsTexture()->IsStorage());
+ EXPECT_TRUE(s->AsTexture()->AsStorage()->type()->IsF32());
+}
+
+TEST_F(StorageTextureTypeTest, U32Type) {
+ Context ctx;
+ ast::type::Type* s = ctx.type_mgr().Get(std::make_unique<StorageTextureType>(
+ TextureDimension::k2dArray, StorageAccess::kRead,
+ ImageFormat::kRgba8Unorm));
+ ast::Module mod;
+ TypeDeterminer td(&ctx, &mod);
+
+ ASSERT_TRUE(td.Determine()) << td.error();
+ ASSERT_TRUE(s->IsTexture());
+ ASSERT_TRUE(s->AsTexture()->IsStorage());
+ EXPECT_TRUE(s->AsTexture()->AsStorage()->type()->IsU32());
+}
+
+TEST_F(StorageTextureTypeTest, I32Type) {
+ Context ctx;
+ ast::type::Type* s = ctx.type_mgr().Get(std::make_unique<StorageTextureType>(
+ TextureDimension::k2dArray, StorageAccess::kRead,
+ ImageFormat::kRgba32Sint));
+ ast::Module mod;
+ TypeDeterminer td(&ctx, &mod);
+
+ ASSERT_TRUE(td.Determine()) << td.error();
+ ASSERT_TRUE(s->IsTexture());
+ ASSERT_TRUE(s->AsTexture()->IsStorage());
+ EXPECT_TRUE(s->AsTexture()->AsStorage()->type()->IsI32());
+}
+
} // namespace
} // namespace type
} // namespace ast
diff --git a/src/type_determiner.cc b/src/type_determiner.cc
index a559d8b..9f2e90d 100644
--- a/src/type_determiner.cc
+++ b/src/type_determiner.cc
@@ -41,9 +41,11 @@
#include "src/ast/type/array_type.h"
#include "src/ast/type/bool_type.h"
#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/pointer_type.h"
#include "src/ast/type/struct_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/unary_op_expression.h"
@@ -177,6 +179,18 @@
}
bool TypeDeterminer::Determine() {
+ for (auto& iter : ctx_.type_mgr().types()) {
+ auto& type = iter.second;
+ if (!type->IsTexture() || !type->AsTexture()->IsStorage()) {
+ continue;
+ }
+ if (!DetermineStorageTextureSubtype(type->AsTexture()->AsStorage())) {
+ set_error(Source{}, "unable to determine storage texture subtype for: " +
+ type->type_name());
+ return false;
+ }
+ }
+
for (const auto& var : mod_->global_variables()) {
variable_stack_.set_global(var->name(), var.get());
@@ -824,6 +838,67 @@
return true;
}
+bool TypeDeterminer::DetermineStorageTextureSubtype(
+ ast::type::StorageTextureType* tex) {
+ if (tex->type() != nullptr) {
+ return true;
+ }
+
+ switch (tex->image_format()) {
+ case ast::type::ImageFormat::kR8Unorm:
+ case ast::type::ImageFormat::kRg8Unorm:
+ case ast::type::ImageFormat::kRgba8Unorm:
+ case ast::type::ImageFormat::kRgba8UnormSrgb:
+ case ast::type::ImageFormat::kBgra8Unorm:
+ case ast::type::ImageFormat::kBgra8UnormSrgb:
+ case ast::type::ImageFormat::kRgb10A2Unorm:
+ case ast::type::ImageFormat::kR8Uint:
+ case ast::type::ImageFormat::kR16Uint:
+ case ast::type::ImageFormat::kRg8Uint:
+ case ast::type::ImageFormat::kR32Uint:
+ case ast::type::ImageFormat::kRg16Uint:
+ case ast::type::ImageFormat::kRgba8Uint:
+ case ast::type::ImageFormat::kRg32Uint:
+ case ast::type::ImageFormat::kRgba16Uint:
+ case ast::type::ImageFormat::kRgba32Uint: {
+ tex->set_type(
+ ctx_.type_mgr().Get(std::make_unique<ast::type::U32Type>()));
+ return true;
+ }
+
+ case ast::type::ImageFormat::kR8Snorm:
+ case ast::type::ImageFormat::kRg8Snorm:
+ case ast::type::ImageFormat::kRgba8Snorm:
+ case ast::type::ImageFormat::kR8Sint:
+ case ast::type::ImageFormat::kR16Sint:
+ case ast::type::ImageFormat::kRg8Sint:
+ case ast::type::ImageFormat::kR32Sint:
+ case ast::type::ImageFormat::kRg16Sint:
+ case ast::type::ImageFormat::kRgba8Sint:
+ case ast::type::ImageFormat::kRg32Sint:
+ case ast::type::ImageFormat::kRgba16Sint:
+ case ast::type::ImageFormat::kRgba32Sint: {
+ tex->set_type(
+ ctx_.type_mgr().Get(std::make_unique<ast::type::I32Type>()));
+ return true;
+ }
+
+ case ast::type::ImageFormat::kR16Float:
+ case ast::type::ImageFormat::kR32Float:
+ case ast::type::ImageFormat::kRg16Float:
+ case ast::type::ImageFormat::kRg11B10Float:
+ case ast::type::ImageFormat::kRg32Float:
+ case ast::type::ImageFormat::kRgba16Float:
+ case ast::type::ImageFormat::kRgba32Float: {
+ tex->set_type(
+ ctx_.type_mgr().Get(std::make_unique<ast::type::F32Type>()));
+ return true;
+ }
+ }
+
+ return false;
+}
+
ast::type::Type* TypeDeterminer::GetImportData(
const Source& source,
const std::string& path,
diff --git a/src/type_determiner.h b/src/type_determiner.h
index cf8f8bd..290357d 100644
--- a/src/type_determiner.h
+++ b/src/type_determiner.h
@@ -19,6 +19,7 @@
#include <unordered_map>
#include "src/ast/module.h"
+#include "src/ast/type/storage_texture_type.h"
#include "src/context.h"
#include "src/scope_stack.h"
@@ -118,6 +119,8 @@
bool DetermineMemberAccessor(ast::MemberAccessorExpression* expr);
bool DetermineUnaryOp(ast::UnaryOpExpression* expr);
+ bool DetermineStorageTextureSubtype(ast::type::StorageTextureType* tex);
+
Context& ctx_;
ast::Module* mod_;
std::string error_;
diff --git a/src/type_manager.h b/src/type_manager.h
index eb26a25..2c82d76 100644
--- a/src/type_manager.h
+++ b/src/type_manager.h
@@ -37,10 +37,10 @@
/// @return the pointer to the registered type
ast::type::Type* Get(std::unique_ptr<ast::type::Type> type);
- /// Returns the type map, for testing purposes.
+ /// Returns the type map
/// @returns the mapping from name string to type.
const std::unordered_map<std::string, std::unique_ptr<ast::type::Type>>&
- TypesForTesting() {
+ types() {
return types_;
}
diff --git a/src/type_manager_test.cc b/src/type_manager_test.cc
index 1628ffb..217259a 100644
--- a/src/type_manager_test.cc
+++ b/src/type_manager_test.cc
@@ -57,9 +57,9 @@
auto* t = tm.Get(std::make_unique<ast::type::I32Type>());
ASSERT_NE(t, nullptr);
- EXPECT_FALSE(tm.TypesForTesting().empty());
+ EXPECT_FALSE(tm.types().empty());
tm.Reset();
- EXPECT_TRUE(tm.TypesForTesting().empty());
+ EXPECT_TRUE(tm.types().empty());
auto* t2 = tm.Get(std::make_unique<ast::type::I32Type>());
ASSERT_NE(t2, nullptr);