[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();
|
std::string type_name = "__array" + subtype_->type_name();
|
||||||
if (!IsRuntimeArray())
|
if (!IsRuntimeArray())
|
||||||
type_name += "_" + std::to_string(size_);
|
type_name += "_" + std::to_string(size_);
|
||||||
|
if (has_array_stride())
|
||||||
|
type_name += "_" + std::to_string(array_stride_);
|
||||||
|
|
||||||
return type_name;
|
return type_name;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,14 @@ class ArrayType : public Type {
|
||||||
/// i.e. the size is determined at runtime
|
/// i.e. the size is determined at runtime
|
||||||
bool IsRuntimeArray() const { return size_ == 0; }
|
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
|
/// @returns the array type
|
||||||
Type* type() const { return subtype_; }
|
Type* type() const { return subtype_; }
|
||||||
/// @returns the array size. Size is 0 for a runtime array
|
/// @returns the array size. Size is 0 for a runtime array
|
||||||
|
@ -56,6 +64,7 @@ class ArrayType : public Type {
|
||||||
private:
|
private:
|
||||||
Type* subtype_ = nullptr;
|
Type* subtype_ = nullptr;
|
||||||
uint32_t size_ = 0;
|
uint32_t size_ = 0;
|
||||||
|
uint32_t array_stride_ = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace type
|
} // namespace type
|
||||||
|
|
|
@ -60,11 +60,24 @@ TEST_F(ArrayTypeTest, Is) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ArrayTypeTest, TypeName) {
|
TEST_F(ArrayTypeTest, TypeName) {
|
||||||
|
I32Type i32;
|
||||||
|
ArrayType arr{&i32};
|
||||||
|
EXPECT_EQ(arr.type_name(), "__array__i32");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ArrayTypeTest, TypeName_RuntimeArray) {
|
||||||
I32Type i32;
|
I32Type i32;
|
||||||
ArrayType arr{&i32, 3};
|
ArrayType arr{&i32, 3};
|
||||||
EXPECT_EQ(arr.type_name(), "__array__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
|
||||||
} // namespace type
|
} // namespace type
|
||||||
} // namespace ast
|
} // namespace ast
|
||||||
|
|
|
@ -41,6 +41,11 @@ class StructType : public Type {
|
||||||
/// @returns the struct name
|
/// @returns the struct name
|
||||||
const std::string& name() const { return 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
|
/// @returns true if the type is a struct type
|
||||||
bool IsStruct() const override;
|
bool IsStruct() const override;
|
||||||
|
|
||||||
|
|
|
@ -1681,6 +1681,7 @@ bool Builder::GenerateArrayType(ast::type::ArrayType* ary,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto result_id = result.to_i();
|
||||||
if (ary->IsRuntimeArray()) {
|
if (ary->IsRuntimeArray()) {
|
||||||
push_type(spv::Op::OpTypeRuntimeArray, {result, Operand::Int(elem_type)});
|
push_type(spv::Op::OpTypeRuntimeArray, {result, Operand::Int(elem_type)});
|
||||||
} else {
|
} else {
|
||||||
|
@ -1692,6 +1693,17 @@ bool Builder::GenerateArrayType(ast::type::ArrayType* ary,
|
||||||
push_type(spv::Op::OpTypeArray,
|
push_type(spv::Op::OpTypeArray,
|
||||||
{result, Operand::Int(elem_type), Operand::Int(len_id)});
|
{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;
|
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) {
|
TEST_F(BuilderTest_Type, ReturnsGeneratedArray) {
|
||||||
ast::type::I32Type i32;
|
ast::type::I32Type i32;
|
||||||
ast::type::ArrayType ary(&i32, 4);
|
ast::type::ArrayType ary(&i32, 4);
|
||||||
|
|
Loading…
Reference in New Issue