blob: e1ade73bdf092275254646f949826714e4be7e49 [file] [log] [blame]
dan sinclairf9618502020-07-29 19:12:19 +00001// Copyright 2020 The Tint Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include <memory>
16
dan sinclairbdb86722020-08-25 21:22:37 +000017#include "src/ast/array_accessor_expression.h"
18#include "src/ast/assignment_statement.h"
dan sinclairf9618502020-07-29 19:12:19 +000019#include "src/ast/identifier_expression.h"
20#include "src/ast/member_accessor_expression.h"
21#include "src/ast/module.h"
dan sinclairbdb86722020-08-25 21:22:37 +000022#include "src/ast/scalar_constructor_expression.h"
23#include "src/ast/sint_literal.h"
dan sinclaireb5d3e12020-10-08 19:34:25 +000024#include "src/ast/stride_decoration.h"
dan sinclairbdb86722020-08-25 21:22:37 +000025#include "src/ast/struct.h"
26#include "src/ast/struct_member.h"
27#include "src/ast/struct_member_offset_decoration.h"
dan sinclairbdb86722020-08-25 21:22:37 +000028#include "src/ast/type_constructor_expression.h"
Ben Claytona80511e2020-12-11 13:07:02 +000029#include "src/ast/variable.h"
Ben Clayton207b5e22021-01-21 15:42:10 +000030#include "src/type/struct_type.h"
31#include "src/type/vector_type.h"
dan sinclairbdb86722020-08-25 21:22:37 +000032#include "src/type_determiner.h"
dan sinclairdf503f02020-08-26 19:05:46 +000033#include "src/writer/hlsl/test_helper.h"
dan sinclairf9618502020-07-29 19:12:19 +000034
35namespace tint {
36namespace writer {
37namespace hlsl {
38namespace {
39
dan sinclair63b007d2020-08-26 20:02:26 +000040using HlslGeneratorImplTest_MemberAccessor = TestHelper;
dan sinclairf9618502020-07-29 19:12:19 +000041
dan sinclairdf503f02020-08-26 19:05:46 +000042TEST_F(HlslGeneratorImplTest_MemberAccessor, EmitExpression_MemberAccessor) {
dan sinclair5e5e36e2020-12-16 14:41:00 +000043 auto* strct = create<ast::Struct>(
44 ast::StructMemberList{Member("mem", ty.f32, {MemberOffset(0)})},
45 ast::StructDecorationList{});
dan sinclairbdb86722020-08-25 21:22:37 +000046
dan sinclairb5839932020-12-16 21:38:40 +000047 auto* s = ty.struct_("Str", strct);
48 auto* str_var = Var("str", ast::StorageClass::kPrivate, s);
Ben Claytonf12054e2021-01-21 16:15:00 +000049 mod->AddGlobalVariable(str_var);
50
dan sinclair8b40a672020-12-16 11:49:10 +000051 auto* expr = MemberAccessor("str", "mem");
dan sinclairf9618502020-07-29 19:12:19 +000052
Ben Claytonb053acf2020-11-16 16:31:07 +000053 td.RegisterVariableForTesting(str_var);
Ben Clayton9df857d2020-12-15 14:11:48 +000054 ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
Ben Claytonf12054e2021-01-21 16:15:00 +000055
56 GeneratorImpl& gen = Build();
57
58 gen.register_global(str_var);
59
Ben Clayton9df857d2020-12-15 14:11:48 +000060 ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
dan sinclair987376c2021-01-12 04:34:53 +000061 EXPECT_EQ(result(), "str.mem");
dan sinclairf9618502020-07-29 19:12:19 +000062}
63
dan sinclairdf503f02020-08-26 19:05:46 +000064TEST_F(HlslGeneratorImplTest_MemberAccessor,
dan sinclairbdb86722020-08-25 21:22:37 +000065 EmitExpression_MemberAccessor_StorageBuffer_Load) {
66 // struct Data {
dan sinclair8b685862020-09-20 19:14:28 +000067 // [[offset(0)]] a : i32;
68 // [[offset(4)]] b : f32;
dan sinclairbdb86722020-08-25 21:22:37 +000069 // };
dan sinclair336bb0b2021-01-18 21:06:34 +000070 // var<storage> data : Data;
dan sinclairbdb86722020-08-25 21:22:37 +000071 // data.b;
72 //
73 // -> asfloat(data.Load(4));
dan sinclairbdb86722020-08-25 21:22:37 +000074
dan sinclair5e5e36e2020-12-16 14:41:00 +000075 auto* str = create<ast::Struct>(
76 ast::StructMemberList{Member("a", ty.i32, {MemberOffset(0)}),
77 Member("b", ty.f32, {MemberOffset(4)})},
78 ast::StructDecorationList{});
dan sinclairbdb86722020-08-25 21:22:37 +000079
dan sinclairb5839932020-12-16 21:38:40 +000080 auto* s = ty.struct_("Data", str);
dan sinclair336bb0b2021-01-18 21:06:34 +000081 auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
Ben Clayton9df857d2020-12-15 14:11:48 +000082 mod->AddGlobalVariable(coord_var);
Ben Claytonf12054e2021-01-21 16:15:00 +000083 td.RegisterVariableForTesting(coord_var);
84
85 auto* expr = MemberAccessor("data", "b");
dan sinclairbdb86722020-08-25 21:22:37 +000086
dan sinclair196e0972020-11-13 18:13:24 +000087 ASSERT_TRUE(td.Determine()) << td.error();
Ben Clayton9df857d2020-12-15 14:11:48 +000088 ASSERT_TRUE(td.DetermineResultType(expr));
dan sinclairbdb86722020-08-25 21:22:37 +000089
Ben Claytonf12054e2021-01-21 16:15:00 +000090 GeneratorImpl& gen = Build();
91
92 gen.register_global(coord_var);
93
Ben Clayton9df857d2020-12-15 14:11:48 +000094 ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
dan sinclair987376c2021-01-12 04:34:53 +000095 EXPECT_EQ(result(), "asfloat(data.Load(4))");
dan sinclairbdb86722020-08-25 21:22:37 +000096}
97
dan sinclairdf503f02020-08-26 19:05:46 +000098TEST_F(HlslGeneratorImplTest_MemberAccessor,
dan sinclairbdb86722020-08-25 21:22:37 +000099 EmitExpression_MemberAccessor_StorageBuffer_Load_Int) {
100 // struct Data {
dan sinclair8b685862020-09-20 19:14:28 +0000101 // [[offset(0)]] a : i32;
102 // [[offset(4)]] b : f32;
dan sinclairbdb86722020-08-25 21:22:37 +0000103 // };
dan sinclair336bb0b2021-01-18 21:06:34 +0000104 // var<storage> data : Data;
dan sinclairbdb86722020-08-25 21:22:37 +0000105 // data.a;
106 //
107 // -> asint(data.Load(0));
dan sinclairbdb86722020-08-25 21:22:37 +0000108
dan sinclair5e5e36e2020-12-16 14:41:00 +0000109 auto* str = create<ast::Struct>(
110 ast::StructMemberList{Member("a", ty.i32, {MemberOffset(0)}),
111 Member("b", ty.f32, {MemberOffset(4)})},
112 ast::StructDecorationList{});
dan sinclairb5839932020-12-16 21:38:40 +0000113 auto* s = ty.struct_("Data", str);
dan sinclair336bb0b2021-01-18 21:06:34 +0000114 auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
Ben Clayton9df857d2020-12-15 14:11:48 +0000115 mod->AddGlobalVariable(coord_var);
Ben Claytonf12054e2021-01-21 16:15:00 +0000116 td.RegisterVariableForTesting(coord_var);
117
118 auto* expr = MemberAccessor("data", "a");
dan sinclairbdb86722020-08-25 21:22:37 +0000119
dan sinclair196e0972020-11-13 18:13:24 +0000120 ASSERT_TRUE(td.Determine()) << td.error();
Ben Clayton9df857d2020-12-15 14:11:48 +0000121 ASSERT_TRUE(td.DetermineResultType(expr));
dan sinclairbdb86722020-08-25 21:22:37 +0000122
Ben Claytonf12054e2021-01-21 16:15:00 +0000123 GeneratorImpl& gen = Build();
124
125 gen.register_global(coord_var);
126
Ben Clayton9df857d2020-12-15 14:11:48 +0000127 ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
dan sinclair987376c2021-01-12 04:34:53 +0000128 EXPECT_EQ(result(), "asint(data.Load(0))");
dan sinclairbdb86722020-08-25 21:22:37 +0000129}
Ben Claytonf12054e2021-01-21 16:15:00 +0000130
dan sinclair663be302020-08-26 19:55:46 +0000131TEST_F(HlslGeneratorImplTest_MemberAccessor,
132 EmitExpression_MemberAccessor_StorageBuffer_Store_Matrix) {
133 // struct Data {
dan sinclair8b685862020-09-20 19:14:28 +0000134 // [[offset(0)]] z : f32;
135 // [[offset(4)]] a : mat2x3<f32>;
dan sinclair663be302020-08-26 19:55:46 +0000136 // };
dan sinclair336bb0b2021-01-18 21:06:34 +0000137 // var<storage> data : Data;
dan sinclair663be302020-08-26 19:55:46 +0000138 // mat2x3<f32> b;
139 // data.a = b;
140 //
Ben Clayton5b5c98c2020-11-20 09:37:14 +0000141 // -> float3x2 _tint_tmp = b;
dan sinclair663be302020-08-26 19:55:46 +0000142 // data.Store3(4 + 0, asuint(_tint_tmp[0]));
143 // data.Store3(4 + 16, asuint(_tint_tmp[1]));
dan sinclair663be302020-08-26 19:55:46 +0000144
Ben Claytonbcf37542020-12-12 12:52:44 +0000145 auto* str = create<ast::Struct>(
dan sinclair5e5e36e2020-12-16 14:41:00 +0000146 ast::StructMemberList{Member("z", ty.i32, {MemberOffset(0)}),
147 Member("a", ty.mat2x3<f32>(), {MemberOffset(4)})},
Ben Claytonbcf37542020-12-12 12:52:44 +0000148 ast::StructDecorationList{});
dan sinclair663be302020-08-26 19:55:46 +0000149
dan sinclairb5839932020-12-16 21:38:40 +0000150 auto* s = ty.struct_("Data", str);
Ben Clayton9df857d2020-12-15 14:11:48 +0000151 auto* b_var = Var("b", ast::StorageClass::kPrivate, ty.mat2x3<f32>());
Ben Claytonf12054e2021-01-21 16:15:00 +0000152 mod->AddGlobalVariable(b_var);
dan sinclair336bb0b2021-01-18 21:06:34 +0000153 auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
Ben Claytonf12054e2021-01-21 16:15:00 +0000154 mod->AddGlobalVariable(coord_var);
dan sinclair663be302020-08-26 19:55:46 +0000155
dan sinclair8b40a672020-12-16 11:49:10 +0000156 auto* lhs = MemberAccessor("data", "a");
Ben Clayton9df857d2020-12-15 14:11:48 +0000157 auto* rhs = Expr("b");
dan sinclair663be302020-08-26 19:55:46 +0000158
Ben Clayton9df857d2020-12-15 14:11:48 +0000159 auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
dan sinclair663be302020-08-26 19:55:46 +0000160
Ben Claytonb053acf2020-11-16 16:31:07 +0000161 td.RegisterVariableForTesting(coord_var);
162 td.RegisterVariableForTesting(b_var);
dan sinclair663be302020-08-26 19:55:46 +0000163
dan sinclair196e0972020-11-13 18:13:24 +0000164 ASSERT_TRUE(td.Determine()) << td.error();
Ben Clayton9df857d2020-12-15 14:11:48 +0000165 ASSERT_TRUE(td.DetermineResultType(assign));
dan sinclair663be302020-08-26 19:55:46 +0000166
Ben Claytonf12054e2021-01-21 16:15:00 +0000167 GeneratorImpl& gen = Build();
168
169 gen.register_global(coord_var);
170 gen.register_global(b_var);
171
Ben Clayton9df857d2020-12-15 14:11:48 +0000172 ASSERT_TRUE(gen.EmitStatement(out, assign)) << gen.error();
dan sinclair987376c2021-01-12 04:34:53 +0000173 EXPECT_EQ(result(), R"(float3x2 _tint_tmp = b;
174data.Store3(4 + 0, asuint(_tint_tmp[0]));
175data.Store3(4 + 16, asuint(_tint_tmp[1]));
dan sinclair663be302020-08-26 19:55:46 +0000176)");
177}
178
179TEST_F(HlslGeneratorImplTest_MemberAccessor,
180 EmitExpression_MemberAccessor_StorageBuffer_Store_Matrix_Empty) {
181 // struct Data {
dan sinclair8b685862020-09-20 19:14:28 +0000182 // [[offset(0)]] z : f32;
183 // [[offset(4)]] a : mat2x3<f32>;
dan sinclair663be302020-08-26 19:55:46 +0000184 // };
dan sinclair336bb0b2021-01-18 21:06:34 +0000185 // var<storage> data : Data;
dan sinclair663be302020-08-26 19:55:46 +0000186 // data.a = mat2x3<f32>();
187 //
Ben Clayton5b5c98c2020-11-20 09:37:14 +0000188 // -> float3x2 _tint_tmp = float3x2(0.0f, 0.0f, 0.0f,
dan sinclair663be302020-08-26 19:55:46 +0000189 // 0.0f, 0.0f, 0.0f);
190 // data.Store3(4 + 0, asuint(_tint_tmp[0]);
191 // data.Store3(4 + 16, asuint(_tint_tmp[1]));
dan sinclair663be302020-08-26 19:55:46 +0000192
dan sinclair5e5e36e2020-12-16 14:41:00 +0000193 auto* str = create<ast::Struct>(
194 ast::StructMemberList{Member("z", ty.i32, {MemberOffset(0)}),
195 Member("a", ty.mat2x3<f32>(), {MemberOffset(4)})},
196 ast::StructDecorationList{});
dan sinclair663be302020-08-26 19:55:46 +0000197
dan sinclairb5839932020-12-16 21:38:40 +0000198 auto* s = ty.struct_("Data", str);
dan sinclair336bb0b2021-01-18 21:06:34 +0000199 auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
Ben Claytonf12054e2021-01-21 16:15:00 +0000200 mod->AddGlobalVariable(coord_var);
201 td.RegisterVariableForTesting(coord_var);
dan sinclair663be302020-08-26 19:55:46 +0000202
dan sinclair8b40a672020-12-16 11:49:10 +0000203 auto* lhs = MemberAccessor("data", "a");
Ben Clayton9df857d2020-12-15 14:11:48 +0000204 auto* rhs = Construct(ty.mat2x3<f32>(), ast::ExpressionList{});
dan sinclair663be302020-08-26 19:55:46 +0000205
Ben Clayton9df857d2020-12-15 14:11:48 +0000206 auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
dan sinclair663be302020-08-26 19:55:46 +0000207
dan sinclair196e0972020-11-13 18:13:24 +0000208 ASSERT_TRUE(td.Determine()) << td.error();
Ben Clayton9df857d2020-12-15 14:11:48 +0000209 ASSERT_TRUE(td.DetermineResultType(assign));
dan sinclair663be302020-08-26 19:55:46 +0000210
Ben Claytonf12054e2021-01-21 16:15:00 +0000211 GeneratorImpl& gen = Build();
212
213 gen.register_global(coord_var);
214
Ben Clayton9df857d2020-12-15 14:11:48 +0000215 ASSERT_TRUE(gen.EmitStatement(out, assign)) << gen.error();
dan sinclair663be302020-08-26 19:55:46 +0000216 EXPECT_EQ(
217 result(),
Ben Clayton5b5c98c2020-11-20 09:37:14 +0000218 R"(float3x2 _tint_tmp = float3x2(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
dan sinclair987376c2021-01-12 04:34:53 +0000219data.Store3(4 + 0, asuint(_tint_tmp[0]));
220data.Store3(4 + 16, asuint(_tint_tmp[1]));
dan sinclair663be302020-08-26 19:55:46 +0000221)");
222}
223
224TEST_F(HlslGeneratorImplTest_MemberAccessor,
225 EmitExpression_MemberAccessor_StorageBuffer_Load_Matrix) {
226 // struct Data {
dan sinclair8b685862020-09-20 19:14:28 +0000227 // [[offset(0)]] z : f32;
228 // [[offset(4)]] a : mat3x2<f32>;
dan sinclair663be302020-08-26 19:55:46 +0000229 // };
dan sinclair336bb0b2021-01-18 21:06:34 +0000230 // var<storage> data : Data;
dan sinclair663be302020-08-26 19:55:46 +0000231 // data.a;
232 //
Ben Clayton5b5c98c2020-11-20 09:37:14 +0000233 // -> asfloat(uint2x3(data.Load2(4 + 0), data.Load2(4 + 8),
dan sinclair663be302020-08-26 19:55:46 +0000234 // data.Load2(4 + 16)));
dan sinclair663be302020-08-26 19:55:46 +0000235
dan sinclair5e5e36e2020-12-16 14:41:00 +0000236 auto* str = create<ast::Struct>(
237 ast::StructMemberList{Member("z", ty.i32, {MemberOffset(0)}),
238 Member("a", ty.mat3x2<f32>(), {MemberOffset(4)})},
239 ast::StructDecorationList{});
dan sinclair663be302020-08-26 19:55:46 +0000240
dan sinclairb5839932020-12-16 21:38:40 +0000241 auto* s = ty.struct_("Data", str);
dan sinclair336bb0b2021-01-18 21:06:34 +0000242 auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
Ben Claytonf12054e2021-01-21 16:15:00 +0000243 mod->AddGlobalVariable(coord_var);
244 td.RegisterVariableForTesting(coord_var);
dan sinclair663be302020-08-26 19:55:46 +0000245
dan sinclair8b40a672020-12-16 11:49:10 +0000246 auto* expr = MemberAccessor("data", "a");
dan sinclair663be302020-08-26 19:55:46 +0000247
dan sinclair196e0972020-11-13 18:13:24 +0000248 ASSERT_TRUE(td.Determine()) << td.error();
Ben Clayton9df857d2020-12-15 14:11:48 +0000249 ASSERT_TRUE(td.DetermineResultType(expr));
dan sinclair663be302020-08-26 19:55:46 +0000250
Ben Claytonf12054e2021-01-21 16:15:00 +0000251 GeneratorImpl& gen = Build();
252
253 gen.register_global(coord_var);
254
Ben Clayton9df857d2020-12-15 14:11:48 +0000255 ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
dan sinclair663be302020-08-26 19:55:46 +0000256 EXPECT_EQ(result(),
dan sinclair987376c2021-01-12 04:34:53 +0000257 "asfloat(uint2x3(data.Load2(4 + 0), data.Load2(4 + 8), "
258 "data.Load2(4 + 16)))");
dan sinclair663be302020-08-26 19:55:46 +0000259}
260
261TEST_F(HlslGeneratorImplTest_MemberAccessor,
262 EmitExpression_MemberAccessor_StorageBuffer_Load_Matrix_Nested) {
263 // struct Data {
dan sinclair8b685862020-09-20 19:14:28 +0000264 // [[offset(0)]] z : f32;
265 // [[offset(4)]] a : mat2x3<f32;
dan sinclair663be302020-08-26 19:55:46 +0000266 // };
267 // struct Outer {
dan sinclair8b685862020-09-20 19:14:28 +0000268 // [[offset(0)]] c : f32;
269 // [[offset(4)]] b : Data;
dan sinclair663be302020-08-26 19:55:46 +0000270 // };
dan sinclair336bb0b2021-01-18 21:06:34 +0000271 // var<storage> data : Outer;
dan sinclair663be302020-08-26 19:55:46 +0000272 // data.b.a;
273 //
Ben Clayton5b5c98c2020-11-20 09:37:14 +0000274 // -> asfloat(uint3x2(data.Load3(4 + 0), data.Load3(4 + 16)));
dan sinclair663be302020-08-26 19:55:46 +0000275
dan sinclair5e5e36e2020-12-16 14:41:00 +0000276 auto* str = create<ast::Struct>(
277 ast::StructMemberList{
278 Member("z", ty.i32, {MemberOffset(0)}),
279 Member("a", ty.mat2x3<f32>(), {MemberOffset(4)}),
280 },
281 ast::StructDecorationList{});
dan sinclair663be302020-08-26 19:55:46 +0000282
dan sinclairb5839932020-12-16 21:38:40 +0000283 auto* s = ty.struct_("Data", str);
dan sinclair336bb0b2021-01-18 21:06:34 +0000284 auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
Ben Clayton9df857d2020-12-15 14:11:48 +0000285 mod->AddGlobalVariable(coord_var);
Ben Claytonf12054e2021-01-21 16:15:00 +0000286 td.RegisterVariableForTesting(coord_var);
287
288 auto* expr = MemberAccessor("data", "a");
dan sinclair663be302020-08-26 19:55:46 +0000289
dan sinclair196e0972020-11-13 18:13:24 +0000290 ASSERT_TRUE(td.Determine()) << td.error();
Ben Clayton9df857d2020-12-15 14:11:48 +0000291 ASSERT_TRUE(td.DetermineResultType(expr));
dan sinclair663be302020-08-26 19:55:46 +0000292
Ben Claytonf12054e2021-01-21 16:15:00 +0000293 GeneratorImpl& gen = Build();
294
295 gen.register_global(coord_var);
296
Ben Clayton9df857d2020-12-15 14:11:48 +0000297 ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
dan sinclair987376c2021-01-12 04:34:53 +0000298 EXPECT_EQ(result(),
299 "asfloat(uint3x2(data.Load3(4 + 0), data.Load3(4 + 16)))");
dan sinclair663be302020-08-26 19:55:46 +0000300}
301
302TEST_F(
303 HlslGeneratorImplTest_MemberAccessor,
304 EmitExpression_MemberAccessor_StorageBuffer_Load_Matrix_By3_Is_16_Bytes) {
305 // struct Data {
dan sinclair8b685862020-09-20 19:14:28 +0000306 // [[offset(4)]] a : mat3x3<f32;
dan sinclair663be302020-08-26 19:55:46 +0000307 // };
dan sinclair336bb0b2021-01-18 21:06:34 +0000308 // var<storage> data : Data;
dan sinclair663be302020-08-26 19:55:46 +0000309 // data.a;
310 //
Ben Clayton5b5c98c2020-11-20 09:37:14 +0000311 // -> asfloat(uint3x3(data.Load3(0), data.Load3(16),
dan sinclair663be302020-08-26 19:55:46 +0000312 // data.Load3(32)));
dan sinclair663be302020-08-26 19:55:46 +0000313
dan sinclair5e5e36e2020-12-16 14:41:00 +0000314 auto* str = create<ast::Struct>(
315 ast::StructMemberList{Member("a", ty.mat3x3<f32>(), {MemberOffset(0)})},
316 ast::StructDecorationList{});
dan sinclair663be302020-08-26 19:55:46 +0000317
dan sinclairb5839932020-12-16 21:38:40 +0000318 auto* s = ty.struct_("Data", str);
dan sinclair336bb0b2021-01-18 21:06:34 +0000319 auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
Ben Clayton9df857d2020-12-15 14:11:48 +0000320 mod->AddGlobalVariable(coord_var);
Ben Claytonf12054e2021-01-21 16:15:00 +0000321 td.RegisterVariableForTesting(coord_var);
322
323 auto* expr = MemberAccessor("data", "a");
dan sinclair663be302020-08-26 19:55:46 +0000324
dan sinclair196e0972020-11-13 18:13:24 +0000325 ASSERT_TRUE(td.Determine()) << td.error();
Ben Clayton9df857d2020-12-15 14:11:48 +0000326 ASSERT_TRUE(td.DetermineResultType(expr));
dan sinclair663be302020-08-26 19:55:46 +0000327
Ben Claytonf12054e2021-01-21 16:15:00 +0000328 GeneratorImpl& gen = Build();
329
330 gen.register_global(coord_var);
331
Ben Clayton9df857d2020-12-15 14:11:48 +0000332 ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
dan sinclair663be302020-08-26 19:55:46 +0000333 EXPECT_EQ(result(),
dan sinclair987376c2021-01-12 04:34:53 +0000334 "asfloat(uint3x3(data.Load3(0 + 0), data.Load3(0 + 16), "
335 "data.Load3(0 + 32)))");
dan sinclair663be302020-08-26 19:55:46 +0000336}
337
338TEST_F(HlslGeneratorImplTest_MemberAccessor,
339 EmitExpression_MemberAccessor_StorageBuffer_Load_Matrix_Single_Element) {
340 // struct Data {
dan sinclair8b685862020-09-20 19:14:28 +0000341 // [[offset(0)]] z : f32;
342 // [[offset(16)]] a : mat4x3<f32>;
dan sinclair663be302020-08-26 19:55:46 +0000343 // };
dan sinclair336bb0b2021-01-18 21:06:34 +0000344 // var<storage> data : Data;
dan sinclair663be302020-08-26 19:55:46 +0000345 // data.a[2][1];
346 //
347 // -> asfloat(data.Load((2 * 16) + (1 * 4) + 16)))
dan sinclair663be302020-08-26 19:55:46 +0000348
dan sinclair5e5e36e2020-12-16 14:41:00 +0000349 auto* str = create<ast::Struct>(
350 ast::StructMemberList{Member("z", ty.i32, {MemberOffset(0)}),
351 Member("a", ty.mat4x3<f32>(), {MemberOffset(16)})},
352 ast::StructDecorationList{});
dan sinclair663be302020-08-26 19:55:46 +0000353
dan sinclairb5839932020-12-16 21:38:40 +0000354 auto* s = ty.struct_("Data", str);
dan sinclair336bb0b2021-01-18 21:06:34 +0000355 auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
Ben Claytonf12054e2021-01-21 16:15:00 +0000356 mod->AddGlobalVariable(coord_var);
357 td.RegisterVariableForTesting(coord_var);
358
dan sinclair8b40a672020-12-16 11:49:10 +0000359 auto* expr = IndexAccessor(
360 IndexAccessor(MemberAccessor("data", "a"), Expr(2)), Expr(1));
dan sinclair663be302020-08-26 19:55:46 +0000361
dan sinclair196e0972020-11-13 18:13:24 +0000362 ASSERT_TRUE(td.Determine()) << td.error();
Ben Clayton9df857d2020-12-15 14:11:48 +0000363 ASSERT_TRUE(td.DetermineResultType(expr));
dan sinclair663be302020-08-26 19:55:46 +0000364
Ben Claytonf12054e2021-01-21 16:15:00 +0000365 GeneratorImpl& gen = Build();
366
367 gen.register_global(coord_var);
368
Ben Clayton9df857d2020-12-15 14:11:48 +0000369 ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
dan sinclair987376c2021-01-12 04:34:53 +0000370 EXPECT_EQ(result(), "asfloat(data.Load((4 * 1) + (16 * 2) + 16))");
dan sinclair663be302020-08-26 19:55:46 +0000371}
dan sinclairbdb86722020-08-25 21:22:37 +0000372
dan sinclairdf503f02020-08-26 19:05:46 +0000373TEST_F(HlslGeneratorImplTest_MemberAccessor,
dan sinclairbdb86722020-08-25 21:22:37 +0000374 EmitExpression_ArrayAccessor_StorageBuffer_Load_Int_FromArray) {
375 // struct Data {
dan sinclair077d16d2020-09-20 21:28:18 +0000376 // [[offset(0)]] a : [[stride(4)]] array<i32, 5>;
dan sinclairbdb86722020-08-25 21:22:37 +0000377 // };
dan sinclair336bb0b2021-01-18 21:06:34 +0000378 // var<storage> data : Data;
dan sinclairbdb86722020-08-25 21:22:37 +0000379 // data.a[2];
380 //
381 // -> asint(data.Load((2 * 4));
Ben Clayton207b5e22021-01-21 15:42:10 +0000382 type::Array ary(ty.i32, 5,
383 ast::ArrayDecorationList{
384 create<ast::StrideDecoration>(4),
385 });
dan sinclairbdb86722020-08-25 21:22:37 +0000386
dan sinclair5e5e36e2020-12-16 14:41:00 +0000387 auto* str = create<ast::Struct>(
388 ast::StructMemberList{Member("a", &ary, {MemberOffset(0)})},
389 ast::StructDecorationList{});
dan sinclairb5839932020-12-16 21:38:40 +0000390 auto* s = ty.struct_("Data", str);
dan sinclair336bb0b2021-01-18 21:06:34 +0000391 auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
Ben Clayton9df857d2020-12-15 14:11:48 +0000392 mod->AddGlobalVariable(coord_var);
Ben Claytonf12054e2021-01-21 16:15:00 +0000393 td.RegisterVariableForTesting(coord_var);
394
395 auto* expr = IndexAccessor(MemberAccessor("data", "a"), Expr(2));
dan sinclairbdb86722020-08-25 21:22:37 +0000396
dan sinclair196e0972020-11-13 18:13:24 +0000397 ASSERT_TRUE(td.Determine()) << td.error();
Ben Clayton9df857d2020-12-15 14:11:48 +0000398 ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
dan sinclairbdb86722020-08-25 21:22:37 +0000399
Ben Claytonf12054e2021-01-21 16:15:00 +0000400 GeneratorImpl& gen = Build();
401
402 gen.register_global(coord_var);
403
Ben Clayton9df857d2020-12-15 14:11:48 +0000404 ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
dan sinclair987376c2021-01-12 04:34:53 +0000405 EXPECT_EQ(result(), "asint(data.Load((4 * 2) + 0))");
dan sinclairbdb86722020-08-25 21:22:37 +0000406}
407
dan sinclairdf503f02020-08-26 19:05:46 +0000408TEST_F(HlslGeneratorImplTest_MemberAccessor,
dan sinclairbdb86722020-08-25 21:22:37 +0000409 EmitExpression_ArrayAccessor_StorageBuffer_Load_Int_FromArray_ExprIdx) {
410 // struct Data {
dan sinclair077d16d2020-09-20 21:28:18 +0000411 // [[offset(0)]] a : [[stride(4)]] array<i32, 5>;
dan sinclairbdb86722020-08-25 21:22:37 +0000412 // };
dan sinclair336bb0b2021-01-18 21:06:34 +0000413 // var<storage> data : Data;
dan sinclairbdb86722020-08-25 21:22:37 +0000414 // data.a[(2 + 4) - 3];
415 //
416 // -> asint(data.Load((4 * ((2 + 4) - 3)));
Ben Clayton207b5e22021-01-21 15:42:10 +0000417 type::Array ary(ty.i32, 5,
418 ast::ArrayDecorationList{
419 create<ast::StrideDecoration>(4),
420 });
dan sinclairbdb86722020-08-25 21:22:37 +0000421
dan sinclair5e5e36e2020-12-16 14:41:00 +0000422 auto* str = create<ast::Struct>(
423 ast::StructMemberList{Member("a", &ary, {MemberOffset(0)})},
424 ast::StructDecorationList{});
dan sinclairb5839932020-12-16 21:38:40 +0000425 auto* s = ty.struct_("Data", str);
dan sinclair336bb0b2021-01-18 21:06:34 +0000426 auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
Ben Claytonf12054e2021-01-21 16:15:00 +0000427 mod->AddGlobalVariable(coord_var);
428 td.RegisterVariableForTesting(coord_var);
429
dan sinclair8b40a672020-12-16 11:49:10 +0000430 auto* expr = IndexAccessor(MemberAccessor("data", "a"),
431 Sub(Add(Expr(2), Expr(4)), Expr(3)));
dan sinclairbdb86722020-08-25 21:22:37 +0000432
dan sinclair196e0972020-11-13 18:13:24 +0000433 ASSERT_TRUE(td.Determine()) << td.error();
Ben Clayton9df857d2020-12-15 14:11:48 +0000434 ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
dan sinclairbdb86722020-08-25 21:22:37 +0000435
Ben Claytonf12054e2021-01-21 16:15:00 +0000436 GeneratorImpl& gen = Build();
437
438 gen.register_global(coord_var);
439
Ben Clayton9df857d2020-12-15 14:11:48 +0000440 ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
dan sinclair987376c2021-01-12 04:34:53 +0000441 EXPECT_EQ(result(), "asint(data.Load((4 * ((2 + 4) - 3)) + 0))");
dan sinclairbdb86722020-08-25 21:22:37 +0000442}
443
dan sinclairdf503f02020-08-26 19:05:46 +0000444TEST_F(HlslGeneratorImplTest_MemberAccessor,
dan sinclairbdb86722020-08-25 21:22:37 +0000445 EmitExpression_MemberAccessor_StorageBuffer_Store) {
446 // struct Data {
dan sinclair8b685862020-09-20 19:14:28 +0000447 // [[offset(0)]] a : i32;
448 // [[offset(4)]] b : f32;
dan sinclairbdb86722020-08-25 21:22:37 +0000449 // };
dan sinclair336bb0b2021-01-18 21:06:34 +0000450 // var<storage> data : Data;
dan sinclairbdb86722020-08-25 21:22:37 +0000451 // data.b = 2.3f;
452 //
453 // -> data.Store(0, asuint(2.0f));
454
dan sinclair5e5e36e2020-12-16 14:41:00 +0000455 auto* str = create<ast::Struct>(
456 ast::StructMemberList{Member("a", ty.i32, {MemberOffset(0)}),
457 Member("b", ty.f32, {MemberOffset(4)})},
458 ast::StructDecorationList{});
dan sinclairbdb86722020-08-25 21:22:37 +0000459
dan sinclairb5839932020-12-16 21:38:40 +0000460 auto* s = ty.struct_("Data", str);
dan sinclair336bb0b2021-01-18 21:06:34 +0000461 auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
Ben Clayton9df857d2020-12-15 14:11:48 +0000462 mod->AddGlobalVariable(coord_var);
Ben Claytonf12054e2021-01-21 16:15:00 +0000463 td.RegisterVariableForTesting(coord_var);
dan sinclairbdb86722020-08-25 21:22:37 +0000464
dan sinclair8b40a672020-12-16 11:49:10 +0000465 auto* lhs = MemberAccessor("data", "b");
Ben Clayton9df857d2020-12-15 14:11:48 +0000466 auto* rhs = Expr(2.0f);
467 auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
dan sinclairbdb86722020-08-25 21:22:37 +0000468
Ben Claytonf12054e2021-01-21 16:15:00 +0000469 ASSERT_TRUE(td.Determine()) << td.error();
Ben Clayton9df857d2020-12-15 14:11:48 +0000470 ASSERT_TRUE(td.DetermineResultType(assign));
Ben Claytonf12054e2021-01-21 16:15:00 +0000471
472 GeneratorImpl& gen = Build();
473
474 gen.register_global(coord_var);
475
Ben Clayton9df857d2020-12-15 14:11:48 +0000476 ASSERT_TRUE(gen.EmitStatement(out, assign)) << gen.error();
dan sinclair987376c2021-01-12 04:34:53 +0000477 EXPECT_EQ(result(), R"(data.Store(4, asuint(2.0f));
dan sinclairbdb86722020-08-25 21:22:37 +0000478)");
479}
480
dan sinclairdf503f02020-08-26 19:05:46 +0000481TEST_F(HlslGeneratorImplTest_MemberAccessor,
dan sinclairbdb86722020-08-25 21:22:37 +0000482 EmitExpression_MemberAccessor_StorageBuffer_Store_ToArray) {
483 // struct Data {
dan sinclair077d16d2020-09-20 21:28:18 +0000484 // [[offset(0)]] a : [[stride(4)]] array<i32, 5>;
dan sinclairbdb86722020-08-25 21:22:37 +0000485 // };
dan sinclair336bb0b2021-01-18 21:06:34 +0000486 // var<storage> data : Data;
dan sinclairbdb86722020-08-25 21:22:37 +0000487 // data.a[2] = 2;
488 //
489 // -> data.Store((2 * 4), asuint(2.3f));
490
Ben Clayton207b5e22021-01-21 15:42:10 +0000491 type::Array ary(ty.i32, 5,
492 ast::ArrayDecorationList{
493 create<ast::StrideDecoration>(4),
494 });
dan sinclairbdb86722020-08-25 21:22:37 +0000495
dan sinclair5e5e36e2020-12-16 14:41:00 +0000496 auto* str = create<ast::Struct>(
497 ast::StructMemberList{Member("a", &ary, {MemberOffset(0)})},
498 ast::StructDecorationList{});
dan sinclairbdb86722020-08-25 21:22:37 +0000499
dan sinclairb5839932020-12-16 21:38:40 +0000500 auto* s = ty.struct_("Data", str);
dan sinclair336bb0b2021-01-18 21:06:34 +0000501 auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
Ben Clayton9df857d2020-12-15 14:11:48 +0000502 mod->AddGlobalVariable(coord_var);
Ben Claytonf12054e2021-01-21 16:15:00 +0000503 td.RegisterVariableForTesting(coord_var);
dan sinclairbdb86722020-08-25 21:22:37 +0000504
dan sinclair8b40a672020-12-16 11:49:10 +0000505 auto* lhs = IndexAccessor(MemberAccessor("data", "a"), Expr(2));
Ben Clayton9df857d2020-12-15 14:11:48 +0000506 auto* rhs = Expr(2);
507 auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
dan sinclairbdb86722020-08-25 21:22:37 +0000508
Ben Claytonf12054e2021-01-21 16:15:00 +0000509 ASSERT_TRUE(td.Determine()) << td.error();
Ben Clayton9df857d2020-12-15 14:11:48 +0000510 ASSERT_TRUE(td.DetermineResultType(assign)) << td.error();
Ben Claytonf12054e2021-01-21 16:15:00 +0000511
512 GeneratorImpl& gen = Build();
513
514 gen.register_global(coord_var);
515
Ben Clayton9df857d2020-12-15 14:11:48 +0000516 ASSERT_TRUE(gen.EmitStatement(out, assign)) << gen.error();
dan sinclair987376c2021-01-12 04:34:53 +0000517 EXPECT_EQ(result(), R"(data.Store((4 * 2) + 0, asuint(2));
dan sinclairbdb86722020-08-25 21:22:37 +0000518)");
519}
520
dan sinclairdf503f02020-08-26 19:05:46 +0000521TEST_F(HlslGeneratorImplTest_MemberAccessor,
dan sinclairbdb86722020-08-25 21:22:37 +0000522 EmitExpression_MemberAccessor_StorageBuffer_Store_Int) {
523 // struct Data {
dan sinclair8b685862020-09-20 19:14:28 +0000524 // [[offset(0)]] a : i32;
525 // [[offset(4)]] b : f32;
dan sinclairbdb86722020-08-25 21:22:37 +0000526 // };
dan sinclair336bb0b2021-01-18 21:06:34 +0000527 // var<storage> data : Data;
dan sinclairbdb86722020-08-25 21:22:37 +0000528 // data.a = 2;
529 //
530 // -> data.Store(0, asuint(2));
531
dan sinclair5e5e36e2020-12-16 14:41:00 +0000532 auto* str = create<ast::Struct>(
533 ast::StructMemberList{Member("a", ty.i32, {MemberOffset(0)}),
534 Member("b", ty.f32, {MemberOffset(4)})},
535 ast::StructDecorationList{});
dan sinclairbdb86722020-08-25 21:22:37 +0000536
dan sinclairb5839932020-12-16 21:38:40 +0000537 auto* s = ty.struct_("Data", str);
dan sinclair336bb0b2021-01-18 21:06:34 +0000538 auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
Ben Clayton9df857d2020-12-15 14:11:48 +0000539 mod->AddGlobalVariable(coord_var);
Ben Claytonf12054e2021-01-21 16:15:00 +0000540 td.RegisterVariableForTesting(coord_var);
dan sinclairbdb86722020-08-25 21:22:37 +0000541
dan sinclair8b40a672020-12-16 11:49:10 +0000542 auto* lhs = MemberAccessor("data", "a");
Ben Clayton9df857d2020-12-15 14:11:48 +0000543 auto* rhs = Expr(2);
544 auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
dan sinclairbdb86722020-08-25 21:22:37 +0000545
Ben Claytonf12054e2021-01-21 16:15:00 +0000546 ASSERT_TRUE(td.Determine()) << td.error();
Ben Clayton9df857d2020-12-15 14:11:48 +0000547 ASSERT_TRUE(td.DetermineResultType(assign));
Ben Claytonf12054e2021-01-21 16:15:00 +0000548
549 GeneratorImpl& gen = Build();
550
551 gen.register_global(coord_var);
552
Ben Clayton9df857d2020-12-15 14:11:48 +0000553 ASSERT_TRUE(gen.EmitStatement(out, assign)) << gen.error();
dan sinclair987376c2021-01-12 04:34:53 +0000554 EXPECT_EQ(result(), R"(data.Store(0, asuint(2));
dan sinclairbdb86722020-08-25 21:22:37 +0000555)");
556}
557
dan sinclairdf503f02020-08-26 19:05:46 +0000558TEST_F(HlslGeneratorImplTest_MemberAccessor,
dan sinclairbdb86722020-08-25 21:22:37 +0000559 EmitExpression_MemberAccessor_StorageBuffer_Load_Vec3) {
560 // struct Data {
dan sinclair8b685862020-09-20 19:14:28 +0000561 // [[offset(0)]] a : vec3<i32>;
562 // [[offset(16)]] b : vec3<f32>;
dan sinclairbdb86722020-08-25 21:22:37 +0000563 // };
dan sinclair336bb0b2021-01-18 21:06:34 +0000564 // var<storage> data : Data;
dan sinclairbdb86722020-08-25 21:22:37 +0000565 // data.b;
566 //
567 // -> asfloat(data.Load(16));
568
dan sinclair5e5e36e2020-12-16 14:41:00 +0000569 auto* str = create<ast::Struct>(
570 ast::StructMemberList{Member("a", ty.vec3<i32>(), {MemberOffset(0)}),
571 Member("b", ty.vec3<f32>(), {MemberOffset(16)})},
572 ast::StructDecorationList{});
dan sinclairbdb86722020-08-25 21:22:37 +0000573
dan sinclairb5839932020-12-16 21:38:40 +0000574 auto* s = ty.struct_("Data", str);
dan sinclair336bb0b2021-01-18 21:06:34 +0000575 auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
Ben Clayton9df857d2020-12-15 14:11:48 +0000576 mod->AddGlobalVariable(coord_var);
Ben Claytonf12054e2021-01-21 16:15:00 +0000577 td.RegisterVariableForTesting(coord_var);
dan sinclairbdb86722020-08-25 21:22:37 +0000578
dan sinclair8b40a672020-12-16 11:49:10 +0000579 auto* expr = MemberAccessor("data", "b");
dan sinclairbdb86722020-08-25 21:22:37 +0000580
Ben Claytonf12054e2021-01-21 16:15:00 +0000581 ASSERT_TRUE(td.Determine()) << td.error();
Ben Clayton9df857d2020-12-15 14:11:48 +0000582 ASSERT_TRUE(td.DetermineResultType(expr));
Ben Claytonf12054e2021-01-21 16:15:00 +0000583
584 GeneratorImpl& gen = Build();
585
586 gen.register_global(coord_var);
587
Ben Clayton9df857d2020-12-15 14:11:48 +0000588 ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
dan sinclair987376c2021-01-12 04:34:53 +0000589 EXPECT_EQ(result(), "asfloat(data.Load3(16))");
dan sinclairbdb86722020-08-25 21:22:37 +0000590}
591
dan sinclairdf503f02020-08-26 19:05:46 +0000592TEST_F(HlslGeneratorImplTest_MemberAccessor,
dan sinclairbdb86722020-08-25 21:22:37 +0000593 EmitExpression_MemberAccessor_StorageBuffer_Store_Vec3) {
594 // struct Data {
dan sinclair8b685862020-09-20 19:14:28 +0000595 // [[offset(0)]] a : vec3<i32>;
596 // [[offset(16)]] b : vec3<f32>;
dan sinclairbdb86722020-08-25 21:22:37 +0000597 // };
dan sinclair336bb0b2021-01-18 21:06:34 +0000598 // var<storage> data : Data;
dan sinclairbdb86722020-08-25 21:22:37 +0000599 // data.b = vec3<f32>(2.3f, 1.2f, 0.2f);
600 //
Ben Clayton31df1132020-11-19 16:49:12 +0000601 // -> data.Store(16, asuint(float3(2.3f, 1.2f, 0.2f)));
dan sinclairbdb86722020-08-25 21:22:37 +0000602
dan sinclair5e5e36e2020-12-16 14:41:00 +0000603 auto* str = create<ast::Struct>(
604 ast::StructMemberList{Member("a", ty.vec3<i32>(), {MemberOffset(0)}),
605 Member("b", ty.vec3<f32>(), {MemberOffset(16)})},
606 ast::StructDecorationList{});
dan sinclairbdb86722020-08-25 21:22:37 +0000607
dan sinclairb5839932020-12-16 21:38:40 +0000608 auto* s = ty.struct_("Data", str);
dan sinclair336bb0b2021-01-18 21:06:34 +0000609 auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
Ben Clayton9df857d2020-12-15 14:11:48 +0000610 mod->AddGlobalVariable(coord_var);
Ben Claytonf12054e2021-01-21 16:15:00 +0000611 td.RegisterVariableForTesting(coord_var);
dan sinclairbdb86722020-08-25 21:22:37 +0000612
dan sinclair8b40a672020-12-16 11:49:10 +0000613 auto* lhs = MemberAccessor("data", "b");
Ben Clayton9df857d2020-12-15 14:11:48 +0000614 auto* rhs = vec3<f32>(1.f, 2.f, 3.f);
dan sinclairbdb86722020-08-25 21:22:37 +0000615
Ben Clayton9df857d2020-12-15 14:11:48 +0000616 auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
dan sinclairbdb86722020-08-25 21:22:37 +0000617
Ben Claytonf12054e2021-01-21 16:15:00 +0000618 ASSERT_TRUE(td.Determine()) << td.error();
Ben Clayton9df857d2020-12-15 14:11:48 +0000619 ASSERT_TRUE(td.DetermineResultType(assign));
Ben Claytonf12054e2021-01-21 16:15:00 +0000620
621 GeneratorImpl& gen = Build();
622
623 gen.register_global(coord_var);
624
Ben Clayton9df857d2020-12-15 14:11:48 +0000625 ASSERT_TRUE(gen.EmitStatement(out, assign)) << gen.error();
Ben Clayton2da833d2020-11-20 10:04:44 +0000626 EXPECT_EQ(result(),
dan sinclair987376c2021-01-12 04:34:53 +0000627 R"(data.Store3(16, asuint(float3(1.0f, 2.0f, 3.0f)));
dan sinclairbdb86722020-08-25 21:22:37 +0000628)");
629}
630
dan sinclairdf503f02020-08-26 19:05:46 +0000631TEST_F(HlslGeneratorImplTest_MemberAccessor,
dan sinclairbdb86722020-08-25 21:22:37 +0000632 EmitExpression_MemberAccessor_StorageBuffer_Load_MultiLevel) {
633 // struct Data {
dan sinclair8b685862020-09-20 19:14:28 +0000634 // [[offset(0)]] a : vec3<i32>;
635 // [[offset(16)]] b : vec3<f32>;
dan sinclairbdb86722020-08-25 21:22:37 +0000636 // };
637 // struct Pre {
dan sinclair077d16d2020-09-20 21:28:18 +0000638 // var c : [[stride(32)]] array<Data, 4>;
dan sinclairbdb86722020-08-25 21:22:37 +0000639 // };
640 //
dan sinclair336bb0b2021-01-18 21:06:34 +0000641 // var<storage> data : Pre;
dan sinclairbdb86722020-08-25 21:22:37 +0000642 // data.c[2].b
643 //
644 // -> asfloat(data.Load3(16 + (2 * 32)))
645
Ben Claytonbcf37542020-12-12 12:52:44 +0000646 auto* data_str = create<ast::Struct>(
Ben Claytonbcf37542020-12-12 12:52:44 +0000647 ast::StructMemberList{
dan sinclair5e5e36e2020-12-16 14:41:00 +0000648 Member("a", ty.vec3<i32>(), {MemberOffset(0)}),
649 Member("b", ty.vec3<f32>(), {MemberOffset(16)}),
Ben Claytonbcf37542020-12-12 12:52:44 +0000650 },
651 ast::StructDecorationList{});
dan sinclairbdb86722020-08-25 21:22:37 +0000652
dan sinclairb5839932020-12-16 21:38:40 +0000653 auto* data = ty.struct_("Data", data_str);
Ben Clayton207b5e22021-01-21 15:42:10 +0000654 type::Array ary(data, 4,
655 ast::ArrayDecorationList{
656 create<ast::StrideDecoration>(32),
657 });
dan sinclairbdb86722020-08-25 21:22:37 +0000658
Ben Claytonbcf37542020-12-12 12:52:44 +0000659 auto* pre_str = create<ast::Struct>(
dan sinclair5e5e36e2020-12-16 14:41:00 +0000660 ast::StructMemberList{Member("c", &ary, {MemberOffset(0)})},
Ben Claytonbcf37542020-12-12 12:52:44 +0000661 ast::StructDecorationList{});
dan sinclairbdb86722020-08-25 21:22:37 +0000662
dan sinclairb5839932020-12-16 21:38:40 +0000663 auto* pre_struct = ty.struct_("Pre", pre_str);
dan sinclair336bb0b2021-01-18 21:06:34 +0000664 auto* coord_var = Var("data", ast::StorageClass::kStorage, pre_struct);
Ben Clayton9df857d2020-12-15 14:11:48 +0000665 mod->AddGlobalVariable(coord_var);
Ben Claytonf12054e2021-01-21 16:15:00 +0000666 td.RegisterVariableForTesting(coord_var);
dan sinclairbdb86722020-08-25 21:22:37 +0000667
dan sinclair8b40a672020-12-16 11:49:10 +0000668 auto* expr =
669 MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), Expr(2)), "b");
dan sinclairbdb86722020-08-25 21:22:37 +0000670
Ben Claytonf12054e2021-01-21 16:15:00 +0000671 ASSERT_TRUE(td.Determine()) << td.error();
Ben Clayton9df857d2020-12-15 14:11:48 +0000672 ASSERT_TRUE(td.DetermineResultType(expr));
Ben Claytonf12054e2021-01-21 16:15:00 +0000673
674 GeneratorImpl& gen = Build();
675
676 gen.register_global(coord_var);
677
Ben Clayton9df857d2020-12-15 14:11:48 +0000678 ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
dan sinclair987376c2021-01-12 04:34:53 +0000679 EXPECT_EQ(result(), "asfloat(data.Load3(16 + (32 * 2) + 0))");
dan sinclairbdb86722020-08-25 21:22:37 +0000680}
681
dan sinclairdf503f02020-08-26 19:05:46 +0000682TEST_F(HlslGeneratorImplTest_MemberAccessor,
dan sinclairbdb86722020-08-25 21:22:37 +0000683 EmitExpression_MemberAccessor_StorageBuffer_Load_MultiLevel_Swizzle) {
684 // struct Data {
dan sinclair8b685862020-09-20 19:14:28 +0000685 // [[offset(0)]] a : vec3<i32>;
686 // [[offset(16)]] b : vec3<f32>;
dan sinclairbdb86722020-08-25 21:22:37 +0000687 // };
688 // struct Pre {
dan sinclair077d16d2020-09-20 21:28:18 +0000689 // var c : [[stride(32)]] array<Data, 4>;
dan sinclairbdb86722020-08-25 21:22:37 +0000690 // };
691 //
dan sinclair336bb0b2021-01-18 21:06:34 +0000692 // var<storage> data : Pre;
dan sinclairbdb86722020-08-25 21:22:37 +0000693 // data.c[2].b.xy
694 //
695 // -> asfloat(data.Load3(16 + (2 * 32))).xy
696
Ben Claytonbcf37542020-12-12 12:52:44 +0000697 auto* data_str = create<ast::Struct>(
Ben Claytonbcf37542020-12-12 12:52:44 +0000698 ast::StructMemberList{
dan sinclair5e5e36e2020-12-16 14:41:00 +0000699 Member("a", ty.vec3<i32>(), {MemberOffset(0)}),
700 Member("b", ty.vec3<f32>(), {MemberOffset(16)}),
Ben Claytonbcf37542020-12-12 12:52:44 +0000701 },
702 ast::StructDecorationList{});
dan sinclairbdb86722020-08-25 21:22:37 +0000703
dan sinclairb5839932020-12-16 21:38:40 +0000704 auto* data = ty.struct_("Data", data_str);
Ben Clayton207b5e22021-01-21 15:42:10 +0000705 type::Array ary(data, 4,
706 ast::ArrayDecorationList{create<ast::StrideDecoration>(32)});
dan sinclairbdb86722020-08-25 21:22:37 +0000707
Ben Claytonbcf37542020-12-12 12:52:44 +0000708 auto* pre_str = create<ast::Struct>(
dan sinclair5e5e36e2020-12-16 14:41:00 +0000709 ast::StructMemberList{Member("c", &ary, {MemberOffset(0)})},
Ben Claytonbcf37542020-12-12 12:52:44 +0000710 ast::StructDecorationList{});
dan sinclairbdb86722020-08-25 21:22:37 +0000711
dan sinclairb5839932020-12-16 21:38:40 +0000712 auto* pre_struct = ty.struct_("Pre", pre_str);
dan sinclair336bb0b2021-01-18 21:06:34 +0000713 auto* coord_var = Var("data", ast::StorageClass::kStorage, pre_struct);
Ben Clayton9df857d2020-12-15 14:11:48 +0000714 mod->AddGlobalVariable(coord_var);
dan sinclairbdb86722020-08-25 21:22:37 +0000715
Ben Claytonf12054e2021-01-21 16:15:00 +0000716 td.RegisterVariableForTesting(coord_var);
dan sinclairbdb86722020-08-25 21:22:37 +0000717
dan sinclair8b40a672020-12-16 11:49:10 +0000718 auto* expr = MemberAccessor(
719 MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), Expr(2)), "b"),
720 "xy");
dan sinclairbdb86722020-08-25 21:22:37 +0000721
Ben Claytonf12054e2021-01-21 16:15:00 +0000722 ASSERT_TRUE(td.Determine()) << td.error();
Ben Clayton9df857d2020-12-15 14:11:48 +0000723 ASSERT_TRUE(td.DetermineResultType(expr));
Ben Claytonf12054e2021-01-21 16:15:00 +0000724
725 GeneratorImpl& gen = Build();
726
727 gen.register_global(coord_var);
728
Ben Clayton9df857d2020-12-15 14:11:48 +0000729 ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
dan sinclair987376c2021-01-12 04:34:53 +0000730 EXPECT_EQ(result(), "asfloat(data.Load3(16 + (32 * 2) + 0)).xy");
dan sinclairbdb86722020-08-25 21:22:37 +0000731}
732
733TEST_F(
dan sinclairdf503f02020-08-26 19:05:46 +0000734 HlslGeneratorImplTest_MemberAccessor,
dan sinclaird5fd7e02020-11-03 16:26:09 +0000735 EmitExpression_MemberAccessor_StorageBuffer_Load_MultiLevel_Swizzle_SingleLetter) { // NOLINT
dan sinclairbdb86722020-08-25 21:22:37 +0000736 // struct Data {
dan sinclair8b685862020-09-20 19:14:28 +0000737 // [[offset(0)]] a : vec3<i32>;
738 // [[offset(16)]] b : vec3<f32>;
dan sinclairbdb86722020-08-25 21:22:37 +0000739 // };
740 // struct Pre {
dan sinclair077d16d2020-09-20 21:28:18 +0000741 // var c : [[stride(32)]] array<Data, 4>;
dan sinclairbdb86722020-08-25 21:22:37 +0000742 // };
743 //
dan sinclair336bb0b2021-01-18 21:06:34 +0000744 // var<storage> data : Pre;
dan sinclairbdb86722020-08-25 21:22:37 +0000745 // data.c[2].b.g
746 //
747 // -> asfloat(data.Load((4 * 1) + 16 + (2 * 32) + 0))
748
Ben Claytonbcf37542020-12-12 12:52:44 +0000749 auto* data_str = create<ast::Struct>(
Ben Claytonbcf37542020-12-12 12:52:44 +0000750 ast::StructMemberList{
dan sinclair5e5e36e2020-12-16 14:41:00 +0000751 Member("a", ty.vec3<i32>(), {MemberOffset(0)}),
752 Member("b", ty.vec3<f32>(), {MemberOffset(16)}),
Ben Claytonbcf37542020-12-12 12:52:44 +0000753 },
754 ast::StructDecorationList{});
dan sinclairbdb86722020-08-25 21:22:37 +0000755
dan sinclairb5839932020-12-16 21:38:40 +0000756 auto* data = ty.struct_("Data", data_str);
Ben Clayton207b5e22021-01-21 15:42:10 +0000757 type::Array ary(data, 4,
758 ast::ArrayDecorationList{
759 create<ast::StrideDecoration>(32),
760 });
dan sinclairbdb86722020-08-25 21:22:37 +0000761
Ben Claytonbcf37542020-12-12 12:52:44 +0000762 auto* pre_str = create<ast::Struct>(
dan sinclair5e5e36e2020-12-16 14:41:00 +0000763 ast::StructMemberList{Member("c", &ary, {MemberOffset(0)})},
Ben Claytonbcf37542020-12-12 12:52:44 +0000764 ast::StructDecorationList{});
dan sinclairbdb86722020-08-25 21:22:37 +0000765
dan sinclairb5839932020-12-16 21:38:40 +0000766 auto* pre_struct = ty.struct_("Pre", pre_str);
dan sinclair336bb0b2021-01-18 21:06:34 +0000767 auto* coord_var = Var("data", ast::StorageClass::kStorage, pre_struct);
Ben Clayton9df857d2020-12-15 14:11:48 +0000768 mod->AddGlobalVariable(coord_var);
Ben Claytonf12054e2021-01-21 16:15:00 +0000769 td.RegisterVariableForTesting(coord_var);
dan sinclairbdb86722020-08-25 21:22:37 +0000770
dan sinclair8b40a672020-12-16 11:49:10 +0000771 auto* expr = MemberAccessor(
772 MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), Expr(2)), "b"),
773 "g");
dan sinclairbdb86722020-08-25 21:22:37 +0000774
Ben Claytonf12054e2021-01-21 16:15:00 +0000775 ASSERT_TRUE(td.Determine()) << td.error();
Ben Clayton9df857d2020-12-15 14:11:48 +0000776 ASSERT_TRUE(td.DetermineResultType(expr));
Ben Claytonf12054e2021-01-21 16:15:00 +0000777
778 GeneratorImpl& gen = Build();
779
780 gen.register_global(coord_var);
781
Ben Clayton9df857d2020-12-15 14:11:48 +0000782 ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
dan sinclair987376c2021-01-12 04:34:53 +0000783 EXPECT_EQ(result(), "asfloat(data.Load((4 * 1) + 16 + (32 * 2) + 0))");
dan sinclairbdb86722020-08-25 21:22:37 +0000784}
785
dan sinclairdf503f02020-08-26 19:05:46 +0000786TEST_F(HlslGeneratorImplTest_MemberAccessor,
dan sinclairbdb86722020-08-25 21:22:37 +0000787 EmitExpression_MemberAccessor_StorageBuffer_Load_MultiLevel_Index) {
788 // struct Data {
dan sinclair8b685862020-09-20 19:14:28 +0000789 // [[offset(0)]] a : vec3<i32>;
790 // [[offset(16)]] b : vec3<f32>;
dan sinclairbdb86722020-08-25 21:22:37 +0000791 // };
792 // struct Pre {
dan sinclair077d16d2020-09-20 21:28:18 +0000793 // var c : [[stride(32)]] array<Data, 4>;
dan sinclairbdb86722020-08-25 21:22:37 +0000794 // };
795 //
dan sinclair336bb0b2021-01-18 21:06:34 +0000796 // var<storage> data : Pre;
dan sinclairbdb86722020-08-25 21:22:37 +0000797 // data.c[2].b[1]
798 //
799 // -> asfloat(data.Load(4 + 16 + (2 * 32)))
800
Ben Claytonbcf37542020-12-12 12:52:44 +0000801 auto* data_str = create<ast::Struct>(
Ben Claytonbcf37542020-12-12 12:52:44 +0000802 ast::StructMemberList{
dan sinclair5e5e36e2020-12-16 14:41:00 +0000803 Member("a", ty.vec3<i32>(), {MemberOffset(0)}),
804 Member("b", ty.vec3<f32>(), {MemberOffset(16)}),
Ben Claytonbcf37542020-12-12 12:52:44 +0000805 },
806 ast::StructDecorationList{});
dan sinclairbdb86722020-08-25 21:22:37 +0000807
dan sinclairb5839932020-12-16 21:38:40 +0000808 auto* data = ty.struct_("Data", data_str);
Ben Clayton207b5e22021-01-21 15:42:10 +0000809 type::Array ary(data, 4,
810 ast::ArrayDecorationList{
811 create<ast::StrideDecoration>(32),
812 });
dan sinclairbdb86722020-08-25 21:22:37 +0000813
Ben Claytonbcf37542020-12-12 12:52:44 +0000814 auto* pre_str = create<ast::Struct>(
dan sinclair5e5e36e2020-12-16 14:41:00 +0000815 ast::StructMemberList{Member("c", &ary, {MemberOffset(0)})},
Ben Claytonbcf37542020-12-12 12:52:44 +0000816 ast::StructDecorationList{});
dan sinclairbdb86722020-08-25 21:22:37 +0000817
dan sinclairb5839932020-12-16 21:38:40 +0000818 auto* pre_struct = ty.struct_("Pre", pre_str);
dan sinclair336bb0b2021-01-18 21:06:34 +0000819 auto* coord_var = Var("data", ast::StorageClass::kStorage, pre_struct);
Ben Clayton9df857d2020-12-15 14:11:48 +0000820 mod->AddGlobalVariable(coord_var);
Ben Claytonf12054e2021-01-21 16:15:00 +0000821 td.RegisterVariableForTesting(coord_var);
dan sinclairbdb86722020-08-25 21:22:37 +0000822
dan sinclair8b40a672020-12-16 11:49:10 +0000823 auto* expr = IndexAccessor(
824 MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), Expr(2)), "b"),
825 Expr(1));
dan sinclairbdb86722020-08-25 21:22:37 +0000826
Ben Claytonf12054e2021-01-21 16:15:00 +0000827 ASSERT_TRUE(td.Determine()) << td.error();
Ben Clayton9df857d2020-12-15 14:11:48 +0000828 ASSERT_TRUE(td.DetermineResultType(expr));
Ben Claytonf12054e2021-01-21 16:15:00 +0000829
830 GeneratorImpl& gen = Build();
831
832 gen.register_global(coord_var);
833
Ben Clayton9df857d2020-12-15 14:11:48 +0000834 ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
dan sinclair987376c2021-01-12 04:34:53 +0000835 EXPECT_EQ(result(), "asfloat(data.Load((4 * 1) + 16 + (32 * 2) + 0))");
dan sinclairbdb86722020-08-25 21:22:37 +0000836}
837
dan sinclairdf503f02020-08-26 19:05:46 +0000838TEST_F(HlslGeneratorImplTest_MemberAccessor,
dan sinclairbdb86722020-08-25 21:22:37 +0000839 EmitExpression_MemberAccessor_StorageBuffer_Store_MultiLevel) {
840 // struct Data {
dan sinclair8b685862020-09-20 19:14:28 +0000841 // [[offset(0)]] a : vec3<i32>;
842 // [[offset(16)]] b : vec3<f32>;
dan sinclairbdb86722020-08-25 21:22:37 +0000843 // };
844 // struct Pre {
dan sinclair077d16d2020-09-20 21:28:18 +0000845 // var c : [[stride(32)]] array<Data, 4>;
dan sinclairbdb86722020-08-25 21:22:37 +0000846 // };
847 //
dan sinclair336bb0b2021-01-18 21:06:34 +0000848 // var<storage> data : Pre;
dan sinclairbdb86722020-08-25 21:22:37 +0000849 // data.c[2].b = vec3<f32>(1.f, 2.f, 3.f);
850 //
Ben Clayton31df1132020-11-19 16:49:12 +0000851 // -> data.Store3(16 + (2 * 32), asuint(float3(1.0f, 2.0f, 3.0f)));
dan sinclairbdb86722020-08-25 21:22:37 +0000852
Ben Claytonbcf37542020-12-12 12:52:44 +0000853 auto* data_str = create<ast::Struct>(
Ben Claytonbcf37542020-12-12 12:52:44 +0000854 ast::StructMemberList{
dan sinclair5e5e36e2020-12-16 14:41:00 +0000855 Member("a", ty.vec3<i32>(), {MemberOffset(0)}),
856 Member("b", ty.vec3<f32>(), {MemberOffset(16)}),
Ben Claytonbcf37542020-12-12 12:52:44 +0000857 },
858 ast::StructDecorationList{});
dan sinclairbdb86722020-08-25 21:22:37 +0000859
dan sinclairb5839932020-12-16 21:38:40 +0000860 auto* data = ty.struct_("Data", data_str);
Ben Clayton207b5e22021-01-21 15:42:10 +0000861 type::Array ary(data, 4,
862 ast::ArrayDecorationList{
863 create<ast::StrideDecoration>(32),
864 });
dan sinclairbdb86722020-08-25 21:22:37 +0000865
Ben Claytonbcf37542020-12-12 12:52:44 +0000866 auto* pre_str = create<ast::Struct>(
dan sinclair5e5e36e2020-12-16 14:41:00 +0000867 ast::StructMemberList{Member("c", &ary, {MemberOffset(0)})},
Ben Claytonbcf37542020-12-12 12:52:44 +0000868 ast::StructDecorationList{});
dan sinclairbdb86722020-08-25 21:22:37 +0000869
dan sinclairb5839932020-12-16 21:38:40 +0000870 auto* pre_struct = ty.struct_("Pre", pre_str);
dan sinclair336bb0b2021-01-18 21:06:34 +0000871 auto* coord_var = Var("data", ast::StorageClass::kStorage, pre_struct);
Ben Clayton9df857d2020-12-15 14:11:48 +0000872 mod->AddGlobalVariable(coord_var);
Ben Claytonf12054e2021-01-21 16:15:00 +0000873 td.RegisterVariableForTesting(coord_var);
dan sinclairbdb86722020-08-25 21:22:37 +0000874
dan sinclair8b40a672020-12-16 11:49:10 +0000875 auto* lhs =
876 MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), Expr(2)), "b");
dan sinclairbdb86722020-08-25 21:22:37 +0000877
Ben Clayton9df857d2020-12-15 14:11:48 +0000878 auto* assign =
879 create<ast::AssignmentStatement>(lhs, vec3<f32>(1.f, 2.f, 3.f));
dan sinclairbdb86722020-08-25 21:22:37 +0000880
Ben Claytonf12054e2021-01-21 16:15:00 +0000881 ASSERT_TRUE(td.Determine()) << td.error();
Ben Clayton9df857d2020-12-15 14:11:48 +0000882 ASSERT_TRUE(td.DetermineResultType(assign));
Ben Claytonf12054e2021-01-21 16:15:00 +0000883
884 GeneratorImpl& gen = Build();
885
886 gen.register_global(coord_var);
887
Ben Clayton9df857d2020-12-15 14:11:48 +0000888 ASSERT_TRUE(gen.EmitStatement(out, assign)) << gen.error();
dan sinclair987376c2021-01-12 04:34:53 +0000889 EXPECT_EQ(result(),
890 R"(data.Store3(16 + (32 * 2) + 0, asuint(float3(1.0f, 2.0f, 3.0f)));
dan sinclairbdb86722020-08-25 21:22:37 +0000891)");
892}
893
dan sinclairdf503f02020-08-26 19:05:46 +0000894TEST_F(HlslGeneratorImplTest_MemberAccessor,
dan sinclairbdb86722020-08-25 21:22:37 +0000895 EmitExpression_MemberAccessor_StorageBuffer_Store_Swizzle_SingleLetter) {
896 // struct Data {
dan sinclair8b685862020-09-20 19:14:28 +0000897 // [[offset(0)]] a : vec3<i32>;
898 // [[offset(16)]] b : vec3<f32>;
dan sinclairbdb86722020-08-25 21:22:37 +0000899 // };
900 // struct Pre {
dan sinclair077d16d2020-09-20 21:28:18 +0000901 // var c : [[stride(32)]] array<Data, 4>;
dan sinclairbdb86722020-08-25 21:22:37 +0000902 // };
903 //
dan sinclair336bb0b2021-01-18 21:06:34 +0000904 // var<storage> data : Pre;
dan sinclairbdb86722020-08-25 21:22:37 +0000905 // data.c[2].b.y = 1.f;
906 //
907 // -> data.Store((4 * 1) + 16 + (2 * 32) + 0, asuint(1.0f));
908
Ben Claytonbcf37542020-12-12 12:52:44 +0000909 auto* data_str = create<ast::Struct>(
Ben Claytonbcf37542020-12-12 12:52:44 +0000910 ast::StructMemberList{
dan sinclair5e5e36e2020-12-16 14:41:00 +0000911 Member("a", ty.vec3<i32>(), {MemberOffset(0)}),
912 Member("b", ty.vec3<f32>(), {MemberOffset(16)}),
Ben Claytonbcf37542020-12-12 12:52:44 +0000913 },
914 ast::StructDecorationList{});
dan sinclairbdb86722020-08-25 21:22:37 +0000915
dan sinclairb5839932020-12-16 21:38:40 +0000916 auto* data = ty.struct_("Data", data_str);
Ben Clayton207b5e22021-01-21 15:42:10 +0000917 type::Array ary(data, 4,
918 ast::ArrayDecorationList{
919 create<ast::StrideDecoration>(32),
920 });
dan sinclairbdb86722020-08-25 21:22:37 +0000921
Ben Claytonbcf37542020-12-12 12:52:44 +0000922 auto* pre_str = create<ast::Struct>(
dan sinclair5e5e36e2020-12-16 14:41:00 +0000923 ast::StructMemberList{Member("c", &ary, {MemberOffset(0)})},
Ben Claytonbcf37542020-12-12 12:52:44 +0000924 ast::StructDecorationList{});
dan sinclairbdb86722020-08-25 21:22:37 +0000925
dan sinclairb5839932020-12-16 21:38:40 +0000926 auto* pre_struct = ty.struct_("Pre", pre_str);
dan sinclair336bb0b2021-01-18 21:06:34 +0000927 auto* coord_var = Var("data", ast::StorageClass::kStorage, pre_struct);
Ben Clayton9df857d2020-12-15 14:11:48 +0000928 mod->AddGlobalVariable(coord_var);
Ben Claytonf12054e2021-01-21 16:15:00 +0000929 td.RegisterVariableForTesting(coord_var);
dan sinclairbdb86722020-08-25 21:22:37 +0000930
dan sinclair8b40a672020-12-16 11:49:10 +0000931 auto* lhs = MemberAccessor(
932 MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), Expr(2)), "b"),
933 "y");
Ben Clayton9df857d2020-12-15 14:11:48 +0000934 auto* rhs = Expr(1.f);
dan sinclairbdb86722020-08-25 21:22:37 +0000935
Ben Clayton9df857d2020-12-15 14:11:48 +0000936 auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
dan sinclairbdb86722020-08-25 21:22:37 +0000937
Ben Claytonf12054e2021-01-21 16:15:00 +0000938 ASSERT_TRUE(td.Determine()) << td.error();
Ben Clayton9df857d2020-12-15 14:11:48 +0000939 ASSERT_TRUE(td.DetermineResultType(assign));
Ben Claytonf12054e2021-01-21 16:15:00 +0000940
941 GeneratorImpl& gen = Build();
942
943 gen.register_global(coord_var);
944
Ben Clayton9df857d2020-12-15 14:11:48 +0000945 ASSERT_TRUE(gen.EmitStatement(out, assign)) << gen.error();
dan sinclairdf503f02020-08-26 19:05:46 +0000946 EXPECT_EQ(result(),
dan sinclair987376c2021-01-12 04:34:53 +0000947 R"(data.Store((4 * 1) + 16 + (32 * 2) + 0, asuint(1.0f));
dan sinclairbdb86722020-08-25 21:22:37 +0000948)");
949}
950
dan sinclairf9618502020-07-29 19:12:19 +0000951} // namespace
952} // namespace hlsl
953} // namespace writer
954} // namespace tint