writer/hlsl: Generate padding for UBO padded structs
Combined with the new PadArrayElements transform, arrays with strides are now correctly emitted. Fixed: tint:182 Fixed: tint:895 Change-Id: I26a1be94dee6e4c9d9747c8317a932fc1fb3c810 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/54640 Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: James Price <jrprice@google.com>
This commit is contained in:
parent
31936f375f
commit
d47eb3a965
|
@ -14,6 +14,8 @@
|
|||
|
||||
#include "src/writer/hlsl/generator_impl.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iomanip>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
|
@ -1343,7 +1345,11 @@ bool GeneratorImpl::EmitTypeConstructor(std::ostream& pre,
|
|||
type->is_scalar_vector() && expr->values().size() == 1 &&
|
||||
TypeOf(expr->values()[0])->is_scalar();
|
||||
|
||||
if (brackets) {
|
||||
auto it = structure_builders_.find(As<sem::Struct>(type));
|
||||
if (it != structure_builders_.end()) {
|
||||
out << it->second << "(";
|
||||
brackets = false;
|
||||
} else if (brackets) {
|
||||
out << "{";
|
||||
} else {
|
||||
if (!EmitType(out, type, ast::StorageClass::kNone, ast::Access::kReadWrite,
|
||||
|
@ -1904,7 +1910,13 @@ bool GeneratorImpl::EmitZeroValue(std::ostream& out, const sem::Type* type) {
|
|||
}
|
||||
}
|
||||
} else if (auto* str = type->As<sem::Struct>()) {
|
||||
out << "{";
|
||||
auto it = structure_builders_.find(str);
|
||||
if (it != structure_builders_.end()) {
|
||||
out << it->second << "(";
|
||||
} else {
|
||||
out << "{";
|
||||
}
|
||||
|
||||
bool first = true;
|
||||
for (auto* member : str->Members()) {
|
||||
if (!first) {
|
||||
|
@ -1915,7 +1927,8 @@ bool GeneratorImpl::EmitZeroValue(std::ostream& out, const sem::Type* type) {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
out << "}";
|
||||
|
||||
out << (it != structure_builders_.end() ? ")" : "}");
|
||||
} else if (auto* arr = type->As<sem::Array>()) {
|
||||
out << "{";
|
||||
auto* elem = arr->ElemType();
|
||||
|
@ -2244,23 +2257,75 @@ bool GeneratorImpl::EmitStructType(std::ostream& out, const sem::Struct* str) {
|
|||
return true;
|
||||
}
|
||||
|
||||
auto name = builder_.Symbols().NameFor(str->Declaration()->name());
|
||||
out << "struct " << name << " {" << std::endl;
|
||||
bool is_host_shareable = str->IsHostShareable();
|
||||
uint32_t hlsl_offset = 0;
|
||||
|
||||
// Emits a `/* 0xnnnn */` byte offset comment for a struct member.
|
||||
auto add_byte_offset_comment = [&](uint32_t offset) {
|
||||
std::ios_base::fmtflags saved_flag_state(out.flags());
|
||||
out << "/* 0x" << std::hex << std::setfill('0') << std::setw(4) << offset
|
||||
<< " */ ";
|
||||
out.flags(saved_flag_state);
|
||||
};
|
||||
|
||||
uint32_t pad_count = 0;
|
||||
auto add_padding = [&](uint32_t size) {
|
||||
if (size & 3) {
|
||||
TINT_ICE(builder_.Diagnostics())
|
||||
<< "attempting to pad field with " << size
|
||||
<< " bytes, but we require a multiple of 4 bytes";
|
||||
return false;
|
||||
}
|
||||
std::string name;
|
||||
do {
|
||||
name = "tint_pad_" + std::to_string(pad_count++);
|
||||
} while (str->FindMember(builder_.Symbols().Get(name)));
|
||||
|
||||
out << "int " << name << "[" << (size / 4) << "];" << std::endl;
|
||||
return true;
|
||||
};
|
||||
|
||||
auto struct_name = builder_.Symbols().NameFor(str->Declaration()->name());
|
||||
out << "struct " << struct_name << " {" << std::endl;
|
||||
|
||||
increment_indent();
|
||||
for (auto* mem : str->Members()) {
|
||||
make_indent(out);
|
||||
// TODO(dsinclair): Handle [[offset]] annotation on structs
|
||||
// https://bugs.chromium.org/p/tint/issues/detail?id=184
|
||||
|
||||
auto mem_name = builder_.Symbols().NameFor(mem->Declaration()->symbol());
|
||||
if (!EmitType(out, mem->Type(), ast::StorageClass::kNone,
|
||||
ast::Access::kReadWrite, mem_name)) {
|
||||
auto name = builder_.Symbols().NameFor(mem->Declaration()->symbol());
|
||||
auto wgsl_offset = mem->Offset();
|
||||
|
||||
if (is_host_shareable) {
|
||||
if (wgsl_offset < hlsl_offset) {
|
||||
// Unimplementable layout
|
||||
TINT_ICE(diagnostics_)
|
||||
<< "Structure member WGSL offset (" << wgsl_offset
|
||||
<< ") is behind HLSL offset (" << hlsl_offset << ")";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Generate padding if required
|
||||
if (auto padding = wgsl_offset - hlsl_offset) {
|
||||
add_byte_offset_comment(hlsl_offset);
|
||||
if (!add_padding(padding)) {
|
||||
return false;
|
||||
}
|
||||
hlsl_offset += padding;
|
||||
make_indent(out);
|
||||
}
|
||||
|
||||
add_byte_offset_comment(hlsl_offset);
|
||||
}
|
||||
|
||||
auto* ty = mem->Type();
|
||||
|
||||
if (!EmitType(out, ty, ast::StorageClass::kNone, ast::Access::kReadWrite,
|
||||
name)) {
|
||||
return false;
|
||||
}
|
||||
// Array member name will be output with the type
|
||||
if (!mem->Type()->Is<sem::Array>()) {
|
||||
out << " " << mem_name;
|
||||
if (!ty->Is<sem::Array>()) {
|
||||
out << " " << name;
|
||||
}
|
||||
|
||||
for (auto* deco : mem->Declaration()->decorations()) {
|
||||
|
@ -2295,12 +2360,84 @@ bool GeneratorImpl::EmitStructType(std::ostream& out, const sem::Struct* str) {
|
|||
}
|
||||
|
||||
out << ";" << std::endl;
|
||||
|
||||
if (is_host_shareable) {
|
||||
// Calculate new HLSL offset
|
||||
auto size_align = HlslPackedTypeSizeAndAlign(ty);
|
||||
if (hlsl_offset % size_align.align) {
|
||||
TINT_ICE(diagnostics_)
|
||||
<< "Misaligned HLSL structure member "
|
||||
<< ty->FriendlyName(builder_.Symbols()) << " " << name;
|
||||
return false;
|
||||
}
|
||||
hlsl_offset += size_align.size;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_host_shareable && str->Size() != hlsl_offset) {
|
||||
make_indent(out);
|
||||
add_byte_offset_comment(hlsl_offset);
|
||||
if (!add_padding(str->Size() - hlsl_offset)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
decrement_indent();
|
||||
make_indent(out);
|
||||
|
||||
out << "};" << std::endl;
|
||||
|
||||
// If the structure has padding members, create a helper function for building
|
||||
// the structure.
|
||||
if (pad_count) {
|
||||
auto builder_name = generate_name("make_" + struct_name);
|
||||
|
||||
out << std::endl;
|
||||
out << struct_name << " " << builder_name << "(";
|
||||
uint32_t idx = 0;
|
||||
for (auto* mem : str->Members()) {
|
||||
if (idx > 0) {
|
||||
out << ",";
|
||||
make_indent(out << std::endl);
|
||||
out << std::string(struct_name.length() + builder_name.length() + 2,
|
||||
' ');
|
||||
}
|
||||
auto name = "param_" + std::to_string(idx++);
|
||||
auto* ty = mem->Type();
|
||||
if (!EmitType(out, ty, ast::StorageClass::kNone, ast::Access::kReadWrite,
|
||||
name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Array member name will be output with the type
|
||||
if (!ty->Is<sem::Array>()) {
|
||||
out << " " << name;
|
||||
}
|
||||
}
|
||||
out << ") {";
|
||||
increment_indent();
|
||||
make_indent(out << std::endl);
|
||||
|
||||
out << struct_name << " output;";
|
||||
make_indent(out << std::endl);
|
||||
idx = 0;
|
||||
for (auto* mem : str->Members()) {
|
||||
out << "output."
|
||||
<< builder_.Symbols().NameFor(mem->Declaration()->symbol()) << " = "
|
||||
<< "param_" + std::to_string(idx++) << ";";
|
||||
make_indent(out << std::endl);
|
||||
}
|
||||
out << "return output;";
|
||||
|
||||
decrement_indent();
|
||||
make_indent(out << std::endl);
|
||||
out << "}";
|
||||
|
||||
make_indent(out << std::endl);
|
||||
|
||||
structure_builders_[str] = builder_name;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2469,6 +2606,63 @@ bool GeneratorImpl::EmitBlockBraces(std::ostream& out,
|
|||
return true;
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-packing-rules
|
||||
// TODO(crbug.com/tint/898): We need CTS and / or Dawn e2e tests for this logic.
|
||||
GeneratorImpl::SizeAndAlign GeneratorImpl::HlslPackedTypeSizeAndAlign(
|
||||
const sem::Type* ty) {
|
||||
if (ty->IsAnyOf<sem::U32, sem::I32, sem::F32>()) {
|
||||
return {4, 4};
|
||||
}
|
||||
|
||||
if (auto* vec = ty->As<sem::Vector>()) {
|
||||
auto num_els = vec->size();
|
||||
auto* el_ty = vec->type();
|
||||
if (el_ty->IsAnyOf<sem::U32, sem::I32, sem::F32>()) {
|
||||
return SizeAndAlign{num_els * 4, 4};
|
||||
}
|
||||
}
|
||||
|
||||
if (auto* mat = ty->As<sem::Matrix>()) {
|
||||
auto cols = mat->columns();
|
||||
auto rows = mat->rows();
|
||||
auto* el_ty = mat->type();
|
||||
if (el_ty->IsAnyOf<sem::U32, sem::I32, sem::F32>()) {
|
||||
static constexpr SizeAndAlign table[] = {
|
||||
/* float2x2 */ {16, 8},
|
||||
/* float2x3 */ {32, 16},
|
||||
/* float2x4 */ {32, 16},
|
||||
/* float3x2 */ {24, 8},
|
||||
/* float3x3 */ {48, 16},
|
||||
/* float3x4 */ {48, 16},
|
||||
/* float4x2 */ {32, 8},
|
||||
/* float4x3 */ {64, 16},
|
||||
/* float4x4 */ {64, 16},
|
||||
};
|
||||
if (cols >= 2 && cols <= 4 && rows >= 2 && rows <= 4) {
|
||||
return table[(3 * (cols - 2)) + (rows - 2)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (auto* arr = ty->As<sem::Array>()) {
|
||||
auto el_size_align = HlslPackedTypeSizeAndAlign(arr->ElemType());
|
||||
if (!arr->IsStrideImplicit()) {
|
||||
TINT_ICE(diagnostics_) << "arrays with explicit strides should have "
|
||||
"removed with the PadArrayElements transform";
|
||||
return {};
|
||||
}
|
||||
auto num_els = std::max<uint32_t>(arr->Count(), 1);
|
||||
return SizeAndAlign{el_size_align.size * num_els, el_size_align.align};
|
||||
}
|
||||
|
||||
if (auto* str = ty->As<sem::Struct>()) {
|
||||
return SizeAndAlign{str->Size(), str->Align()};
|
||||
}
|
||||
|
||||
TINT_UNREACHABLE(diagnostics_) << "Unhandled type " << ty->TypeInfo().name;
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace hlsl
|
||||
} // namespace writer
|
||||
} // namespace tint
|
||||
|
|
|
@ -426,8 +426,19 @@ class GeneratorImpl : public TextGenerator {
|
|||
return EmitBlockBraces(out, "", std::forward<F>(cb));
|
||||
}
|
||||
|
||||
// A pair of byte size and alignment `uint32_t`s.
|
||||
struct SizeAndAlign {
|
||||
uint32_t size;
|
||||
uint32_t align;
|
||||
};
|
||||
|
||||
/// @returns the HLSL packed type size and alignment in bytes for the given
|
||||
/// type.
|
||||
SizeAndAlign HlslPackedTypeSizeAndAlign(const sem::Type* ty);
|
||||
|
||||
ProgramBuilder builder_;
|
||||
std::function<bool(std::ostream& out)> emit_continuing_;
|
||||
std::unordered_map<const sem::Struct*, std::string> structure_builders_;
|
||||
};
|
||||
|
||||
} // namespace hlsl
|
||||
|
|
|
@ -342,7 +342,7 @@ TEST_F(HlslGeneratorImplTest_Function,
|
|||
|
||||
ASSERT_TRUE(gen.Generate(out)) << gen.error();
|
||||
EXPECT_EQ(result(), R"(struct UBO {
|
||||
float4 coord;
|
||||
/* 0x0000 */ float4 coord;
|
||||
};
|
||||
|
||||
ConstantBuffer<UBO> ubo : register(b0, space1);
|
||||
|
@ -385,7 +385,7 @@ TEST_F(HlslGeneratorImplTest_Function,
|
|||
|
||||
ASSERT_TRUE(gen.Generate(out)) << gen.error();
|
||||
EXPECT_EQ(result(), R"(struct Uniforms {
|
||||
float4 coord;
|
||||
/* 0x0000 */ float4 coord;
|
||||
};
|
||||
|
||||
ConstantBuffer<Uniforms> uniforms : register(b0, space1);
|
||||
|
@ -584,7 +584,7 @@ TEST_F(HlslGeneratorImplTest_Function,
|
|||
|
||||
ASSERT_TRUE(gen.Generate(out)) << gen.error();
|
||||
EXPECT_EQ(result(), R"(struct S {
|
||||
float x;
|
||||
/* 0x0000 */ float x;
|
||||
};
|
||||
|
||||
ConstantBuffer<S> coord : register(b0, space1);
|
||||
|
|
|
@ -93,16 +93,29 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_Array_WithoutName) {
|
|||
EXPECT_EQ(result(), "bool[4]");
|
||||
}
|
||||
|
||||
TEST_F(HlslGeneratorImplTest_Type, DISABLED_EmitType_RuntimeArray) {
|
||||
auto* arr = ty.array<bool>();
|
||||
Global("G", arr, ast::StorageClass::kPrivate);
|
||||
TEST_F(HlslGeneratorImplTest_Type, EmitType_ArrayWithStride) {
|
||||
auto* s = Structure("s", {Member("arr", ty.array<f32, 4>(64))},
|
||||
{create<ast::StructBlockDecoration>()});
|
||||
auto* ubo = Global("ubo", ty.Of(s), ast::StorageClass::kUniform,
|
||||
ast::DecorationList{
|
||||
create<ast::GroupDecoration>(1),
|
||||
create<ast::BindingDecoration>(1),
|
||||
});
|
||||
WrapInFunction(MemberAccessor(ubo, "arr"));
|
||||
|
||||
GeneratorImpl& gen = Build();
|
||||
GeneratorImpl& gen = SanitizeAndBuild();
|
||||
|
||||
ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), ast::StorageClass::kNone,
|
||||
ast::Access::kReadWrite, "ary"))
|
||||
<< gen.error();
|
||||
EXPECT_EQ(result(), "bool ary[]");
|
||||
ASSERT_TRUE(gen.Generate(out)) << gen.error();
|
||||
EXPECT_THAT(result(), HasSubstr(R"(struct tint_padded_array_element {
|
||||
/* 0x0000 */ float el;
|
||||
/* 0x0004 */ int tint_pad_0[15];
|
||||
};)"));
|
||||
EXPECT_THAT(result(), HasSubstr(R"(struct tint_array_wrapper {
|
||||
/* 0x0000 */ tint_padded_array_element arr[4];
|
||||
};)"));
|
||||
EXPECT_THAT(result(), HasSubstr(R"(struct s {
|
||||
/* 0x0000 */ tint_array_wrapper arr;
|
||||
};)"));
|
||||
}
|
||||
|
||||
TEST_F(HlslGeneratorImplTest_Type, EmitType_Bool) {
|
||||
|
@ -219,31 +232,427 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_Struct) {
|
|||
EXPECT_EQ(result(), "S");
|
||||
}
|
||||
|
||||
/// TODO(bclayton): Enable this, fix it, add tests for vector, matrix, array and
|
||||
/// nested structures.
|
||||
TEST_F(HlslGeneratorImplTest_Type, DISABLED_EmitType_Struct_InjectPadding) {
|
||||
auto* s = Structure(
|
||||
"S", {
|
||||
Member("a", ty.i32(), {MemberSize(32)}),
|
||||
Member("b", ty.f32()),
|
||||
Member("c", ty.f32(), {MemberAlign(128), MemberSize(128)}),
|
||||
});
|
||||
Global("g", ty.Of(s), ast::StorageClass::kPrivate);
|
||||
TEST_F(HlslGeneratorImplTest_Type, EmitType_Struct_Layout_NonComposites) {
|
||||
auto* s =
|
||||
Structure("S",
|
||||
{
|
||||
Member("a", ty.i32(), {MemberSize(32)}),
|
||||
Member("b", ty.f32(), {MemberAlign(128), MemberSize(128)}),
|
||||
Member("c", ty.vec2<f32>()),
|
||||
Member("d", ty.u32()),
|
||||
Member("e", ty.vec3<f32>()),
|
||||
Member("f", ty.u32()),
|
||||
Member("g", ty.vec4<f32>()),
|
||||
Member("h", ty.u32()),
|
||||
Member("i", ty.mat2x2<f32>()),
|
||||
Member("j", ty.u32()),
|
||||
Member("k", ty.mat2x3<f32>()),
|
||||
Member("l", ty.u32()),
|
||||
Member("m", ty.mat2x4<f32>()),
|
||||
Member("n", ty.u32()),
|
||||
Member("o", ty.mat3x2<f32>()),
|
||||
Member("p", ty.u32()),
|
||||
Member("q", ty.mat3x3<f32>()),
|
||||
Member("r", ty.u32()),
|
||||
Member("s", ty.mat3x4<f32>()),
|
||||
Member("t", ty.u32()),
|
||||
Member("u", ty.mat4x2<f32>()),
|
||||
Member("v", ty.u32()),
|
||||
Member("w", ty.mat4x3<f32>()),
|
||||
Member("x", ty.u32()),
|
||||
Member("y", ty.mat4x4<f32>()),
|
||||
Member("z", ty.f32()),
|
||||
},
|
||||
{create<ast::StructBlockDecoration>()});
|
||||
|
||||
Global("G", ty.Of(s), ast::StorageClass::kUniform,
|
||||
ast::DecorationList{
|
||||
create<ast::BindingDecoration>(0),
|
||||
create<ast::GroupDecoration>(0),
|
||||
});
|
||||
|
||||
GeneratorImpl& gen = Build();
|
||||
|
||||
auto* sem_s = program->TypeOf(s)->As<sem::Struct>();
|
||||
ASSERT_TRUE(gen.EmitType(out, sem_s, ast::StorageClass::kNone,
|
||||
ast::Access::kReadWrite, ""))
|
||||
<< gen.error();
|
||||
EXPECT_EQ(gen.result(), R"(struct S {
|
||||
int a;
|
||||
int8_t pad_0[28];
|
||||
float b;
|
||||
int8_t pad_1[92];
|
||||
float c;
|
||||
int8_t pad_2[124];
|
||||
ASSERT_TRUE(gen.EmitStructType(out, sem_s)) << gen.error();
|
||||
|
||||
auto* expect = R"(struct S {
|
||||
/* 0x0000 */ int a;
|
||||
/* 0x0004 */ int tint_pad_0[31];
|
||||
/* 0x0080 */ float b;
|
||||
/* 0x0084 */ int tint_pad_1[31];
|
||||
/* 0x0100 */ float2 c;
|
||||
/* 0x0108 */ uint d;
|
||||
/* 0x010c */ int tint_pad_2[1];
|
||||
/* 0x0110 */ float3 e;
|
||||
/* 0x011c */ uint f;
|
||||
/* 0x0120 */ float4 g;
|
||||
/* 0x0130 */ uint h;
|
||||
/* 0x0134 */ int tint_pad_3[1];
|
||||
/* 0x0138 */ float2x2 i;
|
||||
/* 0x0148 */ uint j;
|
||||
/* 0x014c */ int tint_pad_4[1];
|
||||
/* 0x0150 */ float2x3 k;
|
||||
/* 0x0170 */ uint l;
|
||||
/* 0x0174 */ int tint_pad_5[3];
|
||||
/* 0x0180 */ float2x4 m;
|
||||
/* 0x01a0 */ uint n;
|
||||
/* 0x01a4 */ int tint_pad_6[1];
|
||||
/* 0x01a8 */ float3x2 o;
|
||||
/* 0x01c0 */ uint p;
|
||||
/* 0x01c4 */ int tint_pad_7[3];
|
||||
/* 0x01d0 */ float3x3 q;
|
||||
/* 0x0200 */ uint r;
|
||||
/* 0x0204 */ int tint_pad_8[3];
|
||||
/* 0x0210 */ float3x4 s;
|
||||
/* 0x0240 */ uint t;
|
||||
/* 0x0244 */ int tint_pad_9[1];
|
||||
/* 0x0248 */ float4x2 u;
|
||||
/* 0x0268 */ uint v;
|
||||
/* 0x026c */ int tint_pad_10[1];
|
||||
/* 0x0270 */ float4x3 w;
|
||||
/* 0x02b0 */ uint x;
|
||||
/* 0x02b4 */ int tint_pad_11[3];
|
||||
/* 0x02c0 */ float4x4 y;
|
||||
/* 0x0300 */ float z;
|
||||
/* 0x0304 */ int tint_pad_12[31];
|
||||
};
|
||||
|
||||
S make_S(int param_0,
|
||||
float param_1,
|
||||
float2 param_2,
|
||||
uint param_3,
|
||||
float3 param_4,
|
||||
uint param_5,
|
||||
float4 param_6,
|
||||
uint param_7,
|
||||
float2x2 param_8,
|
||||
uint param_9,
|
||||
float2x3 param_10,
|
||||
uint param_11,
|
||||
float2x4 param_12,
|
||||
uint param_13,
|
||||
float3x2 param_14,
|
||||
uint param_15,
|
||||
float3x3 param_16,
|
||||
uint param_17,
|
||||
float3x4 param_18,
|
||||
uint param_19,
|
||||
float4x2 param_20,
|
||||
uint param_21,
|
||||
float4x3 param_22,
|
||||
uint param_23,
|
||||
float4x4 param_24,
|
||||
float param_25) {
|
||||
S output;
|
||||
output.a = param_0;
|
||||
output.b = param_1;
|
||||
output.c = param_2;
|
||||
output.d = param_3;
|
||||
output.e = param_4;
|
||||
output.f = param_5;
|
||||
output.g = param_6;
|
||||
output.h = param_7;
|
||||
output.i = param_8;
|
||||
output.j = param_9;
|
||||
output.k = param_10;
|
||||
output.l = param_11;
|
||||
output.m = param_12;
|
||||
output.n = param_13;
|
||||
output.o = param_14;
|
||||
output.p = param_15;
|
||||
output.q = param_16;
|
||||
output.r = param_17;
|
||||
output.s = param_18;
|
||||
output.t = param_19;
|
||||
output.u = param_20;
|
||||
output.v = param_21;
|
||||
output.w = param_22;
|
||||
output.x = param_23;
|
||||
output.y = param_24;
|
||||
output.z = param_25;
|
||||
return output;
|
||||
}
|
||||
)";
|
||||
|
||||
EXPECT_EQ(result(), expect);
|
||||
}
|
||||
|
||||
TEST_F(HlslGeneratorImplTest_Type, EmitType_Struct_Layout_Structures) {
|
||||
// inner_x: size(1024), align(512)
|
||||
auto* inner_x =
|
||||
Structure("inner_x", {
|
||||
Member("a", ty.i32()),
|
||||
Member("b", ty.f32(), {MemberAlign(512)}),
|
||||
});
|
||||
|
||||
// inner_y: size(516), align(4)
|
||||
auto* inner_y =
|
||||
Structure("inner_y", {
|
||||
Member("a", ty.i32(), {MemberSize(512)}),
|
||||
Member("b", ty.f32()),
|
||||
});
|
||||
|
||||
auto* s = Structure("S",
|
||||
{
|
||||
Member("a", ty.i32()),
|
||||
Member("b", ty.Of(inner_x)),
|
||||
Member("c", ty.f32()),
|
||||
Member("d", ty.Of(inner_y)),
|
||||
Member("e", ty.f32()),
|
||||
},
|
||||
{create<ast::StructBlockDecoration>()});
|
||||
|
||||
Global("G", ty.Of(s), ast::StorageClass::kUniform,
|
||||
ast::DecorationList{
|
||||
create<ast::BindingDecoration>(0),
|
||||
create<ast::GroupDecoration>(0),
|
||||
});
|
||||
|
||||
GeneratorImpl& gen = Build();
|
||||
|
||||
auto* sem_s = program->TypeOf(s)->As<sem::Struct>();
|
||||
ASSERT_TRUE(gen.EmitStructType(out, sem_s)) << gen.error();
|
||||
|
||||
auto* expect = R"(struct S {
|
||||
/* 0x0000 */ int a;
|
||||
/* 0x0004 */ int tint_pad_0[127];
|
||||
/* 0x0200 */ inner_x b;
|
||||
/* 0x0600 */ float c;
|
||||
/* 0x0604 */ inner_y d;
|
||||
/* 0x0808 */ float e;
|
||||
/* 0x080c */ int tint_pad_1[125];
|
||||
};
|
||||
|
||||
S make_S(int param_0,
|
||||
inner_x param_1,
|
||||
float param_2,
|
||||
inner_y param_3,
|
||||
float param_4) {
|
||||
S output;
|
||||
output.a = param_0;
|
||||
output.b = param_1;
|
||||
output.c = param_2;
|
||||
output.d = param_3;
|
||||
output.e = param_4;
|
||||
return output;
|
||||
}
|
||||
)";
|
||||
EXPECT_EQ(result(), expect);
|
||||
}
|
||||
|
||||
TEST_F(HlslGeneratorImplTest_Type, EmitType_Struct_Layout_ArrayDefaultStride) {
|
||||
// inner: size(1024), align(512)
|
||||
auto* inner =
|
||||
Structure("inner", {
|
||||
Member("a", ty.i32()),
|
||||
Member("b", ty.f32(), {MemberAlign(512)}),
|
||||
});
|
||||
|
||||
// array_x: size(28), align(4)
|
||||
auto* array_x = ty.array<f32, 7>();
|
||||
|
||||
// array_y: size(4096), align(512)
|
||||
auto* array_y = ty.array(ty.Of(inner), 4);
|
||||
|
||||
// array_z: size(4), align(4)
|
||||
auto* array_z = ty.array<f32, 1>();
|
||||
|
||||
auto* s =
|
||||
Structure("S",
|
||||
{
|
||||
Member("a", ty.i32()),
|
||||
Member("b", array_x),
|
||||
Member("c", ty.f32()),
|
||||
Member("d", array_y),
|
||||
Member("e", ty.f32()),
|
||||
Member("f", array_z),
|
||||
},
|
||||
ast::DecorationList{create<ast::StructBlockDecoration>()});
|
||||
|
||||
Global("G", ty.Of(s), ast::StorageClass::kUniform,
|
||||
ast::DecorationList{
|
||||
create<ast::BindingDecoration>(0),
|
||||
create<ast::GroupDecoration>(0),
|
||||
});
|
||||
|
||||
GeneratorImpl& gen = Build();
|
||||
|
||||
auto* sem_s = program->TypeOf(s)->As<sem::Struct>();
|
||||
ASSERT_TRUE(gen.EmitStructType(out, sem_s)) << gen.error();
|
||||
|
||||
auto* expect = R"(struct S {
|
||||
/* 0x0000 */ int a;
|
||||
/* 0x0004 */ float b[7];
|
||||
/* 0x0020 */ float c;
|
||||
/* 0x0024 */ int tint_pad_0[119];
|
||||
/* 0x0200 */ inner d[4];
|
||||
/* 0x1200 */ float e;
|
||||
/* 0x1204 */ float f[1];
|
||||
/* 0x1208 */ int tint_pad_1[126];
|
||||
};
|
||||
|
||||
S make_S(int param_0,
|
||||
float param_1[7],
|
||||
float param_2,
|
||||
inner param_3[4],
|
||||
float param_4,
|
||||
float param_5[1]) {
|
||||
S output;
|
||||
output.a = param_0;
|
||||
output.b = param_1;
|
||||
output.c = param_2;
|
||||
output.d = param_3;
|
||||
output.e = param_4;
|
||||
output.f = param_5;
|
||||
return output;
|
||||
}
|
||||
)";
|
||||
|
||||
EXPECT_EQ(result(), expect);
|
||||
}
|
||||
|
||||
TEST_F(HlslGeneratorImplTest_Type, AttemptTintPadSymbolCollision) {
|
||||
auto* s = Structure(
|
||||
"S",
|
||||
{
|
||||
// uses symbols tint_pad_[0..9] and tint_pad_[20..35]
|
||||
Member("tint_pad_2", ty.i32(), {MemberSize(32)}),
|
||||
Member("tint_pad_20", ty.f32(), {MemberAlign(128), MemberSize(128)}),
|
||||
Member("tint_pad_33", ty.vec2<f32>()),
|
||||
Member("tint_pad_1", ty.u32()),
|
||||
Member("tint_pad_3", ty.vec3<f32>()),
|
||||
Member("tint_pad_7", ty.u32()),
|
||||
Member("tint_pad_25", ty.vec4<f32>()),
|
||||
Member("tint_pad_5", ty.u32()),
|
||||
Member("tint_pad_27", ty.mat2x2<f32>()),
|
||||
Member("tint_pad_24", ty.u32()),
|
||||
Member("tint_pad_23", ty.mat2x3<f32>()),
|
||||
Member("tint_pad_0", ty.u32()),
|
||||
Member("tint_pad_8", ty.mat2x4<f32>()),
|
||||
Member("tint_pad_26", ty.u32()),
|
||||
Member("tint_pad_29", ty.mat3x2<f32>()),
|
||||
Member("tint_pad_6", ty.u32()),
|
||||
Member("tint_pad_22", ty.mat3x3<f32>()),
|
||||
Member("tint_pad_32", ty.u32()),
|
||||
Member("tint_pad_34", ty.mat3x4<f32>()),
|
||||
Member("tint_pad_35", ty.u32()),
|
||||
Member("tint_pad_30", ty.mat4x2<f32>()),
|
||||
Member("tint_pad_9", ty.u32()),
|
||||
Member("tint_pad_31", ty.mat4x3<f32>()),
|
||||
Member("tint_pad_28", ty.u32()),
|
||||
Member("tint_pad_4", ty.mat4x4<f32>()),
|
||||
Member("tint_pad_21", ty.f32()),
|
||||
},
|
||||
{create<ast::StructBlockDecoration>()});
|
||||
|
||||
Global("G", ty.Of(s), ast::StorageClass::kUniform,
|
||||
ast::DecorationList{
|
||||
create<ast::BindingDecoration>(0),
|
||||
create<ast::GroupDecoration>(0),
|
||||
});
|
||||
|
||||
GeneratorImpl& gen = Build();
|
||||
|
||||
auto* sem_s = program->TypeOf(s)->As<sem::Struct>();
|
||||
ASSERT_TRUE(gen.EmitStructType(out, sem_s)) << gen.error();
|
||||
EXPECT_EQ(result(), R"(struct S {
|
||||
/* 0x0000 */ int tint_pad_2;
|
||||
/* 0x0004 */ int tint_pad_10[31];
|
||||
/* 0x0080 */ float tint_pad_20;
|
||||
/* 0x0084 */ int tint_pad_11[31];
|
||||
/* 0x0100 */ float2 tint_pad_33;
|
||||
/* 0x0108 */ uint tint_pad_1;
|
||||
/* 0x010c */ int tint_pad_12[1];
|
||||
/* 0x0110 */ float3 tint_pad_3;
|
||||
/* 0x011c */ uint tint_pad_7;
|
||||
/* 0x0120 */ float4 tint_pad_25;
|
||||
/* 0x0130 */ uint tint_pad_5;
|
||||
/* 0x0134 */ int tint_pad_13[1];
|
||||
/* 0x0138 */ float2x2 tint_pad_27;
|
||||
/* 0x0148 */ uint tint_pad_24;
|
||||
/* 0x014c */ int tint_pad_14[1];
|
||||
/* 0x0150 */ float2x3 tint_pad_23;
|
||||
/* 0x0170 */ uint tint_pad_0;
|
||||
/* 0x0174 */ int tint_pad_15[3];
|
||||
/* 0x0180 */ float2x4 tint_pad_8;
|
||||
/* 0x01a0 */ uint tint_pad_26;
|
||||
/* 0x01a4 */ int tint_pad_16[1];
|
||||
/* 0x01a8 */ float3x2 tint_pad_29;
|
||||
/* 0x01c0 */ uint tint_pad_6;
|
||||
/* 0x01c4 */ int tint_pad_17[3];
|
||||
/* 0x01d0 */ float3x3 tint_pad_22;
|
||||
/* 0x0200 */ uint tint_pad_32;
|
||||
/* 0x0204 */ int tint_pad_18[3];
|
||||
/* 0x0210 */ float3x4 tint_pad_34;
|
||||
/* 0x0240 */ uint tint_pad_35;
|
||||
/* 0x0244 */ int tint_pad_19[1];
|
||||
/* 0x0248 */ float4x2 tint_pad_30;
|
||||
/* 0x0268 */ uint tint_pad_9;
|
||||
/* 0x026c */ int tint_pad_36[1];
|
||||
/* 0x0270 */ float4x3 tint_pad_31;
|
||||
/* 0x02b0 */ uint tint_pad_28;
|
||||
/* 0x02b4 */ int tint_pad_37[3];
|
||||
/* 0x02c0 */ float4x4 tint_pad_4;
|
||||
/* 0x0300 */ float tint_pad_21;
|
||||
/* 0x0304 */ int tint_pad_38[31];
|
||||
};
|
||||
|
||||
S make_S(int param_0,
|
||||
float param_1,
|
||||
float2 param_2,
|
||||
uint param_3,
|
||||
float3 param_4,
|
||||
uint param_5,
|
||||
float4 param_6,
|
||||
uint param_7,
|
||||
float2x2 param_8,
|
||||
uint param_9,
|
||||
float2x3 param_10,
|
||||
uint param_11,
|
||||
float2x4 param_12,
|
||||
uint param_13,
|
||||
float3x2 param_14,
|
||||
uint param_15,
|
||||
float3x3 param_16,
|
||||
uint param_17,
|
||||
float3x4 param_18,
|
||||
uint param_19,
|
||||
float4x2 param_20,
|
||||
uint param_21,
|
||||
float4x3 param_22,
|
||||
uint param_23,
|
||||
float4x4 param_24,
|
||||
float param_25) {
|
||||
S output;
|
||||
output.tint_pad_2 = param_0;
|
||||
output.tint_pad_20 = param_1;
|
||||
output.tint_pad_33 = param_2;
|
||||
output.tint_pad_1 = param_3;
|
||||
output.tint_pad_3 = param_4;
|
||||
output.tint_pad_7 = param_5;
|
||||
output.tint_pad_25 = param_6;
|
||||
output.tint_pad_5 = param_7;
|
||||
output.tint_pad_27 = param_8;
|
||||
output.tint_pad_24 = param_9;
|
||||
output.tint_pad_23 = param_10;
|
||||
output.tint_pad_0 = param_11;
|
||||
output.tint_pad_8 = param_12;
|
||||
output.tint_pad_26 = param_13;
|
||||
output.tint_pad_29 = param_14;
|
||||
output.tint_pad_6 = param_15;
|
||||
output.tint_pad_22 = param_16;
|
||||
output.tint_pad_32 = param_17;
|
||||
output.tint_pad_34 = param_18;
|
||||
output.tint_pad_35 = param_19;
|
||||
output.tint_pad_30 = param_20;
|
||||
output.tint_pad_9 = param_21;
|
||||
output.tint_pad_31 = param_22;
|
||||
output.tint_pad_28 = param_23;
|
||||
output.tint_pad_4 = param_24;
|
||||
output.tint_pad_21 = param_25;
|
||||
return output;
|
||||
}
|
||||
)");
|
||||
}
|
||||
|
||||
|
|
|
@ -2410,6 +2410,7 @@ bool GeneratorImpl::EmitProgramConstVariable(const ast::Variable* var) {
|
|||
return true;
|
||||
}
|
||||
|
||||
// TODO(crbug.com/tint/898): We need CTS and / or Dawn e2e tests for this logic.
|
||||
GeneratorImpl::SizeAndAlign GeneratorImpl::MslPackedTypeSizeAndAlign(
|
||||
const sem::Type* ty) {
|
||||
if (ty->IsAnyOf<sem::U32, sem::I32, sem::F32>()) {
|
||||
|
|
|
@ -4,17 +4,24 @@ void unused_entry_point() {
|
|||
}
|
||||
|
||||
struct tint_padded_array_element {
|
||||
int el;
|
||||
/* 0x0000 */ int el;
|
||||
/* 0x0004 */ int tint_pad_0[3];
|
||||
};
|
||||
|
||||
tint_padded_array_element make_tint_padded_array_element(int param_0) {
|
||||
tint_padded_array_element output;
|
||||
output.el = param_0;
|
||||
return output;
|
||||
}
|
||||
struct tint_array_wrapper {
|
||||
tint_padded_array_element arr[4];
|
||||
/* 0x0000 */ tint_padded_array_element arr[4];
|
||||
};
|
||||
struct S {
|
||||
tint_array_wrapper arr;
|
||||
/* 0x0000 */ tint_array_wrapper arr;
|
||||
};
|
||||
|
||||
tint_array_wrapper tint_symbol_2(RWByteAddressBuffer buffer, uint offset) {
|
||||
const tint_array_wrapper tint_symbol_3 = {{{asint(buffer.Load((offset + 0u)))}, {asint(buffer.Load((offset + 16u)))}, {asint(buffer.Load((offset + 32u)))}, {asint(buffer.Load((offset + 48u)))}}};
|
||||
const tint_array_wrapper tint_symbol_3 = {{make_tint_padded_array_element(asint(buffer.Load((offset + 0u)))), make_tint_padded_array_element(asint(buffer.Load((offset + 16u)))), make_tint_padded_array_element(asint(buffer.Load((offset + 32u)))), make_tint_padded_array_element(asint(buffer.Load((offset + 48u))))}};
|
||||
return tint_symbol_3;
|
||||
}
|
||||
|
||||
|
@ -24,12 +31,12 @@ ConstantBuffer<S> src_uniform : register(b0, space0);
|
|||
RWByteAddressBuffer src_storage : register(u1, space0);
|
||||
|
||||
tint_array_wrapper ret_arr() {
|
||||
const tint_array_wrapper tint_symbol_4 = {{{0}, {0}, {0}, {0}}};
|
||||
const tint_array_wrapper tint_symbol_4 = {{make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0)}};
|
||||
return tint_symbol_4;
|
||||
}
|
||||
|
||||
S ret_struct_arr() {
|
||||
const S tint_symbol_5 = {{{{0}, {0}, {0}, {0}}}};
|
||||
const S tint_symbol_5 = {{{make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0)}}};
|
||||
return tint_symbol_5;
|
||||
}
|
||||
|
||||
|
@ -44,13 +51,13 @@ struct tint_array_wrapper_1 {
|
|||
};
|
||||
|
||||
void foo(tint_array_wrapper src_param) {
|
||||
tint_array_wrapper src_function = {{{0}, {0}, {0}, {0}}};
|
||||
tint_array_wrapper tint_symbol = {{{0}, {0}, {0}, {0}}};
|
||||
const tint_array_wrapper tint_symbol_6 = {{{1}, {2}, {3}, {3}}};
|
||||
tint_array_wrapper src_function = {{make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0)}};
|
||||
tint_array_wrapper tint_symbol = {{make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0)}};
|
||||
const tint_array_wrapper tint_symbol_6 = {{make_tint_padded_array_element(1), make_tint_padded_array_element(2), make_tint_padded_array_element(3), make_tint_padded_array_element(3)}};
|
||||
tint_symbol = tint_symbol_6;
|
||||
tint_symbol = src_param;
|
||||
tint_symbol = ret_arr();
|
||||
const tint_array_wrapper src_let = {{{0}, {0}, {0}, {0}}};
|
||||
const tint_array_wrapper src_let = {{make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0)}};
|
||||
tint_symbol = src_let;
|
||||
tint_symbol = src_function;
|
||||
tint_symbol = src_private;
|
||||
|
|
|
@ -4,17 +4,24 @@ void unused_entry_point() {
|
|||
}
|
||||
|
||||
struct tint_padded_array_element {
|
||||
int el;
|
||||
/* 0x0000 */ int el;
|
||||
/* 0x0004 */ int tint_pad_0[3];
|
||||
};
|
||||
|
||||
tint_padded_array_element make_tint_padded_array_element(int param_0) {
|
||||
tint_padded_array_element output;
|
||||
output.el = param_0;
|
||||
return output;
|
||||
}
|
||||
struct tint_array_wrapper {
|
||||
tint_padded_array_element arr[4];
|
||||
/* 0x0000 */ tint_padded_array_element arr[4];
|
||||
};
|
||||
struct S {
|
||||
tint_array_wrapper arr;
|
||||
/* 0x0000 */ tint_array_wrapper arr;
|
||||
};
|
||||
|
||||
tint_array_wrapper tint_symbol_2(RWByteAddressBuffer buffer, uint offset) {
|
||||
const tint_array_wrapper tint_symbol_3 = {{{asint(buffer.Load((offset + 0u)))}, {asint(buffer.Load((offset + 16u)))}, {asint(buffer.Load((offset + 32u)))}, {asint(buffer.Load((offset + 48u)))}}};
|
||||
const tint_array_wrapper tint_symbol_3 = {{make_tint_padded_array_element(asint(buffer.Load((offset + 0u)))), make_tint_padded_array_element(asint(buffer.Load((offset + 16u)))), make_tint_padded_array_element(asint(buffer.Load((offset + 32u)))), make_tint_padded_array_element(asint(buffer.Load((offset + 48u))))}};
|
||||
return tint_symbol_3;
|
||||
}
|
||||
|
||||
|
@ -37,22 +44,22 @@ struct tint_array_wrapper_1 {
|
|||
static tint_array_wrapper_1 dst_nested;
|
||||
|
||||
tint_array_wrapper ret_arr() {
|
||||
const tint_array_wrapper tint_symbol_4 = {{{0}, {0}, {0}, {0}}};
|
||||
const tint_array_wrapper tint_symbol_4 = {{make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0)}};
|
||||
return tint_symbol_4;
|
||||
}
|
||||
|
||||
S ret_struct_arr() {
|
||||
const S tint_symbol_5 = {{{{0}, {0}, {0}, {0}}}};
|
||||
const S tint_symbol_5 = {{{make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0)}}};
|
||||
return tint_symbol_5;
|
||||
}
|
||||
|
||||
void foo(tint_array_wrapper src_param) {
|
||||
tint_array_wrapper src_function = {{{0}, {0}, {0}, {0}}};
|
||||
const tint_array_wrapper tint_symbol_6 = {{{1}, {2}, {3}, {3}}};
|
||||
tint_array_wrapper src_function = {{make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0)}};
|
||||
const tint_array_wrapper tint_symbol_6 = {{make_tint_padded_array_element(1), make_tint_padded_array_element(2), make_tint_padded_array_element(3), make_tint_padded_array_element(3)}};
|
||||
tint_symbol = tint_symbol_6;
|
||||
tint_symbol = src_param;
|
||||
tint_symbol = ret_arr();
|
||||
const tint_array_wrapper src_let = {{{0}, {0}, {0}, {0}}};
|
||||
const tint_array_wrapper src_let = {{make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0)}};
|
||||
tint_symbol = src_let;
|
||||
tint_symbol = src_function;
|
||||
tint_symbol = src_private;
|
||||
|
|
|
@ -4,17 +4,24 @@ void unused_entry_point() {
|
|||
}
|
||||
|
||||
struct tint_padded_array_element {
|
||||
int el;
|
||||
/* 0x0000 */ int el;
|
||||
/* 0x0004 */ int tint_pad_0[3];
|
||||
};
|
||||
|
||||
tint_padded_array_element make_tint_padded_array_element(int param_0) {
|
||||
tint_padded_array_element output;
|
||||
output.el = param_0;
|
||||
return output;
|
||||
}
|
||||
struct tint_array_wrapper {
|
||||
tint_padded_array_element arr[4];
|
||||
/* 0x0000 */ tint_padded_array_element arr[4];
|
||||
};
|
||||
struct S {
|
||||
tint_array_wrapper arr;
|
||||
/* 0x0000 */ tint_array_wrapper arr;
|
||||
};
|
||||
|
||||
tint_array_wrapper tint_symbol_2(RWByteAddressBuffer buffer, uint offset) {
|
||||
const tint_array_wrapper tint_symbol_9 = {{{asint(buffer.Load((offset + 0u)))}, {asint(buffer.Load((offset + 16u)))}, {asint(buffer.Load((offset + 32u)))}, {asint(buffer.Load((offset + 48u)))}}};
|
||||
const tint_array_wrapper tint_symbol_9 = {{make_tint_padded_array_element(asint(buffer.Load((offset + 0u)))), make_tint_padded_array_element(asint(buffer.Load((offset + 16u)))), make_tint_padded_array_element(asint(buffer.Load((offset + 32u)))), make_tint_padded_array_element(asint(buffer.Load((offset + 48u))))}};
|
||||
return tint_symbol_9;
|
||||
}
|
||||
|
||||
|
@ -26,13 +33,13 @@ void tint_symbol_4(RWByteAddressBuffer buffer, uint offset, tint_array_wrapper v
|
|||
}
|
||||
|
||||
struct tint_array_wrapper_3 {
|
||||
int arr[2];
|
||||
/* 0x0000 */ int arr[2];
|
||||
};
|
||||
struct tint_array_wrapper_2 {
|
||||
tint_array_wrapper_3 arr[3];
|
||||
/* 0x0000 */ tint_array_wrapper_3 arr[3];
|
||||
};
|
||||
struct tint_array_wrapper_1 {
|
||||
tint_array_wrapper_2 arr[4];
|
||||
/* 0x0000 */ tint_array_wrapper_2 arr[4];
|
||||
};
|
||||
|
||||
void tint_symbol_6(RWByteAddressBuffer buffer, uint offset, tint_array_wrapper_3 value) {
|
||||
|
@ -61,22 +68,22 @@ RWByteAddressBuffer tint_symbol : register(u2, space0);
|
|||
RWByteAddressBuffer dst_nested : register(u3, space0);
|
||||
|
||||
tint_array_wrapper ret_arr() {
|
||||
const tint_array_wrapper tint_symbol_10 = {{{0}, {0}, {0}, {0}}};
|
||||
const tint_array_wrapper tint_symbol_10 = {{make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0)}};
|
||||
return tint_symbol_10;
|
||||
}
|
||||
|
||||
S ret_struct_arr() {
|
||||
const S tint_symbol_11 = {{{{0}, {0}, {0}, {0}}}};
|
||||
const S tint_symbol_11 = {{{make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0)}}};
|
||||
return tint_symbol_11;
|
||||
}
|
||||
|
||||
void foo(tint_array_wrapper src_param) {
|
||||
tint_array_wrapper src_function = {{{0}, {0}, {0}, {0}}};
|
||||
const tint_array_wrapper tint_symbol_12 = {{{1}, {2}, {3}, {3}}};
|
||||
tint_array_wrapper src_function = {{make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0)}};
|
||||
const tint_array_wrapper tint_symbol_12 = {{make_tint_padded_array_element(1), make_tint_padded_array_element(2), make_tint_padded_array_element(3), make_tint_padded_array_element(3)}};
|
||||
tint_symbol_4(tint_symbol, 0u, tint_symbol_12);
|
||||
tint_symbol_4(tint_symbol, 0u, src_param);
|
||||
tint_symbol_4(tint_symbol, 0u, ret_arr());
|
||||
const tint_array_wrapper src_let = {{{0}, {0}, {0}, {0}}};
|
||||
const tint_array_wrapper src_let = {{make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0)}};
|
||||
tint_symbol_4(tint_symbol, 0u, src_let);
|
||||
tint_symbol_4(tint_symbol, 0u, src_function);
|
||||
tint_symbol_4(tint_symbol, 0u, src_private);
|
||||
|
|
|
@ -4,17 +4,24 @@ void unused_entry_point() {
|
|||
}
|
||||
|
||||
struct tint_padded_array_element {
|
||||
int el;
|
||||
/* 0x0000 */ int el;
|
||||
/* 0x0004 */ int tint_pad_0[3];
|
||||
};
|
||||
|
||||
tint_padded_array_element make_tint_padded_array_element(int param_0) {
|
||||
tint_padded_array_element output;
|
||||
output.el = param_0;
|
||||
return output;
|
||||
}
|
||||
struct tint_array_wrapper {
|
||||
tint_padded_array_element arr[4];
|
||||
/* 0x0000 */ tint_padded_array_element arr[4];
|
||||
};
|
||||
struct S {
|
||||
tint_array_wrapper arr;
|
||||
/* 0x0000 */ tint_array_wrapper arr;
|
||||
};
|
||||
|
||||
tint_array_wrapper tint_symbol_2(RWByteAddressBuffer buffer, uint offset) {
|
||||
const tint_array_wrapper tint_symbol_3 = {{{asint(buffer.Load((offset + 0u)))}, {asint(buffer.Load((offset + 16u)))}, {asint(buffer.Load((offset + 32u)))}, {asint(buffer.Load((offset + 48u)))}}};
|
||||
const tint_array_wrapper tint_symbol_3 = {{make_tint_padded_array_element(asint(buffer.Load((offset + 0u)))), make_tint_padded_array_element(asint(buffer.Load((offset + 16u)))), make_tint_padded_array_element(asint(buffer.Load((offset + 32u)))), make_tint_padded_array_element(asint(buffer.Load((offset + 48u))))}};
|
||||
return tint_symbol_3;
|
||||
}
|
||||
|
||||
|
@ -37,22 +44,22 @@ struct tint_array_wrapper_1 {
|
|||
groupshared tint_array_wrapper_1 dst_nested;
|
||||
|
||||
tint_array_wrapper ret_arr() {
|
||||
const tint_array_wrapper tint_symbol_4 = {{{0}, {0}, {0}, {0}}};
|
||||
const tint_array_wrapper tint_symbol_4 = {{make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0)}};
|
||||
return tint_symbol_4;
|
||||
}
|
||||
|
||||
S ret_struct_arr() {
|
||||
const S tint_symbol_5 = {{{{0}, {0}, {0}, {0}}}};
|
||||
const S tint_symbol_5 = {{{make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0)}}};
|
||||
return tint_symbol_5;
|
||||
}
|
||||
|
||||
void foo(tint_array_wrapper src_param) {
|
||||
tint_array_wrapper src_function = {{{0}, {0}, {0}, {0}}};
|
||||
const tint_array_wrapper tint_symbol_6 = {{{1}, {2}, {3}, {3}}};
|
||||
tint_array_wrapper src_function = {{make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0)}};
|
||||
const tint_array_wrapper tint_symbol_6 = {{make_tint_padded_array_element(1), make_tint_padded_array_element(2), make_tint_padded_array_element(3), make_tint_padded_array_element(3)}};
|
||||
tint_symbol = tint_symbol_6;
|
||||
tint_symbol = src_param;
|
||||
tint_symbol = ret_arr();
|
||||
const tint_array_wrapper src_let = {{{0}, {0}, {0}, {0}}};
|
||||
const tint_array_wrapper src_let = {{make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0), make_tint_padded_array_element(0)}};
|
||||
tint_symbol = src_let;
|
||||
tint_symbol = src_function;
|
||||
tint_symbol = src_private;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
struct Uniforms {
|
||||
uint2 aShape;
|
||||
uint2 bShape;
|
||||
uint2 outShape;
|
||||
/* 0x0000 */ uint2 aShape;
|
||||
/* 0x0008 */ uint2 bShape;
|
||||
/* 0x0010 */ uint2 outShape;
|
||||
};
|
||||
|
||||
ByteAddressBuffer firstMatrix : register(t0, space0);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
struct Constants {
|
||||
int level;
|
||||
/* 0x0000 */ int level;
|
||||
};
|
||||
|
||||
ConstantBuffer<Constants> constants : register(b0, space0);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
struct tint_array_wrapper {
|
||||
int arr[6];
|
||||
/* 0x0000 */ int arr[6];
|
||||
};
|
||||
|
||||
tint_array_wrapper tint_symbol_1(ByteAddressBuffer buffer, uint offset) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
struct S {
|
||||
int a;
|
||||
/* 0x0000 */ int a;
|
||||
};
|
||||
|
||||
ConstantBuffer<S> v : register(b0, space0);
|
||||
|
|
|
@ -27,13 +27,13 @@ tint_symbol_3 frag_main() {
|
|||
}
|
||||
|
||||
struct SimParams {
|
||||
float deltaT;
|
||||
float rule1Distance;
|
||||
float rule2Distance;
|
||||
float rule3Distance;
|
||||
float rule1Scale;
|
||||
float rule2Scale;
|
||||
float rule3Scale;
|
||||
/* 0x0000 */ float deltaT;
|
||||
/* 0x0004 */ float rule1Distance;
|
||||
/* 0x0008 */ float rule2Distance;
|
||||
/* 0x000c */ float rule3Distance;
|
||||
/* 0x0010 */ float rule1Scale;
|
||||
/* 0x0014 */ float rule2Scale;
|
||||
/* 0x0018 */ float rule3Scale;
|
||||
};
|
||||
|
||||
ConstantBuffer<SimParams> params : register(b0, space0);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
struct Uniforms {
|
||||
float4x4 modelViewProjectionMatrix;
|
||||
/* 0x0000 */ float4x4 modelViewProjectionMatrix;
|
||||
};
|
||||
|
||||
ConstantBuffer<Uniforms> uniforms : register(b0, space0);
|
||||
|
|
|
@ -1,9 +1,21 @@
|
|||
struct S {
|
||||
float f;
|
||||
uint u;
|
||||
float4 v;
|
||||
/* 0x0000 */ float f;
|
||||
/* 0x0004 */ uint u;
|
||||
/* 0x0008 */ int tint_pad_0[30];
|
||||
/* 0x0080 */ float4 v;
|
||||
/* 0x0090 */ int tint_pad_1[28];
|
||||
};
|
||||
|
||||
S make_S(float param_0,
|
||||
uint param_1,
|
||||
float4 param_2) {
|
||||
S output;
|
||||
output.f = param_0;
|
||||
output.u = param_1;
|
||||
output.v = param_2;
|
||||
return output;
|
||||
}
|
||||
|
||||
void tint_symbol_5(RWByteAddressBuffer buffer, uint offset, S value) {
|
||||
buffer.Store((offset + 0u), asuint(value.f));
|
||||
buffer.Store((offset + 4u), asuint(value.u));
|
||||
|
@ -19,7 +31,7 @@ struct tint_symbol_1 {
|
|||
};
|
||||
|
||||
void frag_main(tint_symbol_1 tint_symbol) {
|
||||
const S input = {tint_symbol.f, tint_symbol.u, tint_symbol.v};
|
||||
const S input = make_S(tint_symbol.f, tint_symbol.u, tint_symbol.v);
|
||||
const float f = input.f;
|
||||
const uint u = input.u;
|
||||
const float4 v = input.v;
|
||||
|
|
Loading…
Reference in New Issue