[spirv-writer] Allow emitting an array stride.
This CL adds the ability to attach a stride to an array type and have it emitted during SPIR-V generation. Bug: tint:5 Change-Id: I9c0f0a6afef6ae6662b64f4da2c150ba3f8da29f Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/23223 Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
parent
7be237aa8f
commit
6941c5354c
|
@ -37,6 +37,8 @@ std::string ArrayType::type_name() const {
|
|||
std::string type_name = "__array" + subtype_->type_name();
|
||||
if (!IsRuntimeArray())
|
||||
type_name += "_" + std::to_string(size_);
|
||||
if (has_array_stride())
|
||||
type_name += "_" + std::to_string(array_stride_);
|
||||
|
||||
return type_name;
|
||||
}
|
||||
|
|
|
@ -45,6 +45,14 @@ class ArrayType : public Type {
|
|||
/// i.e. the size is determined at runtime
|
||||
bool IsRuntimeArray() const { return size_ == 0; }
|
||||
|
||||
/// Sets the array stride
|
||||
/// @param stride the stride to set
|
||||
void set_array_stride(uint32_t stride) { array_stride_ = stride; }
|
||||
/// @returns the array stride or 0 if none set.
|
||||
uint32_t array_stride() const { return array_stride_; }
|
||||
/// @returns true if the array has a stride set
|
||||
bool has_array_stride() const { return array_stride_ != 0; }
|
||||
|
||||
/// @returns the array type
|
||||
Type* type() const { return subtype_; }
|
||||
/// @returns the array size. Size is 0 for a runtime array
|
||||
|
@ -56,6 +64,7 @@ class ArrayType : public Type {
|
|||
private:
|
||||
Type* subtype_ = nullptr;
|
||||
uint32_t size_ = 0;
|
||||
uint32_t array_stride_ = 0;
|
||||
};
|
||||
|
||||
} // namespace type
|
||||
|
|
|
@ -60,11 +60,24 @@ TEST_F(ArrayTypeTest, Is) {
|
|||
}
|
||||
|
||||
TEST_F(ArrayTypeTest, TypeName) {
|
||||
I32Type i32;
|
||||
ArrayType arr{&i32};
|
||||
EXPECT_EQ(arr.type_name(), "__array__i32");
|
||||
}
|
||||
|
||||
TEST_F(ArrayTypeTest, TypeName_RuntimeArray) {
|
||||
I32Type i32;
|
||||
ArrayType arr{&i32, 3};
|
||||
EXPECT_EQ(arr.type_name(), "__array__i32_3");
|
||||
}
|
||||
|
||||
TEST_F(ArrayTypeTest, TypeName_WithStride) {
|
||||
I32Type i32;
|
||||
ArrayType arr{&i32, 3};
|
||||
arr.set_array_stride(16);
|
||||
EXPECT_EQ(arr.type_name(), "__array__i32_3_16");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace type
|
||||
} // namespace ast
|
||||
|
|
|
@ -41,6 +41,11 @@ class StructType : public Type {
|
|||
/// @returns the struct name
|
||||
const std::string& name() const { return name_; }
|
||||
|
||||
/// @returns true if the struct has a block decoration
|
||||
bool IsBlockDecorated() const {
|
||||
return struct_->decoration() == StructDecoration::kBlock;
|
||||
}
|
||||
|
||||
/// @returns true if the type is a struct type
|
||||
bool IsStruct() const override;
|
||||
|
||||
|
|
|
@ -1681,6 +1681,7 @@ bool Builder::GenerateArrayType(ast::type::ArrayType* ary,
|
|||
return false;
|
||||
}
|
||||
|
||||
auto result_id = result.to_i();
|
||||
if (ary->IsRuntimeArray()) {
|
||||
push_type(spv::Op::OpTypeRuntimeArray, {result, Operand::Int(elem_type)});
|
||||
} else {
|
||||
|
@ -1692,6 +1693,17 @@ bool Builder::GenerateArrayType(ast::type::ArrayType* ary,
|
|||
push_type(spv::Op::OpTypeArray,
|
||||
{result, Operand::Int(elem_type), Operand::Int(len_id)});
|
||||
}
|
||||
|
||||
// SPIR-V explicitly requires no array stride if the array contains a struct
|
||||
// which has a Block decoration.
|
||||
if (ary->type()->IsStruct() && ary->type()->AsStruct()->IsBlockDecorated()) {
|
||||
return true;
|
||||
}
|
||||
if (ary->has_array_stride()) {
|
||||
push_annot(spv::Op::OpDecorate,
|
||||
{Operand::Int(result_id), Operand::Int(SpvDecorationArrayStride),
|
||||
Operand::Int(ary->array_stride())});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -118,6 +118,27 @@ TEST_F(BuilderTest_Type, GenerateArray) {
|
|||
)");
|
||||
}
|
||||
|
||||
TEST_F(BuilderTest_Type, GenerateArray_WithStride) {
|
||||
ast::type::I32Type i32;
|
||||
ast::type::ArrayType ary(&i32, 4);
|
||||
ary.set_array_stride(16u);
|
||||
|
||||
ast::Module mod;
|
||||
Builder b(&mod);
|
||||
auto id = b.GenerateTypeIfNeeded(&ary);
|
||||
ASSERT_FALSE(b.has_error()) << b.error();
|
||||
EXPECT_EQ(1u, id);
|
||||
|
||||
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %1 ArrayStride 16
|
||||
)");
|
||||
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
|
||||
%3 = OpTypeInt 32 0
|
||||
%4 = OpConstant %3 4
|
||||
%1 = OpTypeArray %2 %4
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(BuilderTest_Type, ReturnsGeneratedArray) {
|
||||
ast::type::I32Type i32;
|
||||
ast::type::ArrayType ary(&i32, 4);
|
||||
|
|
Loading…
Reference in New Issue