mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-16 08:27:05 +00:00
Implement Default Struct Layout
Implements https://github.com/gpuweb/gpuweb/pull/1447 SPIR-V Reader is still TODO, but continues to function as the offset decoration is still supported. Bug: tint:626 Bug: tint:629 Change-Id: Id574eb3a5c6729559382812de37b23f0c68fd406 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/43640 Commit-Queue: Ben Clayton <bclayton@chromium.org> Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
committed by
Commit Bot service account
parent
717fbbf183
commit
d614dd5d12
@@ -65,14 +65,6 @@ std::string AccessControl::FriendlyName(const SymbolTable& symbols) const {
|
||||
return out.str();
|
||||
}
|
||||
|
||||
uint64_t AccessControl::MinBufferBindingSize(MemoryLayout mem_layout) const {
|
||||
return subtype_->MinBufferBindingSize(mem_layout);
|
||||
}
|
||||
|
||||
uint64_t AccessControl::BaseAlignment(MemoryLayout mem_layout) const {
|
||||
return subtype_->BaseAlignment(mem_layout);
|
||||
}
|
||||
|
||||
AccessControl* AccessControl::Clone(CloneContext* ctx) const {
|
||||
// Clone arguments outside of create() call to have deterministic ordering
|
||||
auto* ty = ctx->Clone(type());
|
||||
|
||||
@@ -54,16 +54,6 @@ class AccessControl : public Castable<AccessControl, Type> {
|
||||
/// declared in WGSL.
|
||||
std::string FriendlyName(const SymbolTable& symbols) const override;
|
||||
|
||||
/// @param mem_layout type of memory layout to use in calculation.
|
||||
/// @returns minimum size required for this type, in bytes.
|
||||
/// 0 for non-host shareable types.
|
||||
uint64_t MinBufferBindingSize(MemoryLayout mem_layout) const override;
|
||||
|
||||
/// @param mem_layout type of memory layout to use in calculation.
|
||||
/// @returns base alignment for the type, in bytes.
|
||||
/// 0 for non-host shareable types.
|
||||
uint64_t BaseAlignment(MemoryLayout mem_layout) const override;
|
||||
|
||||
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
|
||||
/// @param ctx the clone context
|
||||
/// @return the newly cloned type
|
||||
|
||||
@@ -95,70 +95,6 @@ TEST_F(AccessControlTest, FriendlyNameReadWrite) {
|
||||
EXPECT_EQ(at.FriendlyName(Symbols()), "[[access(read_write)]] i32");
|
||||
}
|
||||
|
||||
TEST_F(AccessControlTest, MinBufferBindingSizeU32) {
|
||||
U32 u32;
|
||||
AccessControl at{ast::AccessControl::kReadOnly, &u32};
|
||||
EXPECT_EQ(4u, at.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
|
||||
}
|
||||
|
||||
TEST_F(AccessControlTest, MinBufferBindingSizeArray) {
|
||||
U32 u32;
|
||||
Array array(&u32, 4, ast::DecorationList{create<ast::StrideDecoration>(4)});
|
||||
AccessControl at{ast::AccessControl::kReadOnly, &array};
|
||||
EXPECT_EQ(16u, at.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
|
||||
}
|
||||
|
||||
TEST_F(AccessControlTest, MinBufferBindingSizeRuntimeArray) {
|
||||
U32 u32;
|
||||
Array array(&u32, 0, ast::DecorationList{create<ast::StrideDecoration>(4)});
|
||||
AccessControl at{ast::AccessControl::kReadOnly, &array};
|
||||
EXPECT_EQ(4u, at.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
|
||||
}
|
||||
|
||||
TEST_F(AccessControlTest, MinBufferBindingSizeStruct) {
|
||||
auto* str = create<ast::Struct>(
|
||||
ast::StructMemberList{Member("foo", ty.u32(), {MemberOffset(0)}),
|
||||
Member("bar", ty.u32(), {MemberOffset(4)})},
|
||||
ast::DecorationList{});
|
||||
|
||||
auto* struct_type = ty.struct_("struct_type", str);
|
||||
AccessControl at{ast::AccessControl::kReadOnly, struct_type};
|
||||
EXPECT_EQ(16u, at.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
|
||||
EXPECT_EQ(8u, at.MinBufferBindingSize(MemoryLayout::kStorageBuffer));
|
||||
}
|
||||
|
||||
TEST_F(AccessControlTest, BaseAlignmentU32) {
|
||||
U32 u32;
|
||||
AccessControl at{ast::AccessControl::kReadOnly, &u32};
|
||||
EXPECT_EQ(4u, at.BaseAlignment(MemoryLayout::kUniformBuffer));
|
||||
}
|
||||
|
||||
TEST_F(AccessControlTest, BaseAlignmentArray) {
|
||||
U32 u32;
|
||||
Array array(&u32, 4, ast::DecorationList{create<ast::StrideDecoration>(4)});
|
||||
AccessControl at{ast::AccessControl::kReadOnly, &array};
|
||||
EXPECT_EQ(16u, at.BaseAlignment(MemoryLayout::kUniformBuffer));
|
||||
}
|
||||
|
||||
TEST_F(AccessControlTest, BaseAlignmentRuntimeArray) {
|
||||
U32 u32;
|
||||
Array array(&u32, 0, ast::DecorationList{create<ast::StrideDecoration>(4)});
|
||||
AccessControl at{ast::AccessControl::kReadOnly, &array};
|
||||
EXPECT_EQ(16u, at.BaseAlignment(MemoryLayout::kUniformBuffer));
|
||||
}
|
||||
|
||||
TEST_F(AccessControlTest, BaseAlignmentStruct) {
|
||||
auto* str = create<ast::Struct>(
|
||||
ast::StructMemberList{Member("foo", ty.u32(), {MemberOffset(0)}),
|
||||
Member("bar", ty.u32(), {MemberOffset(4)})},
|
||||
ast::DecorationList{});
|
||||
auto* struct_type = ty.struct_("struct_type", str);
|
||||
|
||||
AccessControl at{ast::AccessControl::kReadOnly, struct_type};
|
||||
EXPECT_EQ(16u, at.BaseAlignment(MemoryLayout::kUniformBuffer));
|
||||
EXPECT_EQ(4u, at.BaseAlignment(MemoryLayout::kStorageBuffer));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace type
|
||||
} // namespace tint
|
||||
|
||||
@@ -38,14 +38,6 @@ std::string Alias::FriendlyName(const SymbolTable& symbols) const {
|
||||
return symbols.NameFor(symbol_);
|
||||
}
|
||||
|
||||
uint64_t Alias::MinBufferBindingSize(MemoryLayout mem_layout) const {
|
||||
return subtype_->MinBufferBindingSize(mem_layout);
|
||||
}
|
||||
|
||||
uint64_t Alias::BaseAlignment(MemoryLayout mem_layout) const {
|
||||
return subtype_->BaseAlignment(mem_layout);
|
||||
}
|
||||
|
||||
Alias* Alias::Clone(CloneContext* ctx) const {
|
||||
// Clone arguments outside of create() call to have deterministic ordering
|
||||
auto sym = ctx->Clone(symbol());
|
||||
|
||||
@@ -47,16 +47,6 @@ class Alias : public Castable<Alias, Type> {
|
||||
/// declared in WGSL.
|
||||
std::string FriendlyName(const SymbolTable& symbols) const override;
|
||||
|
||||
/// @param mem_layout type of memory layout to use in calculation.
|
||||
/// @returns minimum size required for this type, in bytes.
|
||||
/// 0 for non-host shareable types.
|
||||
uint64_t MinBufferBindingSize(MemoryLayout mem_layout) const override;
|
||||
|
||||
/// @param mem_layout type of memory layout to use in calculation.
|
||||
/// @returns base alignment for the type, in bytes.
|
||||
/// 0 for non-host shareable types.
|
||||
uint64_t BaseAlignment(MemoryLayout mem_layout) const override;
|
||||
|
||||
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
|
||||
/// @param ctx the clone context
|
||||
/// @return the newly cloned type
|
||||
|
||||
@@ -137,76 +137,6 @@ TEST_F(AliasTest, UnwrapAll_PointerAccessControl) {
|
||||
EXPECT_EQ(a.UnwrapAll(), ty.u32());
|
||||
}
|
||||
|
||||
TEST_F(AliasTest, MinBufferBindingSizeU32) {
|
||||
auto* alias = ty.alias("alias", ty.u32());
|
||||
EXPECT_EQ(4u, alias->MinBufferBindingSize(MemoryLayout::kUniformBuffer));
|
||||
}
|
||||
|
||||
TEST_F(AliasTest, MinBufferBindingSizeArray) {
|
||||
Array array(ty.u32(), 4,
|
||||
ast::DecorationList{
|
||||
create<ast::StrideDecoration>(4),
|
||||
});
|
||||
auto* alias = ty.alias("alias", &array);
|
||||
EXPECT_EQ(16u, alias->MinBufferBindingSize(MemoryLayout::kUniformBuffer));
|
||||
}
|
||||
|
||||
TEST_F(AliasTest, MinBufferBindingSizeRuntimeArray) {
|
||||
Array array(ty.u32(), 0,
|
||||
ast::DecorationList{
|
||||
create<ast::StrideDecoration>(4),
|
||||
});
|
||||
auto* alias = ty.alias("alias", &array);
|
||||
EXPECT_EQ(4u, alias->MinBufferBindingSize(MemoryLayout::kUniformBuffer));
|
||||
}
|
||||
|
||||
TEST_F(AliasTest, MinBufferBindingSizeStruct) {
|
||||
auto* str = create<ast::Struct>(
|
||||
ast::StructMemberList{Member("foo", ty.u32(), {MemberOffset(0)}),
|
||||
Member("bar", ty.u32(), {MemberOffset(4)})},
|
||||
ast::DecorationList{});
|
||||
auto* struct_type = ty.struct_("struct_type", str);
|
||||
auto* alias = ty.alias("alias", struct_type);
|
||||
|
||||
EXPECT_EQ(16u, alias->MinBufferBindingSize(MemoryLayout::kUniformBuffer));
|
||||
EXPECT_EQ(8u, alias->MinBufferBindingSize(MemoryLayout::kStorageBuffer));
|
||||
}
|
||||
|
||||
TEST_F(AliasTest, BaseAlignmentU32) {
|
||||
auto* alias = ty.alias("alias", ty.u32());
|
||||
EXPECT_EQ(4u, alias->BaseAlignment(MemoryLayout::kUniformBuffer));
|
||||
}
|
||||
|
||||
TEST_F(AliasTest, BaseAlignmentArray) {
|
||||
Array array(ty.u32(), 4,
|
||||
ast::DecorationList{
|
||||
create<ast::StrideDecoration>(4),
|
||||
});
|
||||
auto* alias = ty.alias("alias", &array);
|
||||
EXPECT_EQ(16u, alias->BaseAlignment(MemoryLayout::kUniformBuffer));
|
||||
}
|
||||
|
||||
TEST_F(AliasTest, BaseAlignmentRuntimeArray) {
|
||||
Array array(ty.u32(), 0,
|
||||
ast::DecorationList{
|
||||
create<ast::StrideDecoration>(4),
|
||||
});
|
||||
auto* alias = ty.alias("alias", &array);
|
||||
EXPECT_EQ(16u, alias->BaseAlignment(MemoryLayout::kUniformBuffer));
|
||||
}
|
||||
|
||||
TEST_F(AliasTest, BaseAlignmentStruct) {
|
||||
auto* str = create<ast::Struct>(
|
||||
ast::StructMemberList{Member("foo", ty.u32(), {MemberOffset(0)}),
|
||||
Member("bar", ty.u32(), {MemberOffset(4)})},
|
||||
ast::DecorationList{});
|
||||
auto* struct_type = ty.struct_("struct_type", str);
|
||||
auto* alias = ty.alias("alias", struct_type);
|
||||
|
||||
EXPECT_EQ(16u, alias->BaseAlignment(MemoryLayout::kUniformBuffer));
|
||||
EXPECT_EQ(4u, alias->BaseAlignment(MemoryLayout::kStorageBuffer));
|
||||
}
|
||||
|
||||
TEST_F(AliasTest, UnwrapAliasIfNeeded) {
|
||||
auto* alias1 = ty.alias("alias1", ty.f32());
|
||||
auto* alias2 = ty.alias("alias2", alias1);
|
||||
|
||||
@@ -30,71 +30,28 @@ Array::Array(Array&&) = default;
|
||||
|
||||
Array::~Array() = default;
|
||||
|
||||
uint64_t Array::MinBufferBindingSize(MemoryLayout mem_layout) const {
|
||||
if (!has_array_stride()) {
|
||||
// Arrays in buffers are required to have a stride.
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (IsRuntimeArray()) {
|
||||
// WebGPU spec 10.1.2:
|
||||
// If the last field of the corresponding structure defined in the shader
|
||||
// has an unbounded array type, then the value of minBufferBindingSize must
|
||||
// be greater than or equal to the byte offset of that field plus the stride
|
||||
// of the unbounded array
|
||||
return array_stride();
|
||||
} else {
|
||||
// Not including the padding for the last element
|
||||
return (size_ - 1) * array_stride() +
|
||||
subtype_->MinBufferBindingSize(mem_layout);
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t Array::BaseAlignment(MemoryLayout mem_layout) const {
|
||||
if (mem_layout == MemoryLayout::kUniformBuffer) {
|
||||
float aligment = 16; // for a vec4
|
||||
float unaligned = static_cast<float>(subtype_->BaseAlignment(mem_layout));
|
||||
return static_cast<uint64_t>(aligment * std::ceil(unaligned / aligment));
|
||||
} else if (mem_layout == MemoryLayout::kStorageBuffer) {
|
||||
return subtype_->BaseAlignment(mem_layout);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t Array::array_stride() const {
|
||||
for (auto* deco : decos_) {
|
||||
if (auto* stride = deco->As<ast::StrideDecoration>()) {
|
||||
return stride->stride();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Array::has_array_stride() const {
|
||||
for (auto* deco : decos_) {
|
||||
if (deco->Is<ast::StrideDecoration>()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string Array::type_name() const {
|
||||
assert(subtype_);
|
||||
|
||||
std::string type_name = "__array" + subtype_->type_name();
|
||||
if (!IsRuntimeArray())
|
||||
if (!IsRuntimeArray()) {
|
||||
type_name += "_" + std::to_string(size_);
|
||||
if (has_array_stride())
|
||||
type_name += "_stride_" + std::to_string(array_stride());
|
||||
}
|
||||
for (auto* deco : decos_) {
|
||||
if (auto* stride = deco->As<ast::StrideDecoration>()) {
|
||||
type_name += "_stride_" + std::to_string(stride->stride());
|
||||
}
|
||||
}
|
||||
|
||||
return type_name;
|
||||
}
|
||||
|
||||
std::string Array::FriendlyName(const SymbolTable& symbols) const {
|
||||
std::ostringstream out;
|
||||
if (has_array_stride()) {
|
||||
out << "[[stride(" << array_stride() << ")]] ";
|
||||
for (auto* deco : decos_) {
|
||||
if (auto* stride = deco->As<ast::StrideDecoration>()) {
|
||||
out << "[[stride(" << stride->stride() << ")]] ";
|
||||
}
|
||||
}
|
||||
out << "array<" << subtype_->FriendlyName(symbols);
|
||||
if (!IsRuntimeArray()) {
|
||||
|
||||
@@ -40,24 +40,9 @@ class Array : public Castable<Array, Type> {
|
||||
/// i.e. the size is determined at runtime
|
||||
bool IsRuntimeArray() const { return size_ == 0; }
|
||||
|
||||
/// @param mem_layout type of memory layout to use in calculation.
|
||||
/// @returns minimum size required for this type, in bytes.
|
||||
/// 0 for non-host shareable types.
|
||||
uint64_t MinBufferBindingSize(MemoryLayout mem_layout) const override;
|
||||
|
||||
/// @param mem_layout type of memory layout to use in calculation.
|
||||
/// @returns base alignment for the type, in bytes.
|
||||
/// 0 for non-host shareable types.
|
||||
uint64_t BaseAlignment(MemoryLayout mem_layout) const override;
|
||||
|
||||
/// @returns the array decorations
|
||||
const ast::DecorationList& decorations() const { return decos_; }
|
||||
|
||||
/// @returns the array stride or 0 if none set.
|
||||
uint32_t array_stride() const;
|
||||
/// @returns true if the array has a stride set
|
||||
bool has_array_stride() const;
|
||||
|
||||
/// @returns the array type
|
||||
Type* type() const { return subtype_; }
|
||||
/// @returns the array size. Size is 0 for a runtime array
|
||||
|
||||
@@ -94,38 +94,6 @@ TEST_F(ArrayTest, TypeName_WithStride) {
|
||||
EXPECT_EQ(arr.type_name(), "__array__i32_3_stride_16");
|
||||
}
|
||||
|
||||
TEST_F(ArrayTest, MinBufferBindingSizeNoStride) {
|
||||
U32 u32;
|
||||
Array arr(&u32, 4, ast::DecorationList{});
|
||||
EXPECT_EQ(0u, arr.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
|
||||
}
|
||||
|
||||
TEST_F(ArrayTest, MinBufferBindingSizeArray) {
|
||||
U32 u32;
|
||||
Array arr(&u32, 4, ast::DecorationList{create<ast::StrideDecoration>(4)});
|
||||
EXPECT_EQ(16u, arr.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
|
||||
}
|
||||
|
||||
TEST_F(ArrayTest, MinBufferBindingSizeRuntimeArray) {
|
||||
U32 u32;
|
||||
Array arr(&u32, 0, ast::DecorationList{create<ast::StrideDecoration>(4)});
|
||||
EXPECT_EQ(4u, arr.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
|
||||
}
|
||||
|
||||
TEST_F(ArrayTest, BaseAlignmentArray) {
|
||||
U32 u32;
|
||||
Array arr(&u32, 4, ast::DecorationList{create<ast::StrideDecoration>(4)});
|
||||
EXPECT_EQ(16u, arr.BaseAlignment(MemoryLayout::kUniformBuffer));
|
||||
EXPECT_EQ(4u, arr.BaseAlignment(MemoryLayout::kStorageBuffer));
|
||||
}
|
||||
|
||||
TEST_F(ArrayTest, BaseAlignmentRuntimeArray) {
|
||||
U32 u32;
|
||||
Array arr(&u32, 0, ast::DecorationList{create<ast::StrideDecoration>(4)});
|
||||
EXPECT_EQ(16u, arr.BaseAlignment(MemoryLayout::kUniformBuffer));
|
||||
EXPECT_EQ(4u, arr.BaseAlignment(MemoryLayout::kStorageBuffer));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace type
|
||||
} // namespace tint
|
||||
|
||||
@@ -50,11 +50,6 @@ TEST_F(BoolTest, FriendlyName) {
|
||||
EXPECT_EQ(b.FriendlyName(Symbols()), "bool");
|
||||
}
|
||||
|
||||
TEST_F(BoolTest, MinBufferBindingSize) {
|
||||
Bool b;
|
||||
EXPECT_EQ(0u, b.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace type
|
||||
} // namespace tint
|
||||
|
||||
@@ -67,11 +67,6 @@ TEST_F(DepthTextureTest, FriendlyName) {
|
||||
EXPECT_EQ(d.FriendlyName(Symbols()), "texture_depth_cube");
|
||||
}
|
||||
|
||||
TEST_F(DepthTextureTest, MinBufferBindingSize) {
|
||||
DepthTexture d(TextureDimension::kCube);
|
||||
EXPECT_EQ(0u, d.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace type
|
||||
} // namespace tint
|
||||
|
||||
@@ -35,14 +35,6 @@ std::string F32::FriendlyName(const SymbolTable&) const {
|
||||
return "f32";
|
||||
}
|
||||
|
||||
uint64_t F32::MinBufferBindingSize(MemoryLayout) const {
|
||||
return 4;
|
||||
}
|
||||
|
||||
uint64_t F32::BaseAlignment(MemoryLayout) const {
|
||||
return 4;
|
||||
}
|
||||
|
||||
F32* F32::Clone(CloneContext* ctx) const {
|
||||
return ctx->dst->create<F32>();
|
||||
}
|
||||
|
||||
@@ -39,16 +39,6 @@ class F32 : public Castable<F32, Type> {
|
||||
/// declared in WGSL.
|
||||
std::string FriendlyName(const SymbolTable& symbols) const override;
|
||||
|
||||
/// @param mem_layout type of memory layout to use in calculation.
|
||||
/// @returns minimum size required for this type, in bytes.
|
||||
/// 0 for non-host shareable types.
|
||||
uint64_t MinBufferBindingSize(MemoryLayout mem_layout) const override;
|
||||
|
||||
/// @param mem_layout type of memory layout to use in calculation.
|
||||
/// @returns base alignment for the type, in bytes.
|
||||
/// 0 for non-host shareable types.
|
||||
uint64_t BaseAlignment(MemoryLayout mem_layout) const override;
|
||||
|
||||
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
|
||||
/// @param ctx the clone context
|
||||
/// @return the newly cloned type
|
||||
|
||||
@@ -50,16 +50,6 @@ TEST_F(F32Test, FriendlyName) {
|
||||
EXPECT_EQ(f.FriendlyName(Symbols()), "f32");
|
||||
}
|
||||
|
||||
TEST_F(F32Test, MinBufferBindingSize) {
|
||||
F32 f;
|
||||
EXPECT_EQ(4u, f.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
|
||||
}
|
||||
|
||||
TEST_F(F32Test, BaseAlignment) {
|
||||
F32 f;
|
||||
EXPECT_EQ(4u, f.BaseAlignment(MemoryLayout::kUniformBuffer));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace type
|
||||
} // namespace tint
|
||||
|
||||
@@ -35,14 +35,6 @@ std::string I32::FriendlyName(const SymbolTable&) const {
|
||||
return "i32";
|
||||
}
|
||||
|
||||
uint64_t I32::MinBufferBindingSize(MemoryLayout) const {
|
||||
return 4;
|
||||
}
|
||||
|
||||
uint64_t I32::BaseAlignment(MemoryLayout) const {
|
||||
return 4;
|
||||
}
|
||||
|
||||
I32* I32::Clone(CloneContext* ctx) const {
|
||||
return ctx->dst->create<I32>();
|
||||
}
|
||||
|
||||
@@ -39,16 +39,6 @@ class I32 : public Castable<I32, Type> {
|
||||
/// declared in WGSL.
|
||||
std::string FriendlyName(const SymbolTable& symbols) const override;
|
||||
|
||||
/// @param mem_layout type of memory layout to use in calculation.
|
||||
/// @returns minimum size required for this type, in bytes.
|
||||
/// 0 for non-host shareable types.
|
||||
uint64_t MinBufferBindingSize(MemoryLayout mem_layout) const override;
|
||||
|
||||
/// @param mem_layout type of memory layout to use in calculation.
|
||||
/// @returns base alignment for the type, in bytes.
|
||||
/// 0 for non-host shareable types.
|
||||
uint64_t BaseAlignment(MemoryLayout mem_layout) const override;
|
||||
|
||||
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
|
||||
/// @param ctx the clone context
|
||||
/// @return the newly cloned type
|
||||
|
||||
@@ -50,16 +50,6 @@ TEST_F(I32Test, FriendlyName) {
|
||||
EXPECT_EQ(i.FriendlyName(Symbols()), "i32");
|
||||
}
|
||||
|
||||
TEST_F(I32Test, MinBufferBindingSize) {
|
||||
I32 i;
|
||||
EXPECT_EQ(4u, i.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
|
||||
}
|
||||
|
||||
TEST_F(I32Test, BaseAlignment) {
|
||||
I32 i;
|
||||
EXPECT_EQ(4u, i.BaseAlignment(MemoryLayout::kUniformBuffer));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace type
|
||||
} // namespace tint
|
||||
|
||||
@@ -45,18 +45,6 @@ std::string Matrix::FriendlyName(const SymbolTable& symbols) const {
|
||||
return out.str();
|
||||
}
|
||||
|
||||
uint64_t Matrix::MinBufferBindingSize(MemoryLayout mem_layout) const {
|
||||
Vector vec(subtype_, rows_);
|
||||
return (columns_ - 1) * vec.BaseAlignment(mem_layout) +
|
||||
vec.MinBufferBindingSize(mem_layout);
|
||||
}
|
||||
|
||||
uint64_t Matrix::BaseAlignment(MemoryLayout mem_layout) const {
|
||||
Vector vec(subtype_, rows_);
|
||||
Array arr(&vec, columns_, ast::DecorationList{});
|
||||
return arr.BaseAlignment(mem_layout);
|
||||
}
|
||||
|
||||
Matrix* Matrix::Clone(CloneContext* ctx) const {
|
||||
// Clone arguments outside of create() call to have deterministic ordering
|
||||
auto* ty = ctx->Clone(type());
|
||||
|
||||
@@ -49,16 +49,6 @@ class Matrix : public Castable<Matrix, Type> {
|
||||
/// declared in WGSL.
|
||||
std::string FriendlyName(const SymbolTable& symbols) const override;
|
||||
|
||||
/// @param mem_layout type of memory layout to use in calculation.
|
||||
/// @returns minimum size required for this type, in bytes.
|
||||
/// 0 for non-host shareable types.
|
||||
uint64_t MinBufferBindingSize(MemoryLayout mem_layout) const override;
|
||||
|
||||
/// @param mem_layout type of memory layout to use in calculation.
|
||||
/// @returns base alignment for the type, in bytes.
|
||||
/// 0 for non-host shareable types.
|
||||
uint64_t BaseAlignment(MemoryLayout mem_layout) const override;
|
||||
|
||||
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
|
||||
/// @param ctx the clone context
|
||||
/// @return the newly cloned type
|
||||
|
||||
@@ -60,62 +60,6 @@ TEST_F(MatrixTest, FriendlyName) {
|
||||
EXPECT_EQ(m.FriendlyName(Symbols()), "mat2x3<i32>");
|
||||
}
|
||||
|
||||
TEST_F(MatrixTest, MinBufferBindingSize4x2) {
|
||||
I32 i32;
|
||||
Matrix m{&i32, 4, 2};
|
||||
EXPECT_EQ(32u, m.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
|
||||
EXPECT_EQ(32u, m.MinBufferBindingSize(MemoryLayout::kStorageBuffer));
|
||||
}
|
||||
|
||||
TEST_F(MatrixTest, MinBufferBindingSize3x2) {
|
||||
I32 i32;
|
||||
Matrix m{&i32, 3, 2};
|
||||
EXPECT_EQ(28u, m.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
|
||||
EXPECT_EQ(28u, m.MinBufferBindingSize(MemoryLayout::kStorageBuffer));
|
||||
}
|
||||
|
||||
TEST_F(MatrixTest, MinBufferBindingSize2x3) {
|
||||
I32 i32;
|
||||
Matrix m{&i32, 2, 3};
|
||||
EXPECT_EQ(24u, m.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
|
||||
EXPECT_EQ(24u, m.MinBufferBindingSize(MemoryLayout::kStorageBuffer));
|
||||
}
|
||||
|
||||
TEST_F(MatrixTest, MinBufferBindingSize2x2) {
|
||||
I32 i32;
|
||||
Matrix m{&i32, 2, 2};
|
||||
EXPECT_EQ(16u, m.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
|
||||
EXPECT_EQ(16u, m.MinBufferBindingSize(MemoryLayout::kStorageBuffer));
|
||||
}
|
||||
|
||||
TEST_F(MatrixTest, BaseAlignment4x2) {
|
||||
I32 i32;
|
||||
Matrix m{&i32, 4, 2};
|
||||
EXPECT_EQ(16u, m.BaseAlignment(MemoryLayout::kUniformBuffer));
|
||||
EXPECT_EQ(16u, m.BaseAlignment(MemoryLayout::kStorageBuffer));
|
||||
}
|
||||
|
||||
TEST_F(MatrixTest, BaseAlignment3x2) {
|
||||
I32 i32;
|
||||
Matrix m{&i32, 3, 2};
|
||||
EXPECT_EQ(16u, m.BaseAlignment(MemoryLayout::kUniformBuffer));
|
||||
EXPECT_EQ(16u, m.BaseAlignment(MemoryLayout::kStorageBuffer));
|
||||
}
|
||||
|
||||
TEST_F(MatrixTest, BaseAlignment2x3) {
|
||||
I32 i32;
|
||||
Matrix m{&i32, 2, 3};
|
||||
EXPECT_EQ(16u, m.BaseAlignment(MemoryLayout::kUniformBuffer));
|
||||
EXPECT_EQ(8u, m.BaseAlignment(MemoryLayout::kStorageBuffer));
|
||||
}
|
||||
|
||||
TEST_F(MatrixTest, BaseAlignment2x2) {
|
||||
I32 i32;
|
||||
Matrix m{&i32, 2, 2};
|
||||
EXPECT_EQ(16u, m.BaseAlignment(MemoryLayout::kUniformBuffer));
|
||||
EXPECT_EQ(8u, m.BaseAlignment(MemoryLayout::kStorageBuffer));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace type
|
||||
} // namespace tint
|
||||
|
||||
@@ -78,12 +78,6 @@ TEST_F(MultisampledTextureTest, FriendlyName) {
|
||||
EXPECT_EQ(s.FriendlyName(Symbols()), "texture_multisampled_3d<f32>");
|
||||
}
|
||||
|
||||
TEST_F(MultisampledTextureTest, MinBufferBindingSize) {
|
||||
F32 f32;
|
||||
MultisampledTexture s(TextureDimension::k3d, &f32);
|
||||
EXPECT_EQ(0u, s.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace type
|
||||
} // namespace tint
|
||||
|
||||
@@ -76,12 +76,6 @@ TEST_F(SampledTextureTest, FriendlyName) {
|
||||
EXPECT_EQ(s.FriendlyName(Symbols()), "texture_3d<f32>");
|
||||
}
|
||||
|
||||
TEST_F(SampledTextureTest, MinBufferBindingSize) {
|
||||
F32 f32;
|
||||
SampledTexture s(TextureDimension::kCube, &f32);
|
||||
EXPECT_EQ(0u, s.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace type
|
||||
} // namespace tint
|
||||
|
||||
@@ -71,11 +71,6 @@ TEST_F(SamplerTest, FriendlyNameComparisonSampler) {
|
||||
EXPECT_EQ(s.FriendlyName(Symbols()), "sampler_comparison");
|
||||
}
|
||||
|
||||
TEST_F(SamplerTest, MinBufferBindingSize) {
|
||||
Sampler s{SamplerKind::kSampler};
|
||||
EXPECT_EQ(0u, s.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace type
|
||||
} // namespace tint
|
||||
|
||||
@@ -132,13 +132,6 @@ TEST_F(StorageTextureTest, I32) {
|
||||
EXPECT_TRUE(s->As<StorageTexture>()->type()->Is<I32>());
|
||||
}
|
||||
|
||||
TEST_F(StorageTextureTest, MinBufferBindingSize) {
|
||||
auto* subtype = StorageTexture::SubtypeFor(ImageFormat::kRgba32Sint, Types());
|
||||
auto* s = create<StorageTexture>(TextureDimension::k2dArray,
|
||||
ImageFormat::kRgba32Sint, subtype);
|
||||
EXPECT_EQ(0u, s->MinBufferBindingSize(MemoryLayout::kUniformBuffer));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace type
|
||||
} // namespace tint
|
||||
|
||||
@@ -38,48 +38,6 @@ std::string Struct::FriendlyName(const SymbolTable& symbols) const {
|
||||
return symbols.NameFor(symbol_);
|
||||
}
|
||||
|
||||
uint64_t Struct::MinBufferBindingSize(MemoryLayout mem_layout) const {
|
||||
if (!struct_->members().size()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto* last_member = struct_->members().back();
|
||||
|
||||
// If there is no offset, then this is not a host-shareable struct, returning
|
||||
// 0 indicates this to the caller.
|
||||
if (!last_member->has_offset_decoration()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t size = last_member->type()->MinBufferBindingSize(mem_layout);
|
||||
if (!size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
float unaligned = static_cast<float>(last_member->offset() + size);
|
||||
float alignment = static_cast<float>(BaseAlignment(mem_layout));
|
||||
|
||||
return static_cast<uint64_t>(alignment * std::ceil(unaligned / alignment));
|
||||
}
|
||||
|
||||
uint64_t Struct::BaseAlignment(MemoryLayout mem_layout) const {
|
||||
uint64_t max = 0;
|
||||
for (auto* member : struct_->members()) {
|
||||
if (member->type()->BaseAlignment(mem_layout) > max) {
|
||||
max = member->type()->BaseAlignment(mem_layout);
|
||||
}
|
||||
}
|
||||
|
||||
if (mem_layout == MemoryLayout::kUniformBuffer) {
|
||||
// Round up to a vec4.
|
||||
return static_cast<uint64_t>(16 *
|
||||
std::ceil(static_cast<float>(max) / 16.0f));
|
||||
} else if (mem_layout == MemoryLayout::kStorageBuffer) {
|
||||
return max;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Struct* Struct::Clone(CloneContext* ctx) const {
|
||||
// Clone arguments outside of create() call to have deterministic ordering
|
||||
auto sym = ctx->Clone(symbol());
|
||||
|
||||
@@ -51,16 +51,6 @@ class Struct : public Castable<Struct, Type> {
|
||||
/// declared in WGSL.
|
||||
std::string FriendlyName(const SymbolTable& symbols) const override;
|
||||
|
||||
/// @param mem_layout type of memory layout to use in calculation.
|
||||
/// @returns minimum size required for this type, in bytes.
|
||||
/// 0 for non-host shareable types.
|
||||
uint64_t MinBufferBindingSize(MemoryLayout mem_layout) const override;
|
||||
|
||||
/// @param mem_layout type of memory layout to use in calculation.
|
||||
/// @returns base alignment for the type, in bytes.
|
||||
/// 0 for non-host shareable types.
|
||||
uint64_t BaseAlignment(MemoryLayout mem_layout) const override;
|
||||
|
||||
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
|
||||
/// @param ctx the clone context
|
||||
/// @return the newly cloned type
|
||||
|
||||
@@ -64,140 +64,6 @@ TEST_F(StructTypeTest, FriendlyName) {
|
||||
EXPECT_EQ(s->FriendlyName(Symbols()), "my_struct");
|
||||
}
|
||||
|
||||
TEST_F(StructTypeTest, MinBufferBindingSize) {
|
||||
auto* str = create<ast::Struct>(
|
||||
ast::StructMemberList{Member("foo", ty.u32(), {MemberOffset(0)}),
|
||||
Member("bar", ty.u32(), {MemberOffset(4)})},
|
||||
ast::DecorationList{});
|
||||
auto* s_ty = ty.struct_("s_ty", str);
|
||||
|
||||
EXPECT_EQ(16u, s_ty->MinBufferBindingSize(MemoryLayout::kUniformBuffer));
|
||||
EXPECT_EQ(8u, s_ty->MinBufferBindingSize(MemoryLayout::kStorageBuffer));
|
||||
}
|
||||
|
||||
TEST_F(StructTypeTest, MinBufferBindingSizeArray) {
|
||||
Array arr(ty.u32(), 4, ast::DecorationList{create<ast::StrideDecoration>(4)});
|
||||
|
||||
auto* str = create<ast::Struct>(
|
||||
ast::StructMemberList{Member("foo", ty.u32(), {MemberOffset(0)}),
|
||||
Member("bar", ty.u32(), {MemberOffset(4)}),
|
||||
Member("bar", &arr, {MemberOffset(8)})},
|
||||
ast::DecorationList{});
|
||||
auto* s_ty = ty.struct_("s_ty", str);
|
||||
|
||||
EXPECT_EQ(32u, s_ty->MinBufferBindingSize(MemoryLayout::kUniformBuffer));
|
||||
EXPECT_EQ(24u, s_ty->MinBufferBindingSize(MemoryLayout::kStorageBuffer));
|
||||
}
|
||||
|
||||
TEST_F(StructTypeTest, MinBufferBindingSizeRuntimeArray) {
|
||||
Array arr(ty.u32(), 0, ast::DecorationList{create<ast::StrideDecoration>(4)});
|
||||
|
||||
auto* str = create<ast::Struct>(
|
||||
ast::StructMemberList{Member("foo", ty.u32(), {MemberOffset(0)}),
|
||||
Member("bar", ty.u32(), {MemberOffset(4)}),
|
||||
Member("bar", ty.u32(), {MemberOffset(8)})},
|
||||
ast::DecorationList{});
|
||||
auto* s_ty = ty.struct_("s_ty", str);
|
||||
|
||||
EXPECT_EQ(12u, s_ty->MinBufferBindingSize(MemoryLayout::kStorageBuffer));
|
||||
}
|
||||
|
||||
TEST_F(StructTypeTest, MinBufferBindingSizeVec2) {
|
||||
auto* str = create<ast::Struct>(
|
||||
ast::StructMemberList{Member("foo", ty.vec2<u32>(), {MemberOffset(0)})},
|
||||
ast::DecorationList{});
|
||||
auto* s_ty = ty.struct_("s_ty", str);
|
||||
|
||||
EXPECT_EQ(16u, s_ty->MinBufferBindingSize(MemoryLayout::kUniformBuffer));
|
||||
EXPECT_EQ(8u, s_ty->MinBufferBindingSize(MemoryLayout::kStorageBuffer));
|
||||
}
|
||||
|
||||
TEST_F(StructTypeTest, MinBufferBindingSizeVec3) {
|
||||
auto* str = create<ast::Struct>(
|
||||
ast::StructMemberList{Member("foo", ty.vec3<u32>(), {MemberOffset(0)})},
|
||||
ast::DecorationList{});
|
||||
auto* s_ty = ty.struct_("s_ty", str);
|
||||
|
||||
EXPECT_EQ(16u, s_ty->MinBufferBindingSize(MemoryLayout::kUniformBuffer));
|
||||
EXPECT_EQ(16u, s_ty->MinBufferBindingSize(MemoryLayout::kStorageBuffer));
|
||||
}
|
||||
|
||||
TEST_F(StructTypeTest, MinBufferBindingSizeVec4) {
|
||||
auto* str = create<ast::Struct>(
|
||||
ast::StructMemberList{Member("foo", ty.vec4<u32>(), {MemberOffset(0)})},
|
||||
ast::DecorationList{});
|
||||
auto* s_ty = ty.struct_("s_ty", str);
|
||||
|
||||
EXPECT_EQ(16u, s_ty->MinBufferBindingSize(MemoryLayout::kUniformBuffer));
|
||||
EXPECT_EQ(16u, s_ty->MinBufferBindingSize(MemoryLayout::kStorageBuffer));
|
||||
}
|
||||
|
||||
TEST_F(StructTypeTest, BaseAlignment) {
|
||||
auto* str = create<ast::Struct>(
|
||||
ast::StructMemberList{Member("foo", ty.u32(), {MemberOffset(0)}),
|
||||
Member("bar", ty.u32(), {MemberOffset(8)})},
|
||||
ast::DecorationList{});
|
||||
auto* s_ty = ty.struct_("s_ty", str);
|
||||
|
||||
EXPECT_EQ(16u, s_ty->BaseAlignment(MemoryLayout::kUniformBuffer));
|
||||
EXPECT_EQ(4u, s_ty->BaseAlignment(MemoryLayout::kStorageBuffer));
|
||||
}
|
||||
|
||||
TEST_F(StructTypeTest, BaseAlignmentArray) {
|
||||
Array arr(ty.u32(), 4, ast::DecorationList{create<ast::StrideDecoration>(4)});
|
||||
auto* str = create<ast::Struct>(
|
||||
ast::StructMemberList{Member("foo", ty.u32(), {MemberOffset(0)}),
|
||||
Member("bar", ty.u32(), {MemberOffset(4)}),
|
||||
Member("bar", &arr, {MemberOffset(8)})},
|
||||
ast::DecorationList{});
|
||||
auto* s_ty = ty.struct_("s_ty", str);
|
||||
|
||||
EXPECT_EQ(16u, s_ty->BaseAlignment(MemoryLayout::kUniformBuffer));
|
||||
EXPECT_EQ(4u, s_ty->BaseAlignment(MemoryLayout::kStorageBuffer));
|
||||
}
|
||||
|
||||
TEST_F(StructTypeTest, BaseAlignmentRuntimeArray) {
|
||||
Array arr(ty.u32(), 0, ast::DecorationList{create<ast::StrideDecoration>(4)});
|
||||
auto* str = create<ast::Struct>(
|
||||
ast::StructMemberList{Member("foo", ty.u32(), {MemberOffset(0)}),
|
||||
Member("bar", ty.u32(), {MemberOffset(4)}),
|
||||
Member("bar", ty.u32(), {MemberOffset(8)})},
|
||||
ast::DecorationList{});
|
||||
auto* s_ty = ty.struct_("s_ty", str);
|
||||
|
||||
EXPECT_EQ(4u, s_ty->BaseAlignment(MemoryLayout::kStorageBuffer));
|
||||
}
|
||||
|
||||
TEST_F(StructTypeTest, BaseAlignmentVec2) {
|
||||
auto* str = create<ast::Struct>(
|
||||
ast::StructMemberList{Member("foo", ty.vec2<u32>(), {MemberOffset(0)})},
|
||||
ast::DecorationList{});
|
||||
auto* s_ty = ty.struct_("s_ty", str);
|
||||
|
||||
EXPECT_EQ(16u, s_ty->BaseAlignment(MemoryLayout::kUniformBuffer));
|
||||
EXPECT_EQ(8u, s_ty->BaseAlignment(MemoryLayout::kStorageBuffer));
|
||||
}
|
||||
|
||||
TEST_F(StructTypeTest, BaseAlignmentVec3) {
|
||||
auto* str = create<ast::Struct>(
|
||||
ast::StructMemberList{Member("foo", ty.vec3<u32>(), {MemberOffset(0)})},
|
||||
ast::DecorationList{});
|
||||
auto* s_ty = ty.struct_("s_ty", str);
|
||||
|
||||
EXPECT_EQ(16u, s_ty->BaseAlignment(MemoryLayout::kUniformBuffer));
|
||||
EXPECT_EQ(16u, s_ty->BaseAlignment(MemoryLayout::kStorageBuffer));
|
||||
}
|
||||
|
||||
TEST_F(StructTypeTest, BaseAlignmentVec4) {
|
||||
auto* str = create<ast::Struct>(
|
||||
ast::StructMemberList{Member("foo", ty.vec4<u32>(), {MemberOffset(0)})},
|
||||
ast::DecorationList{});
|
||||
auto* s_ty = ty.struct_("s_ty", str);
|
||||
|
||||
EXPECT_EQ(16u, s_ty->BaseAlignment(MemoryLayout::kUniformBuffer));
|
||||
EXPECT_EQ(16u, s_ty->BaseAlignment(MemoryLayout::kStorageBuffer));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace type
|
||||
} // namespace tint
|
||||
|
||||
@@ -70,14 +70,6 @@ Type* Type::UnwrapAll() {
|
||||
return UnwrapIfNeeded()->UnwrapPtrIfNeeded()->UnwrapIfNeeded();
|
||||
}
|
||||
|
||||
uint64_t Type::MinBufferBindingSize(MemoryLayout) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t Type::BaseAlignment(MemoryLayout) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Type::is_scalar() const {
|
||||
return is_float_scalar() || is_integer_scalar() || Is<Bool>();
|
||||
}
|
||||
|
||||
@@ -45,16 +45,6 @@ class Type : public Castable<Type, Cloneable> {
|
||||
/// declared in WGSL.
|
||||
virtual std::string FriendlyName(const SymbolTable& symbols) const = 0;
|
||||
|
||||
/// @param mem_layout type of memory layout to use in calculation.
|
||||
/// @returns minimum size required for this type, in bytes.
|
||||
/// 0 for non-host shareable types.
|
||||
virtual uint64_t MinBufferBindingSize(MemoryLayout mem_layout) const;
|
||||
|
||||
/// @param mem_layout type of memory layout to use in calculation.
|
||||
/// @returns base alignment for the type, in bytes.
|
||||
/// 0 for non-host shareable types.
|
||||
virtual uint64_t BaseAlignment(MemoryLayout mem_layout) const;
|
||||
|
||||
/// @returns the pointee type if this is a pointer, `this` otherwise
|
||||
Type* UnwrapPtrIfNeeded();
|
||||
|
||||
|
||||
@@ -35,14 +35,6 @@ std::string U32::FriendlyName(const SymbolTable&) const {
|
||||
return "u32";
|
||||
}
|
||||
|
||||
uint64_t U32::MinBufferBindingSize(MemoryLayout) const {
|
||||
return 4;
|
||||
}
|
||||
|
||||
uint64_t U32::BaseAlignment(MemoryLayout) const {
|
||||
return 4;
|
||||
}
|
||||
|
||||
U32* U32::Clone(CloneContext* ctx) const {
|
||||
return ctx->dst->create<U32>();
|
||||
}
|
||||
|
||||
@@ -39,16 +39,6 @@ class U32 : public Castable<U32, Type> {
|
||||
/// declared in WGSL.
|
||||
std::string FriendlyName(const SymbolTable& symbols) const override;
|
||||
|
||||
/// @param mem_layout type of memory layout to use in calculation.
|
||||
/// @returns minimum size required for this type, in bytes.
|
||||
/// 0 for non-host shareable types.
|
||||
uint64_t MinBufferBindingSize(MemoryLayout mem_layout) const override;
|
||||
|
||||
/// @param mem_layout type of memory layout to use in calculation.
|
||||
/// @returns base alignment for the type, in bytes.
|
||||
/// 0 for non-host shareable types.
|
||||
uint64_t BaseAlignment(MemoryLayout mem_layout) const override;
|
||||
|
||||
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
|
||||
/// @param ctx the clone context
|
||||
/// @return the newly cloned type
|
||||
|
||||
@@ -50,16 +50,6 @@ TEST_F(U32Test, FriendlyName) {
|
||||
EXPECT_EQ(u.FriendlyName(Symbols()), "u32");
|
||||
}
|
||||
|
||||
TEST_F(U32Test, MinBufferBindingSize) {
|
||||
U32 u;
|
||||
EXPECT_EQ(4u, u.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
|
||||
}
|
||||
|
||||
TEST_F(U32Test, BaseAlignment) {
|
||||
U32 u;
|
||||
EXPECT_EQ(4u, u.BaseAlignment(MemoryLayout::kUniformBuffer));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace type
|
||||
} // namespace tint
|
||||
|
||||
@@ -40,20 +40,6 @@ std::string Vector::FriendlyName(const SymbolTable& symbols) const {
|
||||
return out.str();
|
||||
}
|
||||
|
||||
uint64_t Vector::MinBufferBindingSize(MemoryLayout mem_layout) const {
|
||||
return size_ * subtype_->MinBufferBindingSize(mem_layout);
|
||||
}
|
||||
|
||||
uint64_t Vector::BaseAlignment(MemoryLayout mem_layout) const {
|
||||
if (size_ == 2) {
|
||||
return 2 * subtype_->BaseAlignment(mem_layout);
|
||||
} else if (size_ == 3 || size_ == 4) {
|
||||
return 4 * subtype_->BaseAlignment(mem_layout);
|
||||
}
|
||||
|
||||
return 0; // vectors are only supposed to have 2, 3, or 4 elements.
|
||||
}
|
||||
|
||||
Vector* Vector::Clone(CloneContext* ctx) const {
|
||||
// Clone arguments outside of create() call to have deterministic ordering
|
||||
auto* ty = ctx->Clone(type());
|
||||
|
||||
@@ -46,16 +46,6 @@ class Vector : public Castable<Vector, Type> {
|
||||
/// declared in WGSL.
|
||||
std::string FriendlyName(const SymbolTable& symbols) const override;
|
||||
|
||||
/// @param mem_layout type of memory layout to use in calculation.
|
||||
/// @returns minimum size required for this type, in bytes.
|
||||
/// 0 for non-host shareable types.
|
||||
uint64_t MinBufferBindingSize(MemoryLayout mem_layout) const override;
|
||||
|
||||
/// @param mem_layout type of memory layout to use in calculation.
|
||||
/// @returns base alignment for the type, in bytes.
|
||||
/// 0 for non-host shareable types.
|
||||
uint64_t BaseAlignment(MemoryLayout mem_layout) const override;
|
||||
|
||||
/// Clones this type and all transitive types using the `CloneContext` `ctx`.
|
||||
/// @param ctx the clone context
|
||||
/// @return the newly cloned type
|
||||
|
||||
@@ -59,42 +59,6 @@ TEST_F(VectorTest, FriendlyName) {
|
||||
EXPECT_EQ(v->FriendlyName(Symbols()), "vec3<f32>");
|
||||
}
|
||||
|
||||
TEST_F(VectorTest, MinBufferBindingSizeVec2) {
|
||||
I32 i32;
|
||||
Vector v{&i32, 2};
|
||||
EXPECT_EQ(8u, v.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
|
||||
}
|
||||
|
||||
TEST_F(VectorTest, MinBufferBindingSizeVec3) {
|
||||
I32 i32;
|
||||
Vector v{&i32, 3};
|
||||
EXPECT_EQ(12u, v.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
|
||||
}
|
||||
|
||||
TEST_F(VectorTest, MinBufferBindingSizeVec4) {
|
||||
I32 i32;
|
||||
Vector v{&i32, 4};
|
||||
EXPECT_EQ(16u, v.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
|
||||
}
|
||||
|
||||
TEST_F(VectorTest, BaseAlignmentVec2) {
|
||||
I32 i32;
|
||||
Vector v{&i32, 2};
|
||||
EXPECT_EQ(8u, v.BaseAlignment(MemoryLayout::kUniformBuffer));
|
||||
}
|
||||
|
||||
TEST_F(VectorTest, BaseAlignmentVec3) {
|
||||
I32 i32;
|
||||
Vector v{&i32, 3};
|
||||
EXPECT_EQ(16u, v.BaseAlignment(MemoryLayout::kUniformBuffer));
|
||||
}
|
||||
|
||||
TEST_F(VectorTest, BaseAlignmentVec4) {
|
||||
I32 i32;
|
||||
Vector v{&i32, 4};
|
||||
EXPECT_EQ(16u, v.BaseAlignment(MemoryLayout::kUniformBuffer));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace type
|
||||
} // namespace tint
|
||||
|
||||
Reference in New Issue
Block a user