writer/msl: Wrap each array type in a struct
This allows them to be used in various places that WGSL allows, such as function return types and parameters, and as the type of the RHS of an assignment. Fixed: tint:814 Fixed: tint:820 Change-Id: Idb6a901b9a34e96bb9733cc158191e7b3bafaa0e Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/52844 Auto-Submit: James Price <jrprice@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: James Price <jrprice@google.com> Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
parent
5c0820c76b
commit
94ac078990
|
@ -94,7 +94,18 @@ bool GeneratorImpl::Generate() {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!program_->AST().ConstructedTypes().empty()) {
|
||||
|
||||
// Generate wrappers for array types.
|
||||
for (auto* ty : program_->Types()) {
|
||||
auto* arr = ty->As<sem::Array>();
|
||||
if (arr && !arr->IsRuntimeSized()) {
|
||||
if (!EmitArrayWrapper(arr)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!program_->AST().ConstructedTypes().empty() || array_wrappers_.size()) {
|
||||
out_ << std::endl;
|
||||
}
|
||||
|
||||
|
@ -179,6 +190,14 @@ bool GeneratorImpl::EmitArrayAccessor(ast::ArrayAccessorExpression* expr) {
|
|||
if (paren_lhs) {
|
||||
out_ << ")";
|
||||
}
|
||||
|
||||
// If the array has been wrapped in a struct, emit a member accessor to get to
|
||||
// the actual array.
|
||||
auto* sem_ty = program_->Sem().Get(expr->array())->Type()->UnwrapRef();
|
||||
if (array_wrappers_.count(sem_ty)) {
|
||||
out_ << ".array";
|
||||
}
|
||||
|
||||
out_ << "[";
|
||||
|
||||
if (!EmitExpression(expr->idx_expr())) {
|
||||
|
@ -1892,6 +1911,16 @@ bool GeneratorImpl::EmitSwitch(ast::SwitchStatement* stmt) {
|
|||
|
||||
bool GeneratorImpl::EmitType(const sem::Type* type, const std::string& name) {
|
||||
if (auto* ary = type->As<sem::Array>()) {
|
||||
if (array_wrappers_.count(type)) {
|
||||
// If the array has been wrapped in a struct, emit the struct name instead
|
||||
// of the array type.
|
||||
out_ << array_wrappers_[type];
|
||||
if (!name.empty()) {
|
||||
out_ << " " << name;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const sem::Type* base_type = ary;
|
||||
std::vector<uint32_t> sizes;
|
||||
while (auto* arr = base_type->As<sem::Array>()) {
|
||||
|
@ -1940,7 +1969,8 @@ bool GeneratorImpl::EmitType(const sem::Type* type, const std::string& name) {
|
|||
default:
|
||||
TINT_ICE(diagnostics_) << "unhandled storage class for pointer";
|
||||
}
|
||||
if (ptr->StoreType()->Is<sem::Array>()) {
|
||||
if (ptr->StoreType()->Is<sem::Array>() &&
|
||||
!array_wrappers_.count(ptr->StoreType())) {
|
||||
std::string inner = "(*" + name + ")";
|
||||
if (!EmitType(ptr->StoreType(), inner)) {
|
||||
return false;
|
||||
|
@ -2055,6 +2085,16 @@ bool GeneratorImpl::EmitPackedType(const sem::Type* type,
|
|||
}
|
||||
|
||||
bool GeneratorImpl::EmitStructType(const sem::Struct* str) {
|
||||
// Generate wrappers for any struct members that have an array type.
|
||||
for (auto* mem : str->Members()) {
|
||||
auto* arr = mem->Type()->As<sem::Array>();
|
||||
if (arr && !arr->IsRuntimeSized()) {
|
||||
if (!EmitArrayWrapper(arr)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(dsinclair): Block decoration?
|
||||
// if (str->impl()->decoration() != ast::Decoration::kNone) {
|
||||
// }
|
||||
|
@ -2376,6 +2416,36 @@ GeneratorImpl::SizeAndAlign GeneratorImpl::MslPackedTypeSizeAndAlign(
|
|||
return {};
|
||||
}
|
||||
|
||||
bool GeneratorImpl::EmitArrayWrapper(const sem::Array* arr) {
|
||||
// We may have created a wrapper for this array while emitting structs.
|
||||
if (array_wrappers_.count(arr)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Find a unique name for the new structure.
|
||||
uint32_t i = static_cast<uint32_t>(array_wrappers_.size());
|
||||
std::string struct_name;
|
||||
do {
|
||||
struct_name = "tint_array_wrapper_" + std::to_string(i++);
|
||||
if (i == 0) {
|
||||
TINT_ICE(diagnostics_) << "unable to allocate name for array wrapper";
|
||||
}
|
||||
} while (program_->Symbols().Get(struct_name).IsValid());
|
||||
|
||||
// Generate a struct with a single member with the same type as the array.
|
||||
out_ << "struct " << struct_name << " {" << std::endl;
|
||||
out_ << " ";
|
||||
if (!EmitType(arr->ElemType(), "")) {
|
||||
return false;
|
||||
}
|
||||
out_ << " array[" << arr->Count() << "];" << std::endl;
|
||||
out_ << "};" << std::endl;
|
||||
|
||||
array_wrappers_.emplace(arr, struct_name);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace msl
|
||||
} // namespace writer
|
||||
} // namespace tint
|
||||
|
|
|
@ -42,6 +42,7 @@ namespace tint {
|
|||
|
||||
// Forward declarations
|
||||
namespace sem {
|
||||
class Array;
|
||||
class Call;
|
||||
class Intrinsic;
|
||||
} // namespace sem
|
||||
|
@ -289,12 +290,18 @@ class GeneratorImpl : public TextGenerator {
|
|||
/// type.
|
||||
SizeAndAlign MslPackedTypeSizeAndAlign(const sem::Type* ty);
|
||||
|
||||
/// Generate a struct wrapper for an array type.
|
||||
bool EmitArrayWrapper(const sem::Array* arr);
|
||||
|
||||
ScopeStack<const sem::Variable*> global_variables_;
|
||||
Symbol current_ep_sym_;
|
||||
bool generating_entry_point_ = false;
|
||||
const Program* program_ = nullptr;
|
||||
uint32_t loop_emission_counter_ = 0;
|
||||
|
||||
// Map from an array type to the name of a struct which wraps it.
|
||||
std::unordered_map<const sem::Type*, std::string> array_wrappers_;
|
||||
|
||||
std::unordered_map<Symbol, EntryPointData> ep_sym_to_in_data_;
|
||||
std::unordered_map<Symbol, EntryPointData> ep_sym_to_out_data_;
|
||||
|
||||
|
|
|
@ -776,7 +776,11 @@ TEST_F(MslGeneratorImplTest, Emit_Function_WithArrayParams) {
|
|||
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
void my_func(float const a[5]) {
|
||||
struct tint_array_wrapper_0 {
|
||||
float array[5];
|
||||
};
|
||||
|
||||
void my_func(tint_array_wrapper_0 const a) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -453,10 +453,10 @@ TEST_F(MslGeneratorImplTest, EmitType_Struct_Layout_ArrayDefaultStride) {
|
|||
// for each field of the structure s.
|
||||
#define ALL_FIELDS() \
|
||||
FIELD(0x0000, int, a, /*NO SUFFIX*/) \
|
||||
FIELD(0x0004, float, b, [7]) \
|
||||
FIELD(0x0004, tint_array_wrapper_0, b, /*NO SUFFIX*/) \
|
||||
FIELD(0x0020, float, c, /*NO SUFFIX*/) \
|
||||
FIELD(0x0024, int8_t, tint_pad_0, [476]) \
|
||||
FIELD(0x0200, inner, d, [4]) \
|
||||
FIELD(0x0200, tint_array_wrapper_1, d, /*NO SUFFIX*/) \
|
||||
FIELD(0x1200, float, e, /*NO SUFFIX*/) \
|
||||
FIELD(0x1204, float, f, [1]) \
|
||||
FIELD(0x1208, int8_t, tint_pad_1, [504])
|
||||
|
@ -464,7 +464,14 @@ TEST_F(MslGeneratorImplTest, EmitType_Struct_Layout_ArrayDefaultStride) {
|
|||
// Check that the generated string is as expected.
|
||||
#define FIELD(ADDR, TYPE, NAME, SUFFIX) \
|
||||
" /* " #ADDR " */ " #TYPE " " #NAME #SUFFIX ";\n"
|
||||
auto* expect = "struct S {\n" ALL_FIELDS() "};\n";
|
||||
auto* expect =
|
||||
"struct tint_array_wrapper_0 {\n"
|
||||
" float array[7];\n"
|
||||
"};\n"
|
||||
"struct tint_array_wrapper_1 {\n"
|
||||
" inner array[4];\n"
|
||||
"};\n"
|
||||
"struct S {\n" ALL_FIELDS() "};\n";
|
||||
#undef FIELD
|
||||
EXPECT_EQ(gen.result(), expect);
|
||||
|
||||
|
@ -484,12 +491,12 @@ TEST_F(MslGeneratorImplTest, EmitType_Struct_Layout_ArrayDefaultStride) {
|
|||
CHECK_TYPE_SIZE_AND_ALIGN(inner, 1024, 512);
|
||||
|
||||
// array_x: size(28), align(4)
|
||||
using array_x = std::array<float, 7>;
|
||||
CHECK_TYPE_SIZE_AND_ALIGN(array_x, 28, 4);
|
||||
using tint_array_wrapper_0 = std::array<float, 7>;
|
||||
CHECK_TYPE_SIZE_AND_ALIGN(tint_array_wrapper_0, 28, 4);
|
||||
|
||||
// array_y: size(4096), align(512)
|
||||
using array_y = std::array<inner, 4>;
|
||||
CHECK_TYPE_SIZE_AND_ALIGN(array_y, 4096, 512);
|
||||
using tint_array_wrapper_1 = std::array<inner, 4>;
|
||||
CHECK_TYPE_SIZE_AND_ALIGN(tint_array_wrapper_1, 4096, 512);
|
||||
|
||||
// array_z: size(4), align(4)
|
||||
using array_z = std::array<float, 1>;
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
type ArrayType = [[stride(16)]] array<i32, 4>;
|
||||
|
||||
[[block]]
|
||||
struct S {
|
||||
arr : ArrayType;
|
||||
};
|
||||
|
||||
var<private> src_private : ArrayType;
|
||||
var<workgroup> src_workgroup : ArrayType;
|
||||
[[group(0), binding(0)]] var<uniform> src_uniform : S;
|
||||
[[group(0), binding(1)]] var<storage> src_storage : [[access(read_write)]] S;
|
||||
|
||||
fn ret_arr() -> ArrayType {
|
||||
return ArrayType();
|
||||
}
|
||||
|
||||
fn ret_struct_arr() -> S {
|
||||
return S();
|
||||
}
|
||||
|
||||
fn foo(src_param : ArrayType) {
|
||||
var src_function : ArrayType;
|
||||
|
||||
var dst : ArrayType;
|
||||
|
||||
// Assign from type constructor.
|
||||
dst = ArrayType(1, 2, 3, 3);
|
||||
|
||||
// Assign from parameter.
|
||||
dst = src_param;
|
||||
|
||||
// Assign from function call.
|
||||
dst = ret_arr();
|
||||
|
||||
// Assign from constant.
|
||||
let src_let : ArrayType = ArrayType();
|
||||
dst = src_let;
|
||||
|
||||
// Assign from var, various storage classes.
|
||||
dst = src_function;
|
||||
dst = src_private;
|
||||
dst = src_workgroup;
|
||||
|
||||
// Assign from struct.arr, various storage classes.
|
||||
dst = ret_struct_arr().arr;
|
||||
dst = src_uniform.arr;
|
||||
dst = src_storage.arr;
|
||||
|
||||
// Nested assignment.
|
||||
var dst_nested : array<array<array<i32, 2>, 3>, 4>;
|
||||
var src_nested : array<array<array<i32, 2>, 3>, 4>;
|
||||
dst_nested = src_nested;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
SKIP: crbug.com/tint/845
|
|
@ -0,0 +1 @@
|
|||
SKIP: crbug.com/tint/649
|
|
@ -0,0 +1,112 @@
|
|||
; SPIR-V
|
||||
; Version: 1.3
|
||||
; Generator: Google Tint Compiler; 0
|
||||
; Bound: 60
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
|
||||
OpExecutionMode %unused_entry_point LocalSize 1 1 1
|
||||
OpName %src_private "src_private"
|
||||
OpName %src_workgroup "src_workgroup"
|
||||
OpName %S "S"
|
||||
OpMemberName %S 0 "arr"
|
||||
OpName %src_uniform "src_uniform"
|
||||
OpName %src_storage "src_storage"
|
||||
OpName %unused_entry_point "unused_entry_point"
|
||||
OpName %ret_arr "ret_arr"
|
||||
OpName %ret_struct_arr "ret_struct_arr"
|
||||
OpName %foo "foo"
|
||||
OpName %src_param "src_param"
|
||||
OpName %src_function "src_function"
|
||||
OpName %dst "dst"
|
||||
OpName %dst_nested "dst_nested"
|
||||
OpName %src_nested "src_nested"
|
||||
OpDecorate %_arr_int_uint_4 ArrayStride 16
|
||||
OpDecorate %S Block
|
||||
OpMemberDecorate %S 0 Offset 0
|
||||
OpDecorate %src_uniform DescriptorSet 0
|
||||
OpDecorate %src_uniform Binding 0
|
||||
OpDecorate %src_storage DescriptorSet 0
|
||||
OpDecorate %src_storage Binding 1
|
||||
OpDecorate %_arr_int_uint_2 ArrayStride 4
|
||||
OpDecorate %_arr__arr_int_uint_2_uint_3 ArrayStride 8
|
||||
OpDecorate %_arr__arr__arr_int_uint_2_uint_3_uint_4 ArrayStride 24
|
||||
%int = OpTypeInt 32 1
|
||||
%uint = OpTypeInt 32 0
|
||||
%uint_4 = OpConstant %uint 4
|
||||
%_arr_int_uint_4 = OpTypeArray %int %uint_4
|
||||
%_ptr_Private__arr_int_uint_4 = OpTypePointer Private %_arr_int_uint_4
|
||||
%7 = OpConstantNull %_arr_int_uint_4
|
||||
%src_private = OpVariable %_ptr_Private__arr_int_uint_4 Private %7
|
||||
%_ptr_Workgroup__arr_int_uint_4 = OpTypePointer Workgroup %_arr_int_uint_4
|
||||
%src_workgroup = OpVariable %_ptr_Workgroup__arr_int_uint_4 Workgroup
|
||||
%S = OpTypeStruct %_arr_int_uint_4
|
||||
%_ptr_Uniform_S = OpTypePointer Uniform %S
|
||||
%src_uniform = OpVariable %_ptr_Uniform_S Uniform
|
||||
%_ptr_StorageBuffer_S = OpTypePointer StorageBuffer %S
|
||||
%src_storage = OpVariable %_ptr_StorageBuffer_S StorageBuffer
|
||||
%void = OpTypeVoid
|
||||
%15 = OpTypeFunction %void
|
||||
%19 = OpTypeFunction %_arr_int_uint_4
|
||||
%22 = OpTypeFunction %S
|
||||
%25 = OpConstantNull %S
|
||||
%26 = OpTypeFunction %void %_arr_int_uint_4
|
||||
%_ptr_Function__arr_int_uint_4 = OpTypePointer Function %_arr_int_uint_4
|
||||
%int_1 = OpConstant %int 1
|
||||
%int_2 = OpConstant %int 2
|
||||
%int_3 = OpConstant %int 3
|
||||
%36 = OpConstantComposite %_arr_int_uint_4 %int_1 %int_2 %int_3 %int_3
|
||||
%uint_0 = OpConstant %uint 0
|
||||
%_ptr_Uniform__arr_int_uint_4 = OpTypePointer Uniform %_arr_int_uint_4
|
||||
%_ptr_StorageBuffer__arr_int_uint_4 = OpTypePointer StorageBuffer %_arr_int_uint_4
|
||||
%uint_2 = OpConstant %uint 2
|
||||
%_arr_int_uint_2 = OpTypeArray %int %uint_2
|
||||
%uint_3 = OpConstant %uint 3
|
||||
%_arr__arr_int_uint_2_uint_3 = OpTypeArray %_arr_int_uint_2 %uint_3
|
||||
%_arr__arr__arr_int_uint_2_uint_3_uint_4 = OpTypeArray %_arr__arr_int_uint_2_uint_3 %uint_4
|
||||
%_ptr_Function__arr__arr__arr_int_uint_2_uint_3_uint_4 = OpTypePointer Function %_arr__arr__arr_int_uint_2_uint_3_uint_4
|
||||
%57 = OpConstantNull %_arr__arr__arr_int_uint_2_uint_3_uint_4
|
||||
%unused_entry_point = OpFunction %void None %15
|
||||
%18 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%ret_arr = OpFunction %_arr_int_uint_4 None %19
|
||||
%21 = OpLabel
|
||||
OpReturnValue %7
|
||||
OpFunctionEnd
|
||||
%ret_struct_arr = OpFunction %S None %22
|
||||
%24 = OpLabel
|
||||
OpReturnValue %25
|
||||
OpFunctionEnd
|
||||
%foo = OpFunction %void None %26
|
||||
%src_param = OpFunctionParameter %_arr_int_uint_4
|
||||
%29 = OpLabel
|
||||
%src_function = OpVariable %_ptr_Function__arr_int_uint_4 Function %7
|
||||
%dst = OpVariable %_ptr_Function__arr_int_uint_4 Function %7
|
||||
%dst_nested = OpVariable %_ptr_Function__arr__arr__arr_int_uint_2_uint_3_uint_4 Function %57
|
||||
%src_nested = OpVariable %_ptr_Function__arr__arr__arr_int_uint_2_uint_3_uint_4 Function %57
|
||||
OpStore %dst %36
|
||||
OpStore %dst %src_param
|
||||
%37 = OpFunctionCall %_arr_int_uint_4 %ret_arr
|
||||
OpStore %dst %37
|
||||
OpStore %dst %7
|
||||
%38 = OpLoad %_arr_int_uint_4 %src_function
|
||||
OpStore %dst %38
|
||||
%39 = OpLoad %_arr_int_uint_4 %src_private
|
||||
OpStore %dst %39
|
||||
%40 = OpLoad %_arr_int_uint_4 %src_workgroup
|
||||
OpStore %dst %40
|
||||
%41 = OpFunctionCall %S %ret_struct_arr
|
||||
%42 = OpCompositeExtract %_arr_int_uint_4 %41 0
|
||||
OpStore %dst %42
|
||||
%45 = OpAccessChain %_ptr_Uniform__arr_int_uint_4 %src_uniform %uint_0
|
||||
%46 = OpLoad %_arr_int_uint_4 %45
|
||||
OpStore %dst %46
|
||||
%48 = OpAccessChain %_ptr_StorageBuffer__arr_int_uint_4 %src_storage %uint_0
|
||||
%49 = OpLoad %_arr_int_uint_4 %48
|
||||
OpStore %dst %49
|
||||
%59 = OpLoad %_arr__arr__arr_int_uint_2_uint_3_uint_4 %src_nested
|
||||
OpStore %dst_nested %59
|
||||
OpReturn
|
||||
OpFunctionEnd
|
|
@ -0,0 +1,41 @@
|
|||
type ArrayType = [[stride(16)]] array<i32, 4>;
|
||||
|
||||
[[block]]
|
||||
struct S {
|
||||
arr : ArrayType;
|
||||
};
|
||||
|
||||
var<private> src_private : ArrayType;
|
||||
|
||||
var<workgroup> src_workgroup : ArrayType;
|
||||
|
||||
[[group(0), binding(0)]] var<uniform> src_uniform : S;
|
||||
|
||||
[[group(0), binding(1)]] var<storage> src_storage : [[access(read_write)]] S;
|
||||
|
||||
fn ret_arr() -> ArrayType {
|
||||
return ArrayType();
|
||||
}
|
||||
|
||||
fn ret_struct_arr() -> S {
|
||||
return S();
|
||||
}
|
||||
|
||||
fn foo(src_param : ArrayType) {
|
||||
var src_function : ArrayType;
|
||||
var dst : ArrayType;
|
||||
dst = ArrayType(1, 2, 3, 3);
|
||||
dst = src_param;
|
||||
dst = ret_arr();
|
||||
let src_let : ArrayType = ArrayType();
|
||||
dst = src_let;
|
||||
dst = src_function;
|
||||
dst = src_private;
|
||||
dst = src_workgroup;
|
||||
dst = ret_struct_arr().arr;
|
||||
dst = src_uniform.arr;
|
||||
dst = src_storage.arr;
|
||||
var dst_nested : array<array<array<i32, 2>, 3>, 4>;
|
||||
var src_nested : array<array<array<i32, 2>, 3>, 4>;
|
||||
dst_nested = src_nested;
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
type ArrayType = [[stride(16)]] array<i32, 4>;
|
||||
|
||||
[[block]]
|
||||
struct S {
|
||||
arr : ArrayType;
|
||||
};
|
||||
|
||||
var<private> src_private : ArrayType;
|
||||
var<workgroup> src_workgroup : ArrayType;
|
||||
[[group(0), binding(0)]] var<uniform> src_uniform : S;
|
||||
[[group(0), binding(1)]] var<storage> src_storage : [[access(read_write)]] S;
|
||||
|
||||
var<private> dst : ArrayType;
|
||||
var<private> dst_nested : array<array<array<i32, 2>, 3>, 4>;
|
||||
|
||||
fn ret_arr() -> ArrayType {
|
||||
return ArrayType();
|
||||
}
|
||||
|
||||
fn ret_struct_arr() -> S {
|
||||
return S();
|
||||
}
|
||||
|
||||
fn foo(src_param : ArrayType) {
|
||||
var src_function : ArrayType;
|
||||
|
||||
// Assign from type constructor.
|
||||
dst = ArrayType(1, 2, 3, 3);
|
||||
|
||||
// Assign from parameter.
|
||||
dst = src_param;
|
||||
|
||||
// Assign from function call.
|
||||
dst = ret_arr();
|
||||
|
||||
// Assign from constant.
|
||||
let src_let : ArrayType = ArrayType();
|
||||
dst = src_let;
|
||||
|
||||
// Assign from var, various storage classes.
|
||||
dst = src_function;
|
||||
dst = src_private;
|
||||
dst = src_workgroup;
|
||||
|
||||
// Assign from struct.arr, various storage classes.
|
||||
dst = ret_struct_arr().arr;
|
||||
dst = src_uniform.arr;
|
||||
dst = src_storage.arr;
|
||||
|
||||
// Nested assignment.
|
||||
var src_nested : array<array<array<i32, 2>, 3>, 4>;
|
||||
dst_nested = src_nested;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
SKIP: crbug.com/tint/845
|
|
@ -0,0 +1 @@
|
|||
SKIP: crbug.com/tint/649
|
|
@ -0,0 +1,113 @@
|
|||
; SPIR-V
|
||||
; Version: 1.3
|
||||
; Generator: Google Tint Compiler; 0
|
||||
; Bound: 61
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
|
||||
OpExecutionMode %unused_entry_point LocalSize 1 1 1
|
||||
OpName %src_private "src_private"
|
||||
OpName %src_workgroup "src_workgroup"
|
||||
OpName %S "S"
|
||||
OpMemberName %S 0 "arr"
|
||||
OpName %src_uniform "src_uniform"
|
||||
OpName %src_storage "src_storage"
|
||||
OpName %dst "dst"
|
||||
OpName %dst_nested "dst_nested"
|
||||
OpName %unused_entry_point "unused_entry_point"
|
||||
OpName %ret_arr "ret_arr"
|
||||
OpName %ret_struct_arr "ret_struct_arr"
|
||||
OpName %foo "foo"
|
||||
OpName %src_param "src_param"
|
||||
OpName %src_function "src_function"
|
||||
OpName %src_nested "src_nested"
|
||||
OpDecorate %_arr_int_uint_4 ArrayStride 16
|
||||
OpDecorate %S Block
|
||||
OpMemberDecorate %S 0 Offset 0
|
||||
OpDecorate %src_uniform DescriptorSet 0
|
||||
OpDecorate %src_uniform Binding 0
|
||||
OpDecorate %src_storage DescriptorSet 0
|
||||
OpDecorate %src_storage Binding 1
|
||||
OpDecorate %_arr_int_uint_2 ArrayStride 4
|
||||
OpDecorate %_arr__arr_int_uint_2_uint_3 ArrayStride 8
|
||||
OpDecorate %_arr__arr__arr_int_uint_2_uint_3_uint_4 ArrayStride 24
|
||||
%int = OpTypeInt 32 1
|
||||
%uint = OpTypeInt 32 0
|
||||
%uint_4 = OpConstant %uint 4
|
||||
%_arr_int_uint_4 = OpTypeArray %int %uint_4
|
||||
%_ptr_Private__arr_int_uint_4 = OpTypePointer Private %_arr_int_uint_4
|
||||
%7 = OpConstantNull %_arr_int_uint_4
|
||||
%src_private = OpVariable %_ptr_Private__arr_int_uint_4 Private %7
|
||||
%_ptr_Workgroup__arr_int_uint_4 = OpTypePointer Workgroup %_arr_int_uint_4
|
||||
%src_workgroup = OpVariable %_ptr_Workgroup__arr_int_uint_4 Workgroup
|
||||
%S = OpTypeStruct %_arr_int_uint_4
|
||||
%_ptr_Uniform_S = OpTypePointer Uniform %S
|
||||
%src_uniform = OpVariable %_ptr_Uniform_S Uniform
|
||||
%_ptr_StorageBuffer_S = OpTypePointer StorageBuffer %S
|
||||
%src_storage = OpVariable %_ptr_StorageBuffer_S StorageBuffer
|
||||
%dst = OpVariable %_ptr_Private__arr_int_uint_4 Private %7
|
||||
%uint_2 = OpConstant %uint 2
|
||||
%_arr_int_uint_2 = OpTypeArray %int %uint_2
|
||||
%uint_3 = OpConstant %uint 3
|
||||
%_arr__arr_int_uint_2_uint_3 = OpTypeArray %_arr_int_uint_2 %uint_3
|
||||
%_arr__arr__arr_int_uint_2_uint_3_uint_4 = OpTypeArray %_arr__arr_int_uint_2_uint_3 %uint_4
|
||||
%_ptr_Private__arr__arr__arr_int_uint_2_uint_3_uint_4 = OpTypePointer Private %_arr__arr__arr_int_uint_2_uint_3_uint_4
|
||||
%23 = OpConstantNull %_arr__arr__arr_int_uint_2_uint_3_uint_4
|
||||
%dst_nested = OpVariable %_ptr_Private__arr__arr__arr_int_uint_2_uint_3_uint_4 Private %23
|
||||
%void = OpTypeVoid
|
||||
%24 = OpTypeFunction %void
|
||||
%28 = OpTypeFunction %_arr_int_uint_4
|
||||
%31 = OpTypeFunction %S
|
||||
%34 = OpConstantNull %S
|
||||
%35 = OpTypeFunction %void %_arr_int_uint_4
|
||||
%_ptr_Function__arr_int_uint_4 = OpTypePointer Function %_arr_int_uint_4
|
||||
%int_1 = OpConstant %int 1
|
||||
%int_2 = OpConstant %int 2
|
||||
%int_3 = OpConstant %int 3
|
||||
%44 = OpConstantComposite %_arr_int_uint_4 %int_1 %int_2 %int_3 %int_3
|
||||
%uint_0 = OpConstant %uint 0
|
||||
%_ptr_Uniform__arr_int_uint_4 = OpTypePointer Uniform %_arr_int_uint_4
|
||||
%_ptr_StorageBuffer__arr_int_uint_4 = OpTypePointer StorageBuffer %_arr_int_uint_4
|
||||
%_ptr_Function__arr__arr__arr_int_uint_2_uint_3_uint_4 = OpTypePointer Function %_arr__arr__arr_int_uint_2_uint_3_uint_4
|
||||
%unused_entry_point = OpFunction %void None %24
|
||||
%27 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%ret_arr = OpFunction %_arr_int_uint_4 None %28
|
||||
%30 = OpLabel
|
||||
OpReturnValue %7
|
||||
OpFunctionEnd
|
||||
%ret_struct_arr = OpFunction %S None %31
|
||||
%33 = OpLabel
|
||||
OpReturnValue %34
|
||||
OpFunctionEnd
|
||||
%foo = OpFunction %void None %35
|
||||
%src_param = OpFunctionParameter %_arr_int_uint_4
|
||||
%38 = OpLabel
|
||||
%src_function = OpVariable %_ptr_Function__arr_int_uint_4 Function %7
|
||||
%src_nested = OpVariable %_ptr_Function__arr__arr__arr_int_uint_2_uint_3_uint_4 Function %23
|
||||
OpStore %dst %44
|
||||
OpStore %dst %src_param
|
||||
%45 = OpFunctionCall %_arr_int_uint_4 %ret_arr
|
||||
OpStore %dst %45
|
||||
OpStore %dst %7
|
||||
%46 = OpLoad %_arr_int_uint_4 %src_function
|
||||
OpStore %dst %46
|
||||
%47 = OpLoad %_arr_int_uint_4 %src_private
|
||||
OpStore %dst %47
|
||||
%48 = OpLoad %_arr_int_uint_4 %src_workgroup
|
||||
OpStore %dst %48
|
||||
%49 = OpFunctionCall %S %ret_struct_arr
|
||||
%50 = OpCompositeExtract %_arr_int_uint_4 %49 0
|
||||
OpStore %dst %50
|
||||
%53 = OpAccessChain %_ptr_Uniform__arr_int_uint_4 %src_uniform %uint_0
|
||||
%54 = OpLoad %_arr_int_uint_4 %53
|
||||
OpStore %dst %54
|
||||
%56 = OpAccessChain %_ptr_StorageBuffer__arr_int_uint_4 %src_storage %uint_0
|
||||
%57 = OpLoad %_arr_int_uint_4 %56
|
||||
OpStore %dst %57
|
||||
%60 = OpLoad %_arr__arr__arr_int_uint_2_uint_3_uint_4 %src_nested
|
||||
OpStore %dst_nested %60
|
||||
OpReturn
|
||||
OpFunctionEnd
|
|
@ -0,0 +1,43 @@
|
|||
type ArrayType = [[stride(16)]] array<i32, 4>;
|
||||
|
||||
[[block]]
|
||||
struct S {
|
||||
arr : ArrayType;
|
||||
};
|
||||
|
||||
var<private> src_private : ArrayType;
|
||||
|
||||
var<workgroup> src_workgroup : ArrayType;
|
||||
|
||||
[[group(0), binding(0)]] var<uniform> src_uniform : S;
|
||||
|
||||
[[group(0), binding(1)]] var<storage> src_storage : [[access(read_write)]] S;
|
||||
|
||||
var<private> dst : ArrayType;
|
||||
|
||||
var<private> dst_nested : array<array<array<i32, 2>, 3>, 4>;
|
||||
|
||||
fn ret_arr() -> ArrayType {
|
||||
return ArrayType();
|
||||
}
|
||||
|
||||
fn ret_struct_arr() -> S {
|
||||
return S();
|
||||
}
|
||||
|
||||
fn foo(src_param : ArrayType) {
|
||||
var src_function : ArrayType;
|
||||
dst = ArrayType(1, 2, 3, 3);
|
||||
dst = src_param;
|
||||
dst = ret_arr();
|
||||
let src_let : ArrayType = ArrayType();
|
||||
dst = src_let;
|
||||
dst = src_function;
|
||||
dst = src_private;
|
||||
dst = src_workgroup;
|
||||
dst = ret_struct_arr().arr;
|
||||
dst = src_uniform.arr;
|
||||
dst = src_storage.arr;
|
||||
var src_nested : array<array<array<i32, 2>, 3>, 4>;
|
||||
dst_nested = src_nested;
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
type ArrayType = [[stride(16)]] array<i32, 4>;
|
||||
|
||||
[[block]]
|
||||
struct S {
|
||||
arr : ArrayType;
|
||||
};
|
||||
|
||||
[[block]]
|
||||
struct S_nested {
|
||||
arr : array<array<array<i32, 2>, 3>, 4>;
|
||||
};
|
||||
|
||||
var<private> src_private : ArrayType;
|
||||
var<workgroup> src_workgroup : ArrayType;
|
||||
[[group(0), binding(0)]] var<uniform> src_uniform : S;
|
||||
[[group(0), binding(1)]] var<storage> src_storage : [[access(read_write)]] S;
|
||||
|
||||
[[group(0), binding(2)]] var<storage> dst : [[access(read_write)]] S;
|
||||
[[group(0), binding(3)]] var<storage> dst_nested : [[access(read_write)]] S_nested;
|
||||
|
||||
fn ret_arr() -> ArrayType {
|
||||
return ArrayType();
|
||||
}
|
||||
|
||||
fn ret_struct_arr() -> S {
|
||||
return S();
|
||||
}
|
||||
|
||||
fn foo(src_param : ArrayType) {
|
||||
var src_function : ArrayType;
|
||||
|
||||
// Assign from type constructor.
|
||||
dst.arr = ArrayType(1, 2, 3, 3);
|
||||
|
||||
// Assign from parameter.
|
||||
dst.arr = src_param;
|
||||
|
||||
// Assign from function call.
|
||||
dst.arr = ret_arr();
|
||||
|
||||
// Assign from constant.
|
||||
let src_let : ArrayType = ArrayType();
|
||||
dst.arr = src_let;
|
||||
|
||||
// Assign from var, various storage classes.
|
||||
dst.arr = src_function;
|
||||
dst.arr = src_private;
|
||||
dst.arr = src_workgroup;
|
||||
|
||||
// Assign from struct.arr, various storage classes.
|
||||
dst.arr = ret_struct_arr().arr;
|
||||
dst.arr = src_uniform.arr;
|
||||
dst.arr = src_storage.arr;
|
||||
|
||||
// Nested assignment.
|
||||
var src_nested : array<array<array<i32, 2>, 3>, 4>;
|
||||
dst_nested.arr = src_nested;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
SKIP: crbug.com/tint/845
|
|
@ -0,0 +1 @@
|
|||
SKIP: crbug.com/tint/649
|
|
@ -0,0 +1,134 @@
|
|||
; SPIR-V
|
||||
; Version: 1.3
|
||||
; Generator: Google Tint Compiler; 0
|
||||
; Bound: 74
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
|
||||
OpExecutionMode %unused_entry_point LocalSize 1 1 1
|
||||
OpName %src_private "src_private"
|
||||
OpName %src_workgroup "src_workgroup"
|
||||
OpName %S "S"
|
||||
OpMemberName %S 0 "arr"
|
||||
OpName %src_uniform "src_uniform"
|
||||
OpName %src_storage "src_storage"
|
||||
OpName %dst "dst"
|
||||
OpName %S_nested "S_nested"
|
||||
OpMemberName %S_nested 0 "arr"
|
||||
OpName %dst_nested "dst_nested"
|
||||
OpName %unused_entry_point "unused_entry_point"
|
||||
OpName %ret_arr "ret_arr"
|
||||
OpName %ret_struct_arr "ret_struct_arr"
|
||||
OpName %foo "foo"
|
||||
OpName %src_param "src_param"
|
||||
OpName %src_function "src_function"
|
||||
OpName %src_nested "src_nested"
|
||||
OpDecorate %_arr_int_uint_4 ArrayStride 16
|
||||
OpDecorate %S Block
|
||||
OpMemberDecorate %S 0 Offset 0
|
||||
OpDecorate %src_uniform DescriptorSet 0
|
||||
OpDecorate %src_uniform Binding 0
|
||||
OpDecorate %src_storage DescriptorSet 0
|
||||
OpDecorate %src_storage Binding 1
|
||||
OpDecorate %dst DescriptorSet 0
|
||||
OpDecorate %dst Binding 2
|
||||
OpDecorate %S_nested Block
|
||||
OpMemberDecorate %S_nested 0 Offset 0
|
||||
OpDecorate %_arr_int_uint_2 ArrayStride 4
|
||||
OpDecorate %_arr__arr_int_uint_2_uint_3 ArrayStride 8
|
||||
OpDecorate %_arr__arr__arr_int_uint_2_uint_3_uint_4 ArrayStride 24
|
||||
OpDecorate %dst_nested DescriptorSet 0
|
||||
OpDecorate %dst_nested Binding 3
|
||||
%int = OpTypeInt 32 1
|
||||
%uint = OpTypeInt 32 0
|
||||
%uint_4 = OpConstant %uint 4
|
||||
%_arr_int_uint_4 = OpTypeArray %int %uint_4
|
||||
%_ptr_Private__arr_int_uint_4 = OpTypePointer Private %_arr_int_uint_4
|
||||
%7 = OpConstantNull %_arr_int_uint_4
|
||||
%src_private = OpVariable %_ptr_Private__arr_int_uint_4 Private %7
|
||||
%_ptr_Workgroup__arr_int_uint_4 = OpTypePointer Workgroup %_arr_int_uint_4
|
||||
%src_workgroup = OpVariable %_ptr_Workgroup__arr_int_uint_4 Workgroup
|
||||
%S = OpTypeStruct %_arr_int_uint_4
|
||||
%_ptr_Uniform_S = OpTypePointer Uniform %S
|
||||
%src_uniform = OpVariable %_ptr_Uniform_S Uniform
|
||||
%_ptr_StorageBuffer_S = OpTypePointer StorageBuffer %S
|
||||
%src_storage = OpVariable %_ptr_StorageBuffer_S StorageBuffer
|
||||
%dst = OpVariable %_ptr_StorageBuffer_S StorageBuffer
|
||||
%uint_2 = OpConstant %uint 2
|
||||
%_arr_int_uint_2 = OpTypeArray %int %uint_2
|
||||
%uint_3 = OpConstant %uint 3
|
||||
%_arr__arr_int_uint_2_uint_3 = OpTypeArray %_arr_int_uint_2 %uint_3
|
||||
%_arr__arr__arr_int_uint_2_uint_3_uint_4 = OpTypeArray %_arr__arr_int_uint_2_uint_3 %uint_4
|
||||
%S_nested = OpTypeStruct %_arr__arr__arr_int_uint_2_uint_3_uint_4
|
||||
%_ptr_StorageBuffer_S_nested = OpTypePointer StorageBuffer %S_nested
|
||||
%dst_nested = OpVariable %_ptr_StorageBuffer_S_nested StorageBuffer
|
||||
%void = OpTypeVoid
|
||||
%24 = OpTypeFunction %void
|
||||
%28 = OpTypeFunction %_arr_int_uint_4
|
||||
%31 = OpTypeFunction %S
|
||||
%34 = OpConstantNull %S
|
||||
%35 = OpTypeFunction %void %_arr_int_uint_4
|
||||
%_ptr_Function__arr_int_uint_4 = OpTypePointer Function %_arr_int_uint_4
|
||||
%uint_0 = OpConstant %uint 0
|
||||
%_ptr_StorageBuffer__arr_int_uint_4 = OpTypePointer StorageBuffer %_arr_int_uint_4
|
||||
%int_1 = OpConstant %int 1
|
||||
%int_2 = OpConstant %int 2
|
||||
%int_3 = OpConstant %int 3
|
||||
%47 = OpConstantComposite %_arr_int_uint_4 %int_1 %int_2 %int_3 %int_3
|
||||
%_ptr_Uniform__arr_int_uint_4 = OpTypePointer Uniform %_arr_int_uint_4
|
||||
%_ptr_Function__arr__arr__arr_int_uint_2_uint_3_uint_4 = OpTypePointer Function %_arr__arr__arr_int_uint_2_uint_3_uint_4
|
||||
%70 = OpConstantNull %_arr__arr__arr_int_uint_2_uint_3_uint_4
|
||||
%_ptr_StorageBuffer__arr__arr__arr_int_uint_2_uint_3_uint_4 = OpTypePointer StorageBuffer %_arr__arr__arr_int_uint_2_uint_3_uint_4
|
||||
%unused_entry_point = OpFunction %void None %24
|
||||
%27 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%ret_arr = OpFunction %_arr_int_uint_4 None %28
|
||||
%30 = OpLabel
|
||||
OpReturnValue %7
|
||||
OpFunctionEnd
|
||||
%ret_struct_arr = OpFunction %S None %31
|
||||
%33 = OpLabel
|
||||
OpReturnValue %34
|
||||
OpFunctionEnd
|
||||
%foo = OpFunction %void None %35
|
||||
%src_param = OpFunctionParameter %_arr_int_uint_4
|
||||
%38 = OpLabel
|
||||
%src_function = OpVariable %_ptr_Function__arr_int_uint_4 Function %7
|
||||
%src_nested = OpVariable %_ptr_Function__arr__arr__arr_int_uint_2_uint_3_uint_4 Function %70
|
||||
%43 = OpAccessChain %_ptr_StorageBuffer__arr_int_uint_4 %dst %uint_0
|
||||
OpStore %43 %47
|
||||
%48 = OpAccessChain %_ptr_StorageBuffer__arr_int_uint_4 %dst %uint_0
|
||||
OpStore %48 %src_param
|
||||
%49 = OpAccessChain %_ptr_StorageBuffer__arr_int_uint_4 %dst %uint_0
|
||||
%50 = OpFunctionCall %_arr_int_uint_4 %ret_arr
|
||||
OpStore %49 %50
|
||||
%51 = OpAccessChain %_ptr_StorageBuffer__arr_int_uint_4 %dst %uint_0
|
||||
OpStore %51 %7
|
||||
%52 = OpAccessChain %_ptr_StorageBuffer__arr_int_uint_4 %dst %uint_0
|
||||
%53 = OpLoad %_arr_int_uint_4 %src_function
|
||||
OpStore %52 %53
|
||||
%54 = OpAccessChain %_ptr_StorageBuffer__arr_int_uint_4 %dst %uint_0
|
||||
%55 = OpLoad %_arr_int_uint_4 %src_private
|
||||
OpStore %54 %55
|
||||
%56 = OpAccessChain %_ptr_StorageBuffer__arr_int_uint_4 %dst %uint_0
|
||||
%57 = OpLoad %_arr_int_uint_4 %src_workgroup
|
||||
OpStore %56 %57
|
||||
%58 = OpAccessChain %_ptr_StorageBuffer__arr_int_uint_4 %dst %uint_0
|
||||
%59 = OpFunctionCall %S %ret_struct_arr
|
||||
%60 = OpCompositeExtract %_arr_int_uint_4 %59 0
|
||||
OpStore %58 %60
|
||||
%61 = OpAccessChain %_ptr_StorageBuffer__arr_int_uint_4 %dst %uint_0
|
||||
%63 = OpAccessChain %_ptr_Uniform__arr_int_uint_4 %src_uniform %uint_0
|
||||
%64 = OpLoad %_arr_int_uint_4 %63
|
||||
OpStore %61 %64
|
||||
%65 = OpAccessChain %_ptr_StorageBuffer__arr_int_uint_4 %dst %uint_0
|
||||
%66 = OpAccessChain %_ptr_StorageBuffer__arr_int_uint_4 %src_storage %uint_0
|
||||
%67 = OpLoad %_arr_int_uint_4 %66
|
||||
OpStore %65 %67
|
||||
%72 = OpAccessChain %_ptr_StorageBuffer__arr__arr__arr_int_uint_2_uint_3_uint_4 %dst_nested %uint_0
|
||||
%73 = OpLoad %_arr__arr__arr_int_uint_2_uint_3_uint_4 %src_nested
|
||||
OpStore %72 %73
|
||||
OpReturn
|
||||
OpFunctionEnd
|
|
@ -0,0 +1,48 @@
|
|||
type ArrayType = [[stride(16)]] array<i32, 4>;
|
||||
|
||||
[[block]]
|
||||
struct S {
|
||||
arr : ArrayType;
|
||||
};
|
||||
|
||||
[[block]]
|
||||
struct S_nested {
|
||||
arr : array<array<array<i32, 2>, 3>, 4>;
|
||||
};
|
||||
|
||||
var<private> src_private : ArrayType;
|
||||
|
||||
var<workgroup> src_workgroup : ArrayType;
|
||||
|
||||
[[group(0), binding(0)]] var<uniform> src_uniform : S;
|
||||
|
||||
[[group(0), binding(1)]] var<storage> src_storage : [[access(read_write)]] S;
|
||||
|
||||
[[group(0), binding(2)]] var<storage> dst : [[access(read_write)]] S;
|
||||
|
||||
[[group(0), binding(3)]] var<storage> dst_nested : [[access(read_write)]] S_nested;
|
||||
|
||||
fn ret_arr() -> ArrayType {
|
||||
return ArrayType();
|
||||
}
|
||||
|
||||
fn ret_struct_arr() -> S {
|
||||
return S();
|
||||
}
|
||||
|
||||
fn foo(src_param : ArrayType) {
|
||||
var src_function : ArrayType;
|
||||
dst.arr = ArrayType(1, 2, 3, 3);
|
||||
dst.arr = src_param;
|
||||
dst.arr = ret_arr();
|
||||
let src_let : ArrayType = ArrayType();
|
||||
dst.arr = src_let;
|
||||
dst.arr = src_function;
|
||||
dst.arr = src_private;
|
||||
dst.arr = src_workgroup;
|
||||
dst.arr = ret_struct_arr().arr;
|
||||
dst.arr = src_uniform.arr;
|
||||
dst.arr = src_storage.arr;
|
||||
var src_nested : array<array<array<i32, 2>, 3>, 4>;
|
||||
dst_nested.arr = src_nested;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
type ArrayType = array<i32, 4>;
|
||||
|
||||
struct S {
|
||||
arr : array<i32, 4>;
|
||||
};
|
||||
|
||||
fn foo() {
|
||||
let src : ArrayType = ArrayType();
|
||||
|
||||
var dst : ArrayType;
|
||||
var dst_struct : S;
|
||||
var dst_array : array<ArrayType, 2>;
|
||||
let dst_ptr : ptr<function, ArrayType> = &dst;
|
||||
let dst_struct_ptr : ptr<function, S> = &dst_struct;
|
||||
let dst_array_ptr : ptr<function, array<ArrayType, 2>> = &dst_array;
|
||||
|
||||
// Assign to struct.member.
|
||||
dst_struct.arr = src;
|
||||
|
||||
// Assign to array[index].
|
||||
dst_array[1] = src;
|
||||
|
||||
// Assign via pointers.
|
||||
*dst_ptr = src;
|
||||
(*dst_struct_ptr).arr = src;
|
||||
(*dst_array_ptr)[0] = src;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
struct S {
|
||||
int arr[4];
|
||||
};
|
||||
|
||||
void foo() {
|
||||
const int src[4] = {0, 0, 0, 0};
|
||||
int tint_symbol[4] = {0, 0, 0, 0};
|
||||
S dst_struct = {{0, 0, 0, 0}};
|
||||
int dst_array[2][4] = {{0, 0, 0, 0}, {0, 0, 0, 0}};
|
||||
dst_struct.arr = src;
|
||||
dst_array[1] = src;
|
||||
tint_symbol = src;
|
||||
dst_struct.arr = src;
|
||||
dst_array[0] = src;
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void unused_entry_point() {
|
||||
return;
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
struct tint_array_wrapper_0 {
|
||||
int array[4];
|
||||
};
|
||||
struct S {
|
||||
tint_array_wrapper_0 arr;
|
||||
};
|
||||
struct tint_array_wrapper_1 {
|
||||
tint_array_wrapper_0 array[2];
|
||||
};
|
||||
|
||||
void foo() {
|
||||
tint_array_wrapper_0 const src = {};
|
||||
tint_array_wrapper_0 dst = {0};
|
||||
S dst_struct = {};
|
||||
tint_array_wrapper_1 dst_array = {{0}};
|
||||
thread tint_array_wrapper_0* const dst_ptr = &(dst);
|
||||
thread S* const dst_struct_ptr = &(dst_struct);
|
||||
thread tint_array_wrapper_1* const dst_array_ptr = &(dst_array);
|
||||
dst_struct.arr = src;
|
||||
dst_array.array[1] = src;
|
||||
*(dst_ptr) = src;
|
||||
(*(dst_struct_ptr)).arr = src;
|
||||
(*(dst_array_ptr)).array[0] = src;
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
; SPIR-V
|
||||
; Version: 1.3
|
||||
; Generator: Google Tint Compiler; 0
|
||||
; Bound: 36
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
|
||||
OpExecutionMode %unused_entry_point LocalSize 1 1 1
|
||||
OpName %unused_entry_point "unused_entry_point"
|
||||
OpName %foo "foo"
|
||||
OpName %dst "dst"
|
||||
OpName %S "S"
|
||||
OpMemberName %S 0 "arr"
|
||||
OpName %dst_struct "dst_struct"
|
||||
OpName %dst_array "dst_array"
|
||||
OpDecorate %_arr_int_uint_4 ArrayStride 4
|
||||
OpMemberDecorate %S 0 Offset 0
|
||||
OpDecorate %_arr__arr_int_uint_4_uint_2 ArrayStride 16
|
||||
%void = OpTypeVoid
|
||||
%1 = OpTypeFunction %void
|
||||
%int = OpTypeInt 32 1
|
||||
%uint = OpTypeInt 32 0
|
||||
%uint_4 = OpConstant %uint 4
|
||||
%_arr_int_uint_4 = OpTypeArray %int %uint_4
|
||||
%11 = OpConstantNull %_arr_int_uint_4
|
||||
%_ptr_Function__arr_int_uint_4 = OpTypePointer Function %_arr_int_uint_4
|
||||
%S = OpTypeStruct %_arr_int_uint_4
|
||||
%_ptr_Function_S = OpTypePointer Function %S
|
||||
%17 = OpConstantNull %S
|
||||
%uint_2 = OpConstant %uint 2
|
||||
%_arr__arr_int_uint_4_uint_2 = OpTypeArray %_arr_int_uint_4 %uint_2
|
||||
%_ptr_Function__arr__arr_int_uint_4_uint_2 = OpTypePointer Function %_arr__arr_int_uint_4_uint_2
|
||||
%22 = OpConstantNull %_arr__arr_int_uint_4_uint_2
|
||||
%uint_0 = OpConstant %uint 0
|
||||
%int_1 = OpConstant %int 1
|
||||
%int_0 = OpConstant %int 0
|
||||
%unused_entry_point = OpFunction %void None %1
|
||||
%4 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%foo = OpFunction %void None %1
|
||||
%6 = OpLabel
|
||||
%dst = OpVariable %_ptr_Function__arr_int_uint_4 Function %11
|
||||
%dst_struct = OpVariable %_ptr_Function_S Function %17
|
||||
%dst_array = OpVariable %_ptr_Function__arr__arr_int_uint_4_uint_2 Function %22
|
||||
%27 = OpAccessChain %_ptr_Function__arr_int_uint_4 %dst_struct %uint_0
|
||||
OpStore %27 %11
|
||||
%29 = OpAccessChain %_ptr_Function__arr_int_uint_4 %dst_array %int_1
|
||||
OpStore %29 %11
|
||||
OpStore %dst %11
|
||||
%32 = OpAccessChain %_ptr_Function__arr_int_uint_4 %dst_struct %uint_0
|
||||
OpStore %32 %11
|
||||
%35 = OpAccessChain %_ptr_Function__arr_int_uint_4 %dst_array %int_0
|
||||
OpStore %35 %11
|
||||
OpReturn
|
||||
OpFunctionEnd
|
|
@ -0,0 +1,20 @@
|
|||
type ArrayType = array<i32, 4>;
|
||||
|
||||
struct S {
|
||||
arr : array<i32, 4>;
|
||||
};
|
||||
|
||||
fn foo() {
|
||||
let src : ArrayType = ArrayType();
|
||||
var dst : ArrayType;
|
||||
var dst_struct : S;
|
||||
var dst_array : array<ArrayType, 2>;
|
||||
let dst_ptr : ptr<function, ArrayType> = &(dst);
|
||||
let dst_struct_ptr : ptr<function, S> = &(dst_struct);
|
||||
let dst_array_ptr : ptr<function, array<ArrayType, 2>> = &(dst_array);
|
||||
dst_struct.arr = src;
|
||||
dst_array[1] = src;
|
||||
*(dst_ptr) = src;
|
||||
(*(dst_struct_ptr)).arr = src;
|
||||
(*(dst_array_ptr))[0] = src;
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
type ArrayType = [[stride(16)]] array<i32, 4>;
|
||||
|
||||
[[block]]
|
||||
struct S {
|
||||
arr : ArrayType;
|
||||
};
|
||||
|
||||
var<private> src_private : ArrayType;
|
||||
var<workgroup> src_workgroup : ArrayType;
|
||||
[[group(0), binding(0)]] var<uniform> src_uniform : S;
|
||||
[[group(0), binding(1)]] var<storage> src_storage : [[access(read_write)]] S;
|
||||
|
||||
var<workgroup> dst : ArrayType;
|
||||
var<workgroup> dst_nested : array<array<array<i32, 2>, 3>, 4>;
|
||||
|
||||
fn ret_arr() -> ArrayType {
|
||||
return ArrayType();
|
||||
}
|
||||
|
||||
fn ret_struct_arr() -> S {
|
||||
return S();
|
||||
}
|
||||
|
||||
fn foo(src_param : ArrayType) {
|
||||
var src_function : ArrayType;
|
||||
|
||||
// Assign from type constructor.
|
||||
dst = ArrayType(1, 2, 3, 3);
|
||||
|
||||
// Assign from parameter.
|
||||
dst = src_param;
|
||||
|
||||
// Assign from function call.
|
||||
dst = ret_arr();
|
||||
|
||||
// Assign from constant.
|
||||
let src_let : ArrayType = ArrayType();
|
||||
dst = src_let;
|
||||
|
||||
// Assign from var, various storage classes.
|
||||
dst = src_function;
|
||||
dst = src_private;
|
||||
dst = src_workgroup;
|
||||
|
||||
// Assign from struct.arr, various storage classes.
|
||||
dst = ret_struct_arr().arr;
|
||||
dst = src_uniform.arr;
|
||||
dst = src_storage.arr;
|
||||
|
||||
// Nested assignment.
|
||||
var src_nested : array<array<array<i32, 2>, 3>, 4>;
|
||||
dst_nested = src_nested;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
SKIP: crbug.com/tint/845
|
|
@ -0,0 +1 @@
|
|||
SKIP: crbug.com/tint/649
|
|
@ -0,0 +1,113 @@
|
|||
; SPIR-V
|
||||
; Version: 1.3
|
||||
; Generator: Google Tint Compiler; 0
|
||||
; Bound: 61
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
|
||||
OpExecutionMode %unused_entry_point LocalSize 1 1 1
|
||||
OpName %src_private "src_private"
|
||||
OpName %src_workgroup "src_workgroup"
|
||||
OpName %S "S"
|
||||
OpMemberName %S 0 "arr"
|
||||
OpName %src_uniform "src_uniform"
|
||||
OpName %src_storage "src_storage"
|
||||
OpName %dst "dst"
|
||||
OpName %dst_nested "dst_nested"
|
||||
OpName %unused_entry_point "unused_entry_point"
|
||||
OpName %ret_arr "ret_arr"
|
||||
OpName %ret_struct_arr "ret_struct_arr"
|
||||
OpName %foo "foo"
|
||||
OpName %src_param "src_param"
|
||||
OpName %src_function "src_function"
|
||||
OpName %src_nested "src_nested"
|
||||
OpDecorate %_arr_int_uint_4 ArrayStride 16
|
||||
OpDecorate %S Block
|
||||
OpMemberDecorate %S 0 Offset 0
|
||||
OpDecorate %src_uniform DescriptorSet 0
|
||||
OpDecorate %src_uniform Binding 0
|
||||
OpDecorate %src_storage DescriptorSet 0
|
||||
OpDecorate %src_storage Binding 1
|
||||
OpDecorate %_arr_int_uint_2 ArrayStride 4
|
||||
OpDecorate %_arr__arr_int_uint_2_uint_3 ArrayStride 8
|
||||
OpDecorate %_arr__arr__arr_int_uint_2_uint_3_uint_4 ArrayStride 24
|
||||
%int = OpTypeInt 32 1
|
||||
%uint = OpTypeInt 32 0
|
||||
%uint_4 = OpConstant %uint 4
|
||||
%_arr_int_uint_4 = OpTypeArray %int %uint_4
|
||||
%_ptr_Private__arr_int_uint_4 = OpTypePointer Private %_arr_int_uint_4
|
||||
%7 = OpConstantNull %_arr_int_uint_4
|
||||
%src_private = OpVariable %_ptr_Private__arr_int_uint_4 Private %7
|
||||
%_ptr_Workgroup__arr_int_uint_4 = OpTypePointer Workgroup %_arr_int_uint_4
|
||||
%src_workgroup = OpVariable %_ptr_Workgroup__arr_int_uint_4 Workgroup
|
||||
%S = OpTypeStruct %_arr_int_uint_4
|
||||
%_ptr_Uniform_S = OpTypePointer Uniform %S
|
||||
%src_uniform = OpVariable %_ptr_Uniform_S Uniform
|
||||
%_ptr_StorageBuffer_S = OpTypePointer StorageBuffer %S
|
||||
%src_storage = OpVariable %_ptr_StorageBuffer_S StorageBuffer
|
||||
%dst = OpVariable %_ptr_Workgroup__arr_int_uint_4 Workgroup
|
||||
%uint_2 = OpConstant %uint 2
|
||||
%_arr_int_uint_2 = OpTypeArray %int %uint_2
|
||||
%uint_3 = OpConstant %uint 3
|
||||
%_arr__arr_int_uint_2_uint_3 = OpTypeArray %_arr_int_uint_2 %uint_3
|
||||
%_arr__arr__arr_int_uint_2_uint_3_uint_4 = OpTypeArray %_arr__arr_int_uint_2_uint_3 %uint_4
|
||||
%_ptr_Workgroup__arr__arr__arr_int_uint_2_uint_3_uint_4 = OpTypePointer Workgroup %_arr__arr__arr_int_uint_2_uint_3_uint_4
|
||||
%dst_nested = OpVariable %_ptr_Workgroup__arr__arr__arr_int_uint_2_uint_3_uint_4 Workgroup
|
||||
%void = OpTypeVoid
|
||||
%23 = OpTypeFunction %void
|
||||
%27 = OpTypeFunction %_arr_int_uint_4
|
||||
%30 = OpTypeFunction %S
|
||||
%33 = OpConstantNull %S
|
||||
%34 = OpTypeFunction %void %_arr_int_uint_4
|
||||
%_ptr_Function__arr_int_uint_4 = OpTypePointer Function %_arr_int_uint_4
|
||||
%int_1 = OpConstant %int 1
|
||||
%int_2 = OpConstant %int 2
|
||||
%int_3 = OpConstant %int 3
|
||||
%43 = OpConstantComposite %_arr_int_uint_4 %int_1 %int_2 %int_3 %int_3
|
||||
%uint_0 = OpConstant %uint 0
|
||||
%_ptr_Uniform__arr_int_uint_4 = OpTypePointer Uniform %_arr_int_uint_4
|
||||
%_ptr_StorageBuffer__arr_int_uint_4 = OpTypePointer StorageBuffer %_arr_int_uint_4
|
||||
%_ptr_Function__arr__arr__arr_int_uint_2_uint_3_uint_4 = OpTypePointer Function %_arr__arr__arr_int_uint_2_uint_3_uint_4
|
||||
%59 = OpConstantNull %_arr__arr__arr_int_uint_2_uint_3_uint_4
|
||||
%unused_entry_point = OpFunction %void None %23
|
||||
%26 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%ret_arr = OpFunction %_arr_int_uint_4 None %27
|
||||
%29 = OpLabel
|
||||
OpReturnValue %7
|
||||
OpFunctionEnd
|
||||
%ret_struct_arr = OpFunction %S None %30
|
||||
%32 = OpLabel
|
||||
OpReturnValue %33
|
||||
OpFunctionEnd
|
||||
%foo = OpFunction %void None %34
|
||||
%src_param = OpFunctionParameter %_arr_int_uint_4
|
||||
%37 = OpLabel
|
||||
%src_function = OpVariable %_ptr_Function__arr_int_uint_4 Function %7
|
||||
%src_nested = OpVariable %_ptr_Function__arr__arr__arr_int_uint_2_uint_3_uint_4 Function %59
|
||||
OpStore %dst %43
|
||||
OpStore %dst %src_param
|
||||
%44 = OpFunctionCall %_arr_int_uint_4 %ret_arr
|
||||
OpStore %dst %44
|
||||
OpStore %dst %7
|
||||
%45 = OpLoad %_arr_int_uint_4 %src_function
|
||||
OpStore %dst %45
|
||||
%46 = OpLoad %_arr_int_uint_4 %src_private
|
||||
OpStore %dst %46
|
||||
%47 = OpLoad %_arr_int_uint_4 %src_workgroup
|
||||
OpStore %dst %47
|
||||
%48 = OpFunctionCall %S %ret_struct_arr
|
||||
%49 = OpCompositeExtract %_arr_int_uint_4 %48 0
|
||||
OpStore %dst %49
|
||||
%52 = OpAccessChain %_ptr_Uniform__arr_int_uint_4 %src_uniform %uint_0
|
||||
%53 = OpLoad %_arr_int_uint_4 %52
|
||||
OpStore %dst %53
|
||||
%55 = OpAccessChain %_ptr_StorageBuffer__arr_int_uint_4 %src_storage %uint_0
|
||||
%56 = OpLoad %_arr_int_uint_4 %55
|
||||
OpStore %dst %56
|
||||
%60 = OpLoad %_arr__arr__arr_int_uint_2_uint_3_uint_4 %src_nested
|
||||
OpStore %dst_nested %60
|
||||
OpReturn
|
||||
OpFunctionEnd
|
|
@ -0,0 +1,43 @@
|
|||
type ArrayType = [[stride(16)]] array<i32, 4>;
|
||||
|
||||
[[block]]
|
||||
struct S {
|
||||
arr : ArrayType;
|
||||
};
|
||||
|
||||
var<private> src_private : ArrayType;
|
||||
|
||||
var<workgroup> src_workgroup : ArrayType;
|
||||
|
||||
[[group(0), binding(0)]] var<uniform> src_uniform : S;
|
||||
|
||||
[[group(0), binding(1)]] var<storage> src_storage : [[access(read_write)]] S;
|
||||
|
||||
var<workgroup> dst : ArrayType;
|
||||
|
||||
var<workgroup> dst_nested : array<array<array<i32, 2>, 3>, 4>;
|
||||
|
||||
fn ret_arr() -> ArrayType {
|
||||
return ArrayType();
|
||||
}
|
||||
|
||||
fn ret_struct_arr() -> S {
|
||||
return S();
|
||||
}
|
||||
|
||||
fn foo(src_param : ArrayType) {
|
||||
var src_function : ArrayType;
|
||||
dst = ArrayType(1, 2, 3, 3);
|
||||
dst = src_param;
|
||||
dst = ret_arr();
|
||||
let src_let : ArrayType = ArrayType();
|
||||
dst = src_let;
|
||||
dst = src_function;
|
||||
dst = src_private;
|
||||
dst = src_workgroup;
|
||||
dst = ret_struct_arr().arr;
|
||||
dst = src_uniform.arr;
|
||||
dst = src_storage.arr;
|
||||
var src_nested : array<array<array<i32, 2>, 3>, 4>;
|
||||
dst_nested = src_nested;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
fn f1(a : array<f32, 4>) -> f32 {
|
||||
return a[3];
|
||||
}
|
||||
|
||||
fn f2(a : array<array<f32, 4>, 3>) -> f32 {
|
||||
return a[2][3];
|
||||
}
|
||||
|
||||
fn f3(a : array<array<array<f32, 4>, 3>, 2>) -> f32 {
|
||||
return a[1][2][3];
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn main() {
|
||||
let a1 : array<f32, 4> = array<f32, 4>();
|
||||
let a2 : array<array<f32, 4>, 3> = array<array<f32, 4>, 3>();
|
||||
let a3 : array<array<array<f32, 4>, 3>, 2> = array<array<array<f32, 4>, 3>, 2>();
|
||||
let v1 : f32 = f1(a1);
|
||||
let v2 : f32 = f2(a2);
|
||||
let v3 : f32 = f3(a3);
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
float f1(float a[4]) {
|
||||
return a[3];
|
||||
}
|
||||
|
||||
float f2(float a[3][4]) {
|
||||
return a[2][3];
|
||||
}
|
||||
|
||||
float f3(float a[2][3][4]) {
|
||||
return a[1][2][3];
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void main() {
|
||||
const float a1[4] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
const float a2[3][4] = {{0.0f, 0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f}};
|
||||
const float a3[2][3][4] = {{{0.0f, 0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f}}, {{0.0f, 0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f}}};
|
||||
const float v1 = f1(a1);
|
||||
const float v2 = f2(a2);
|
||||
const float v3 = f3(a3);
|
||||
return;
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
struct tint_array_wrapper_0 {
|
||||
float array[4];
|
||||
};
|
||||
struct tint_array_wrapper_1 {
|
||||
tint_array_wrapper_0 array[3];
|
||||
};
|
||||
struct tint_array_wrapper_2 {
|
||||
tint_array_wrapper_1 array[2];
|
||||
};
|
||||
|
||||
float f1(tint_array_wrapper_0 const a) {
|
||||
return a.array[3];
|
||||
}
|
||||
|
||||
float f2(tint_array_wrapper_1 const a) {
|
||||
return a.array[2].array[3];
|
||||
}
|
||||
|
||||
float f3(tint_array_wrapper_2 const a) {
|
||||
return a.array[1].array[2].array[3];
|
||||
}
|
||||
|
||||
kernel void tint_symbol() {
|
||||
tint_array_wrapper_0 const a1 = {};
|
||||
tint_array_wrapper_1 const a2 = {};
|
||||
tint_array_wrapper_2 const a3 = {};
|
||||
float const v1 = f1(a1);
|
||||
float const v2 = f2(a2);
|
||||
float const v3 = f3(a3);
|
||||
return;
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
; SPIR-V
|
||||
; Version: 1.3
|
||||
; Generator: Google Tint Compiler; 0
|
||||
; Bound: 41
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %main "main"
|
||||
OpExecutionMode %main LocalSize 1 1 1
|
||||
OpName %f1 "f1"
|
||||
OpName %a "a"
|
||||
OpName %f2 "f2"
|
||||
OpName %a_0 "a"
|
||||
OpName %f3 "f3"
|
||||
OpName %a_1 "a"
|
||||
OpName %main "main"
|
||||
OpDecorate %_arr_float_uint_4 ArrayStride 4
|
||||
OpDecorate %_arr__arr_float_uint_4_uint_3 ArrayStride 16
|
||||
OpDecorate %_arr__arr__arr_float_uint_4_uint_3_uint_2 ArrayStride 48
|
||||
%float = OpTypeFloat 32
|
||||
%uint = OpTypeInt 32 0
|
||||
%uint_4 = OpConstant %uint 4
|
||||
%_arr_float_uint_4 = OpTypeArray %float %uint_4
|
||||
%1 = OpTypeFunction %float %_arr_float_uint_4
|
||||
%int = OpTypeInt 32 1
|
||||
%int_3 = OpConstant %int 3
|
||||
%uint_3 = OpConstant %uint 3
|
||||
%_arr__arr_float_uint_4_uint_3 = OpTypeArray %_arr_float_uint_4 %uint_3
|
||||
%12 = OpTypeFunction %float %_arr__arr_float_uint_4_uint_3
|
||||
%int_2 = OpConstant %int 2
|
||||
%uint_2 = OpConstant %uint 2
|
||||
%_arr__arr__arr_float_uint_4_uint_3_uint_2 = OpTypeArray %_arr__arr_float_uint_4_uint_3 %uint_2
|
||||
%21 = OpTypeFunction %float %_arr__arr__arr_float_uint_4_uint_3_uint_2
|
||||
%int_1 = OpConstant %int 1
|
||||
%void = OpTypeVoid
|
||||
%31 = OpTypeFunction %void
|
||||
%35 = OpConstantNull %_arr_float_uint_4
|
||||
%36 = OpConstantNull %_arr__arr_float_uint_4_uint_3
|
||||
%37 = OpConstantNull %_arr__arr__arr_float_uint_4_uint_3_uint_2
|
||||
%f1 = OpFunction %float None %1
|
||||
%a = OpFunctionParameter %_arr_float_uint_4
|
||||
%8 = OpLabel
|
||||
%11 = OpCompositeExtract %float %a 3
|
||||
OpReturnValue %11
|
||||
OpFunctionEnd
|
||||
%f2 = OpFunction %float None %12
|
||||
%a_0 = OpFunctionParameter %_arr__arr_float_uint_4_uint_3
|
||||
%17 = OpLabel
|
||||
%19 = OpCompositeExtract %_arr_float_uint_4 %a_0 2
|
||||
%20 = OpCompositeExtract %float %19 3
|
||||
OpReturnValue %20
|
||||
OpFunctionEnd
|
||||
%f3 = OpFunction %float None %21
|
||||
%a_1 = OpFunctionParameter %_arr__arr__arr_float_uint_4_uint_3_uint_2
|
||||
%26 = OpLabel
|
||||
%28 = OpCompositeExtract %_arr__arr_float_uint_4_uint_3 %a_1 1
|
||||
%29 = OpCompositeExtract %_arr_float_uint_4 %28 2
|
||||
%30 = OpCompositeExtract %float %29 3
|
||||
OpReturnValue %30
|
||||
OpFunctionEnd
|
||||
%main = OpFunction %void None %31
|
||||
%34 = OpLabel
|
||||
%38 = OpFunctionCall %float %f1 %35
|
||||
%39 = OpFunctionCall %float %f2 %36
|
||||
%40 = OpFunctionCall %float %f3 %37
|
||||
OpReturn
|
||||
OpFunctionEnd
|
|
@ -0,0 +1,21 @@
|
|||
fn f1(a : array<f32, 4>) -> f32 {
|
||||
return a[3];
|
||||
}
|
||||
|
||||
fn f2(a : array<array<f32, 4>, 3>) -> f32 {
|
||||
return a[2][3];
|
||||
}
|
||||
|
||||
fn f3(a : array<array<array<f32, 4>, 3>, 2>) -> f32 {
|
||||
return a[1][2][3];
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn main() {
|
||||
let a1 : array<f32, 4> = array<f32, 4>();
|
||||
let a2 : array<array<f32, 4>, 3> = array<array<f32, 4>, 3>();
|
||||
let a3 : array<array<array<f32, 4>, 3>, 2> = array<array<array<f32, 4>, 3>, 2>();
|
||||
let v1 : f32 = f1(a1);
|
||||
let v2 : f32 = f2(a2);
|
||||
let v3 : f32 = f3(a3);
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
fn f1() -> array<f32, 4> {
|
||||
return array<f32, 4>();
|
||||
}
|
||||
|
||||
fn f2() -> array<array<f32, 4>, 3> {
|
||||
return array<array<f32, 4>, 3>(f1(), f1(), f1());
|
||||
}
|
||||
|
||||
fn f3() -> array<array<array<f32, 4>, 3>, 2> {
|
||||
return array<array<array<f32, 4>, 3>, 2>(f2(), f2());
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn main() {
|
||||
let a1 : array<f32, 4> = f1();
|
||||
let a2 : array<array<f32, 4>, 3> = f2();
|
||||
let a3 : array<array<array<f32, 4>, 3>, 2> = f3();
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
SKIP: crbug.com/tint/845
|
|
@ -0,0 +1,35 @@
|
|||
#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
struct tint_array_wrapper_0 {
|
||||
float array[4];
|
||||
};
|
||||
struct tint_array_wrapper_1 {
|
||||
tint_array_wrapper_0 array[3];
|
||||
};
|
||||
struct tint_array_wrapper_2 {
|
||||
tint_array_wrapper_1 array[2];
|
||||
};
|
||||
|
||||
tint_array_wrapper_0 f1() {
|
||||
tint_array_wrapper_0 const tint_symbol_1 = {};
|
||||
return tint_symbol_1;
|
||||
}
|
||||
|
||||
tint_array_wrapper_1 f2() {
|
||||
tint_array_wrapper_1 const tint_symbol_2 = {f1(), f1(), f1()};
|
||||
return tint_symbol_2;
|
||||
}
|
||||
|
||||
tint_array_wrapper_2 f3() {
|
||||
tint_array_wrapper_2 const tint_symbol_3 = {f2(), f2()};
|
||||
return tint_symbol_3;
|
||||
}
|
||||
|
||||
kernel void tint_symbol() {
|
||||
tint_array_wrapper_0 const a1 = f1();
|
||||
tint_array_wrapper_1 const a2 = f2();
|
||||
tint_array_wrapper_2 const a3 = f3();
|
||||
return;
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
; SPIR-V
|
||||
; Version: 1.3
|
||||
; Generator: Google Tint Compiler; 0
|
||||
; Bound: 33
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %main "main"
|
||||
OpExecutionMode %main LocalSize 1 1 1
|
||||
OpName %f1 "f1"
|
||||
OpName %f2 "f2"
|
||||
OpName %f3 "f3"
|
||||
OpName %main "main"
|
||||
OpDecorate %_arr_float_uint_4 ArrayStride 4
|
||||
OpDecorate %_arr__arr_float_uint_4_uint_3 ArrayStride 16
|
||||
OpDecorate %_arr__arr__arr_float_uint_4_uint_3_uint_2 ArrayStride 48
|
||||
%float = OpTypeFloat 32
|
||||
%uint = OpTypeInt 32 0
|
||||
%uint_4 = OpConstant %uint 4
|
||||
%_arr_float_uint_4 = OpTypeArray %float %uint_4
|
||||
%1 = OpTypeFunction %_arr_float_uint_4
|
||||
%8 = OpConstantNull %_arr_float_uint_4
|
||||
%uint_3 = OpConstant %uint 3
|
||||
%_arr__arr_float_uint_4_uint_3 = OpTypeArray %_arr_float_uint_4 %uint_3
|
||||
%9 = OpTypeFunction %_arr__arr_float_uint_4_uint_3
|
||||
%uint_2 = OpConstant %uint 2
|
||||
%_arr__arr__arr_float_uint_4_uint_3_uint_2 = OpTypeArray %_arr__arr_float_uint_4_uint_3 %uint_2
|
||||
%18 = OpTypeFunction %_arr__arr__arr_float_uint_4_uint_3_uint_2
|
||||
%void = OpTypeVoid
|
||||
%26 = OpTypeFunction %void
|
||||
%f1 = OpFunction %_arr_float_uint_4 None %1
|
||||
%7 = OpLabel
|
||||
OpReturnValue %8
|
||||
OpFunctionEnd
|
||||
%f2 = OpFunction %_arr__arr_float_uint_4_uint_3 None %9
|
||||
%13 = OpLabel
|
||||
%14 = OpFunctionCall %_arr_float_uint_4 %f1
|
||||
%15 = OpFunctionCall %_arr_float_uint_4 %f1
|
||||
%16 = OpFunctionCall %_arr_float_uint_4 %f1
|
||||
%17 = OpCompositeConstruct %_arr__arr_float_uint_4_uint_3 %14 %15 %16
|
||||
OpReturnValue %17
|
||||
OpFunctionEnd
|
||||
%f3 = OpFunction %_arr__arr__arr_float_uint_4_uint_3_uint_2 None %18
|
||||
%22 = OpLabel
|
||||
%23 = OpFunctionCall %_arr__arr_float_uint_4_uint_3 %f2
|
||||
%24 = OpFunctionCall %_arr__arr_float_uint_4_uint_3 %f2
|
||||
%25 = OpCompositeConstruct %_arr__arr__arr_float_uint_4_uint_3_uint_2 %23 %24
|
||||
OpReturnValue %25
|
||||
OpFunctionEnd
|
||||
%main = OpFunction %void None %26
|
||||
%29 = OpLabel
|
||||
%30 = OpFunctionCall %_arr_float_uint_4 %f1
|
||||
%31 = OpFunctionCall %_arr__arr_float_uint_4_uint_3 %f2
|
||||
%32 = OpFunctionCall %_arr__arr__arr_float_uint_4_uint_3_uint_2 %f3
|
||||
OpReturn
|
||||
OpFunctionEnd
|
|
@ -0,0 +1,18 @@
|
|||
fn f1() -> array<f32, 4> {
|
||||
return array<f32, 4>();
|
||||
}
|
||||
|
||||
fn f2() -> array<array<f32, 4>, 3> {
|
||||
return array<array<f32, 4>, 3>(f1(), f1(), f1());
|
||||
}
|
||||
|
||||
fn f3() -> array<array<array<f32, 4>, 3>, 2> {
|
||||
return array<array<array<f32, 4>, 3>, 2>(f2(), f2());
|
||||
}
|
||||
|
||||
[[stage(compute)]]
|
||||
fn main() {
|
||||
let a1 : array<f32, 4> = f1();
|
||||
let a2 : array<array<f32, 4>, 3> = f2();
|
||||
let a3 : array<array<array<f32, 4>, 3>, 2> = f3();
|
||||
}
|
|
@ -1 +1,53 @@
|
|||
SKIP: crbug.com/tint/814
|
||||
#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
struct tint_array_wrapper_0 {
|
||||
int array[4];
|
||||
};
|
||||
struct tint_array_wrapper_1 {
|
||||
tint_array_wrapper_0 array[3];
|
||||
};
|
||||
struct tint_array_wrapper_2 {
|
||||
tint_array_wrapper_1 array[2];
|
||||
};
|
||||
struct tint_array_wrapper_3 {
|
||||
tint_array_wrapper_0 array[2];
|
||||
};
|
||||
|
||||
kernel void tint_symbol() {
|
||||
int const x = 42;
|
||||
tint_array_wrapper_0 const empty = {};
|
||||
tint_array_wrapper_0 const nonempty = {1, 2, 3, 4};
|
||||
tint_array_wrapper_0 const nonempty_with_expr = {1, x, (x + 1), nonempty.array[3]};
|
||||
tint_array_wrapper_2 const nested_empty = {};
|
||||
tint_array_wrapper_0 const tint_symbol_1 = {1, 2, 3, 4};
|
||||
tint_array_wrapper_0 const tint_symbol_2 = {5, 6, 7, 8};
|
||||
tint_array_wrapper_0 const tint_symbol_3 = {9, 10, 11, 12};
|
||||
tint_array_wrapper_1 const tint_symbol_4 = {tint_symbol_1, tint_symbol_2, tint_symbol_3};
|
||||
tint_array_wrapper_0 const tint_symbol_5 = {13, 14, 15, 16};
|
||||
tint_array_wrapper_0 const tint_symbol_6 = {17, 18, 19, 20};
|
||||
tint_array_wrapper_0 const tint_symbol_7 = {21, 22, 23, 24};
|
||||
tint_array_wrapper_1 const tint_symbol_8 = {tint_symbol_5, tint_symbol_6, tint_symbol_7};
|
||||
tint_array_wrapper_2 const nested_nonempty = {tint_symbol_4, tint_symbol_8};
|
||||
tint_array_wrapper_0 const tint_symbol_9 = {1, 2, x, (x + 1)};
|
||||
tint_array_wrapper_0 const tint_symbol_10 = {5, 6, nonempty.array[2], (nonempty.array[3] + 1)};
|
||||
tint_array_wrapper_1 const tint_symbol_11 = {tint_symbol_9, tint_symbol_10, nonempty};
|
||||
tint_array_wrapper_2 const nested_nonempty_with_expr = {tint_symbol_11, nested_nonempty.array[1]};
|
||||
tint_array_wrapper_0 const tint_symbol_12 = {};
|
||||
int const subexpr_empty = tint_symbol_12.array[1];
|
||||
tint_array_wrapper_0 const tint_symbol_13 = {1, 2, 3, 4};
|
||||
int const subexpr_nonempty = tint_symbol_13.array[2];
|
||||
tint_array_wrapper_0 const tint_symbol_14 = {1, x, (x + 1), nonempty.array[3]};
|
||||
int const subexpr_nonempty_with_expr = tint_symbol_14.array[2];
|
||||
tint_array_wrapper_3 const tint_symbol_15 = {};
|
||||
tint_array_wrapper_0 const subexpr_nested_empty = tint_symbol_15.array[1];
|
||||
tint_array_wrapper_0 const tint_symbol_16 = {1, 2, 3, 4};
|
||||
tint_array_wrapper_0 const tint_symbol_17 = {5, 6, 7, 8};
|
||||
tint_array_wrapper_3 const tint_symbol_18 = {tint_symbol_16, tint_symbol_17};
|
||||
tint_array_wrapper_0 const subexpr_nested_nonempty = tint_symbol_18.array[1];
|
||||
tint_array_wrapper_0 const tint_symbol_19 = {1, x, (x + 1), nonempty.array[3]};
|
||||
tint_array_wrapper_3 const tint_symbol_20 = {tint_symbol_19, nested_nonempty.array[1].array[2]};
|
||||
tint_array_wrapper_0 const subexpr_nested_nonempty_with_expr = tint_symbol_20.array[1];
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
SKIP: crbug.com/tint/814
|
||||
|
||||
#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
struct tint_array_wrapper_0 {
|
||||
int array[2];
|
||||
};
|
||||
|
||||
void foo() {
|
||||
int tint_symbol[2] = {0};
|
||||
int implict[2] = {0};
|
||||
tint_array_wrapper_0 tint_symbol = {0};
|
||||
tint_array_wrapper_0 implict = {0};
|
||||
implict = tint_symbol;
|
||||
}
|
||||
|
||||
|
|
|
@ -1 +1,67 @@
|
|||
SKIP: crbug.com/tint/814
|
||||
#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
struct S1 {
|
||||
int a;
|
||||
int b;
|
||||
int c;
|
||||
int d;
|
||||
};
|
||||
struct S2 {
|
||||
int e;
|
||||
S1 f;
|
||||
};
|
||||
struct S3 {
|
||||
int g;
|
||||
S1 h;
|
||||
S2 i;
|
||||
};
|
||||
struct tint_array_wrapper_0 {
|
||||
int array[2];
|
||||
};
|
||||
struct T {
|
||||
tint_array_wrapper_0 a;
|
||||
};
|
||||
struct tint_array_wrapper_1 {
|
||||
T array[2];
|
||||
};
|
||||
|
||||
kernel void tint_symbol() {
|
||||
int const x = 42;
|
||||
S1 const empty = {};
|
||||
S1 const nonempty = {1, 2, 3, 4};
|
||||
S1 const nonempty_with_expr = {1, x, (x + 1), nonempty.d};
|
||||
S3 const nested_empty = {};
|
||||
S1 const tint_symbol_1 = {2, 3, 4, 5};
|
||||
S1 const tint_symbol_2 = {7, 8, 9, 10};
|
||||
S2 const tint_symbol_3 = {6, tint_symbol_2};
|
||||
S3 const nested_nonempty = {1, tint_symbol_1, tint_symbol_3};
|
||||
S1 const tint_symbol_4 = {2, x, (x + 1), nested_nonempty.i.f.d};
|
||||
S2 const tint_symbol_5 = {6, nonempty};
|
||||
S3 const nested_nonempty_with_expr = {1, tint_symbol_4, tint_symbol_5};
|
||||
S1 const tint_symbol_6 = {};
|
||||
int const subexpr_empty = tint_symbol_6.a;
|
||||
S1 const tint_symbol_7 = {1, 2, 3, 4};
|
||||
int const subexpr_nonempty = tint_symbol_7.b;
|
||||
S1 const tint_symbol_8 = {1, x, (x + 1), nonempty.d};
|
||||
int const subexpr_nonempty_with_expr = tint_symbol_8.c;
|
||||
S2 const tint_symbol_9 = {};
|
||||
S1 const subexpr_nested_empty = tint_symbol_9.f;
|
||||
S1 const tint_symbol_10 = {2, 3, 4, 5};
|
||||
S2 const tint_symbol_11 = {1, tint_symbol_10};
|
||||
S1 const subexpr_nested_nonempty = tint_symbol_11.f;
|
||||
S1 const tint_symbol_12 = {2, x, (x + 1), nested_nonempty.i.f.d};
|
||||
S2 const tint_symbol_13 = {1, tint_symbol_12};
|
||||
S1 const subexpr_nested_nonempty_with_expr = tint_symbol_13.f;
|
||||
tint_array_wrapper_1 const aosoa_empty = {};
|
||||
tint_array_wrapper_0 const tint_symbol_14 = {1, 2};
|
||||
T const tint_symbol_15 = {tint_symbol_14};
|
||||
tint_array_wrapper_0 const tint_symbol_16 = {3, 4};
|
||||
T const tint_symbol_17 = {tint_symbol_16};
|
||||
tint_array_wrapper_1 const aosoa_nonempty = {tint_symbol_15, tint_symbol_17};
|
||||
tint_array_wrapper_0 const tint_symbol_18 = {1, (aosoa_nonempty.array[0].a.array[0] + 1)};
|
||||
T const tint_symbol_19 = {tint_symbol_18};
|
||||
tint_array_wrapper_1 const aosoa_nonempty_with_expr = {tint_symbol_19, aosoa_nonempty.array[1]};
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
using namespace metal;
|
||||
struct S {
|
||||
};
|
||||
struct tint_array_wrapper_0 {
|
||||
float array[4];
|
||||
};
|
||||
|
||||
kernel void tint_symbol() {
|
||||
bool bool_var = bool();
|
||||
|
@ -21,13 +24,13 @@ kernel void tint_symbol() {
|
|||
float4 const v4f32_let = float4();
|
||||
float2x3 m2x3_var = float2x3();
|
||||
float3x4 const m3x4_let = float3x4();
|
||||
float arr_var[4] = {};
|
||||
float const arr_let[4] = {};
|
||||
tint_array_wrapper_0 arr_var = {};
|
||||
tint_array_wrapper_0 const arr_let = {};
|
||||
S struct_var = {};
|
||||
S const struct_let = {};
|
||||
thread float* const ptr_f32 = &(f32_var);
|
||||
thread float4* const ptr_vec = &(v4f32_var);
|
||||
thread float (*const ptr_arr)[4] = &(arr_var);
|
||||
thread tint_array_wrapper_0* const ptr_arr = &(arr_var);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
using namespace metal;
|
||||
struct S {
|
||||
};
|
||||
struct tint_array_wrapper_0 {
|
||||
float array[4];
|
||||
};
|
||||
|
||||
constant bool bool_let = bool();
|
||||
constant int i32_let = int();
|
||||
|
@ -12,7 +15,7 @@ constant int2 v2i32_let = int2();
|
|||
constant uint3 v3u32_let = uint3();
|
||||
constant float4 v4f32_let = float4();
|
||||
constant float3x4 m3x4_let = float3x4();
|
||||
constant float arr_let[4] = {};
|
||||
constant tint_array_wrapper_0 arr_let = {};
|
||||
constant S struct_let = {};
|
||||
kernel void tint_symbol() {
|
||||
return;
|
||||
|
|
|
@ -1 +1,45 @@
|
|||
SKIP: crbug.com/tint/814
|
||||
#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
struct S {
|
||||
};
|
||||
struct tint_array_wrapper_0 {
|
||||
float array[4];
|
||||
};
|
||||
|
||||
kernel void tint_symbol() {
|
||||
thread bool tint_symbol_4 = false;
|
||||
thread bool* const tint_symbol_3 = &(tint_symbol_4);
|
||||
thread int tint_symbol_6 = 0;
|
||||
thread int* const tint_symbol_5 = &(tint_symbol_6);
|
||||
thread uint tint_symbol_8 = 0u;
|
||||
thread uint* const tint_symbol_7 = &(tint_symbol_8);
|
||||
thread float tint_symbol_10 = 0.0f;
|
||||
thread float* const tint_symbol_9 = &(tint_symbol_10);
|
||||
thread int2 tint_symbol_12 = 0;
|
||||
thread int2* const tint_symbol_11 = &(tint_symbol_12);
|
||||
thread uint3 tint_symbol_14 = 0u;
|
||||
thread uint3* const tint_symbol_13 = &(tint_symbol_14);
|
||||
thread float4 tint_symbol_16 = 0.0f;
|
||||
thread float4* const tint_symbol_15 = &(tint_symbol_16);
|
||||
thread float2x3 tint_symbol_18 = float2x3(0.0f);
|
||||
thread float2x3* const tint_symbol_17 = &(tint_symbol_18);
|
||||
thread tint_array_wrapper_0 tint_symbol_20 = {0.0f};
|
||||
thread tint_array_wrapper_0* const tint_symbol_19 = &(tint_symbol_20);
|
||||
thread S tint_symbol_22 = {};
|
||||
thread S* const tint_symbol_21 = &(tint_symbol_22);
|
||||
*(tint_symbol_3) = bool();
|
||||
*(tint_symbol_5) = int();
|
||||
*(tint_symbol_7) = uint();
|
||||
*(tint_symbol_9) = float();
|
||||
*(tint_symbol_11) = int2();
|
||||
*(tint_symbol_13) = uint3();
|
||||
*(tint_symbol_15) = float4();
|
||||
*(tint_symbol_17) = float2x3();
|
||||
tint_array_wrapper_0 const tint_symbol_1 = {};
|
||||
*(tint_symbol_19) = tint_symbol_1;
|
||||
S const tint_symbol_2 = {};
|
||||
*(tint_symbol_21) = tint_symbol_2;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1 +1,45 @@
|
|||
SKIP: crbug.com/tint/814
|
||||
#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
struct S {
|
||||
};
|
||||
struct tint_array_wrapper_0 {
|
||||
float array[4];
|
||||
};
|
||||
|
||||
kernel void tint_symbol() {
|
||||
thread bool tint_symbol_4 = bool();
|
||||
thread bool* const tint_symbol_3 = &(tint_symbol_4);
|
||||
thread int tint_symbol_6 = int();
|
||||
thread int* const tint_symbol_5 = &(tint_symbol_6);
|
||||
thread uint tint_symbol_8 = uint();
|
||||
thread uint* const tint_symbol_7 = &(tint_symbol_8);
|
||||
thread float tint_symbol_10 = float();
|
||||
thread float* const tint_symbol_9 = &(tint_symbol_10);
|
||||
thread int2 tint_symbol_12 = int2();
|
||||
thread int2* const tint_symbol_11 = &(tint_symbol_12);
|
||||
thread uint3 tint_symbol_14 = uint3();
|
||||
thread uint3* const tint_symbol_13 = &(tint_symbol_14);
|
||||
thread float4 tint_symbol_16 = float4();
|
||||
thread float4* const tint_symbol_15 = &(tint_symbol_16);
|
||||
thread float2x3 tint_symbol_18 = float2x3();
|
||||
thread float2x3* const tint_symbol_17 = &(tint_symbol_18);
|
||||
thread tint_array_wrapper_0 tint_symbol_20 = {};
|
||||
thread tint_array_wrapper_0* const tint_symbol_19 = &(tint_symbol_20);
|
||||
thread S tint_symbol_22 = {};
|
||||
thread S* const tint_symbol_21 = &(tint_symbol_22);
|
||||
*(tint_symbol_3) = bool();
|
||||
*(tint_symbol_5) = int();
|
||||
*(tint_symbol_7) = uint();
|
||||
*(tint_symbol_9) = float();
|
||||
*(tint_symbol_11) = int2();
|
||||
*(tint_symbol_13) = uint3();
|
||||
*(tint_symbol_15) = float4();
|
||||
*(tint_symbol_17) = float2x3();
|
||||
tint_array_wrapper_0 const tint_symbol_1 = {};
|
||||
*(tint_symbol_19) = tint_symbol_1;
|
||||
S const tint_symbol_2 = {};
|
||||
*(tint_symbol_21) = tint_symbol_2;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,8 +3,11 @@
|
|||
using namespace metal;
|
||||
struct S {
|
||||
};
|
||||
struct tint_array_wrapper_0 {
|
||||
float array[4];
|
||||
};
|
||||
|
||||
void foo(bool param_bool, int param_i32, uint param_u32, float param_f32, int2 param_v2i32, uint3 param_v3u32, float4 param_v4f32, float2x3 param_m2x3, float const param_arr[4], S param_struct, thread float* const param_ptr_f32, thread float4* const param_ptr_vec, thread float (*const param_ptr_arr)[4]) {
|
||||
void foo(bool param_bool, int param_i32, uint param_u32, float param_f32, int2 param_v2i32, uint3 param_v3u32, float4 param_v4f32, float2x3 param_m2x3, tint_array_wrapper_0 const param_arr, S param_struct, thread float* const param_ptr_f32, thread float4* const param_ptr_vec, thread tint_array_wrapper_0* const param_ptr_arr) {
|
||||
}
|
||||
|
||||
kernel void tint_symbol() {
|
||||
|
|
|
@ -1 +1 @@
|
|||
SKIP: crbug.com/tint/820: arrays as function return types
|
||||
SKIP: crbug.com/tint/848: arrays as function return types
|
||||
|
|
|
@ -1 +1,55 @@
|
|||
SKIP: crbug.com/tint/820: arrays as function return types
|
||||
#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
struct S {
|
||||
};
|
||||
struct tint_array_wrapper_0 {
|
||||
float array[4];
|
||||
};
|
||||
|
||||
bool ret_bool() {
|
||||
return bool();
|
||||
}
|
||||
|
||||
int ret_i32() {
|
||||
return int();
|
||||
}
|
||||
|
||||
uint ret_u32() {
|
||||
return uint();
|
||||
}
|
||||
|
||||
float ret_f32() {
|
||||
return float();
|
||||
}
|
||||
|
||||
int2 ret_v2i32() {
|
||||
return int2();
|
||||
}
|
||||
|
||||
uint3 ret_v3u32() {
|
||||
return uint3();
|
||||
}
|
||||
|
||||
float4 ret_v4f32() {
|
||||
return float4();
|
||||
}
|
||||
|
||||
float2x3 ret_m2x3() {
|
||||
return float2x3();
|
||||
}
|
||||
|
||||
tint_array_wrapper_0 ret_arr() {
|
||||
tint_array_wrapper_0 const tint_symbol_1 = {};
|
||||
return tint_symbol_1;
|
||||
}
|
||||
|
||||
S ret_struct() {
|
||||
S const tint_symbol_2 = {};
|
||||
return tint_symbol_2;
|
||||
}
|
||||
|
||||
kernel void tint_symbol() {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
using namespace metal;
|
||||
struct S_inner {
|
||||
};
|
||||
struct tint_array_wrapper_0 {
|
||||
float array[4];
|
||||
};
|
||||
struct S {
|
||||
bool member_bool;
|
||||
int member_i32;
|
||||
|
@ -12,7 +15,7 @@ struct S {
|
|||
uint3 member_v3u32;
|
||||
float4 member_v4f32;
|
||||
float2x3 member_m2x3;
|
||||
float member_arr[4];
|
||||
tint_array_wrapper_0 member_arr;
|
||||
S_inner member_struct;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue