mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-07-04 12:16:10 +00:00
tint: Add chromium_internal_relaxed_uniform_layout
This will be used by the PackedVec3 transform to avoid triggering stricter layout validation rules for the uniform address space when mutating types. Bug: tint:1571 Change-Id: Ib15737fbe3cab4a8fbe453bcaf96ef2acc595921 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/121601 Commit-Queue: James Price <jrprice@google.com> Reviewed-by: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
806135658d
commit
0b3400c56e
@ -40,6 +40,9 @@ Extension ParseExtension(std::string_view str) {
|
|||||||
if (str == "chromium_experimental_push_constant") {
|
if (str == "chromium_experimental_push_constant") {
|
||||||
return Extension::kChromiumExperimentalPushConstant;
|
return Extension::kChromiumExperimentalPushConstant;
|
||||||
}
|
}
|
||||||
|
if (str == "chromium_internal_relaxed_uniform_layout") {
|
||||||
|
return Extension::kChromiumInternalRelaxedUniformLayout;
|
||||||
|
}
|
||||||
if (str == "f16") {
|
if (str == "f16") {
|
||||||
return Extension::kF16;
|
return Extension::kF16;
|
||||||
}
|
}
|
||||||
@ -58,6 +61,8 @@ std::ostream& operator<<(std::ostream& out, Extension value) {
|
|||||||
return out << "chromium_experimental_full_ptr_parameters";
|
return out << "chromium_experimental_full_ptr_parameters";
|
||||||
case Extension::kChromiumExperimentalPushConstant:
|
case Extension::kChromiumExperimentalPushConstant:
|
||||||
return out << "chromium_experimental_push_constant";
|
return out << "chromium_experimental_push_constant";
|
||||||
|
case Extension::kChromiumInternalRelaxedUniformLayout:
|
||||||
|
return out << "chromium_internal_relaxed_uniform_layout";
|
||||||
case Extension::kF16:
|
case Extension::kF16:
|
||||||
return out << "f16";
|
return out << "f16";
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@ enum class Extension {
|
|||||||
kChromiumExperimentalDp4A,
|
kChromiumExperimentalDp4A,
|
||||||
kChromiumExperimentalFullPtrParameters,
|
kChromiumExperimentalFullPtrParameters,
|
||||||
kChromiumExperimentalPushConstant,
|
kChromiumExperimentalPushConstant,
|
||||||
|
kChromiumInternalRelaxedUniformLayout,
|
||||||
kF16,
|
kF16,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -51,11 +52,9 @@ std::ostream& operator<<(std::ostream& out, Extension value);
|
|||||||
Extension ParseExtension(std::string_view str);
|
Extension ParseExtension(std::string_view str);
|
||||||
|
|
||||||
constexpr const char* kExtensionStrings[] = {
|
constexpr const char* kExtensionStrings[] = {
|
||||||
"chromium_disable_uniformity_analysis",
|
"chromium_disable_uniformity_analysis", "chromium_experimental_dp4a",
|
||||||
"chromium_experimental_dp4a",
|
"chromium_experimental_full_ptr_parameters", "chromium_experimental_push_constant",
|
||||||
"chromium_experimental_full_ptr_parameters",
|
"chromium_internal_relaxed_uniform_layout", "f16",
|
||||||
"chromium_experimental_push_constant",
|
|
||||||
"f16",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// A unique vector of extensions
|
// A unique vector of extensions
|
||||||
|
@ -59,13 +59,20 @@ void ExtensionParser(::benchmark::State& state) {
|
|||||||
"chromium_exp9rimFntal_ush_constant",
|
"chromium_exp9rimFntal_ush_constant",
|
||||||
"chrmium_experimental_push_constant",
|
"chrmium_experimental_push_constant",
|
||||||
"cOOromium_experiVeHtal_puh_conRRtant",
|
"cOOromium_experiVeHtal_puh_conRRtant",
|
||||||
"y1",
|
"chromium_internl_relaxyd_uniform_layout",
|
||||||
"l77rrn6",
|
"chromnnum_internrr77_Gelaxell_uniform_layout",
|
||||||
"4016",
|
"chromium_intern4l_relaxe00_uniform_layout",
|
||||||
|
"chromium_internal_relaxed_uniform_layout",
|
||||||
|
"chrmoom_internal_relaxed_uniform_lyout",
|
||||||
|
"chroium_internal_rlaxed_uniform_layzzut",
|
||||||
|
"chromium_internaii_r11axed_uppifor_layout",
|
||||||
|
"f1XX",
|
||||||
|
"55199II",
|
||||||
|
"frSSHHa",
|
||||||
"f16",
|
"f16",
|
||||||
"5",
|
"U",
|
||||||
"u16",
|
"jV3",
|
||||||
"f",
|
"",
|
||||||
};
|
};
|
||||||
for (auto _ : state) {
|
for (auto _ : state) {
|
||||||
for (auto* str : kStrings) {
|
for (auto* str : kStrings) {
|
||||||
|
@ -48,6 +48,7 @@ static constexpr Case kValidCases[] = {
|
|||||||
{"chromium_experimental_full_ptr_parameters",
|
{"chromium_experimental_full_ptr_parameters",
|
||||||
Extension::kChromiumExperimentalFullPtrParameters},
|
Extension::kChromiumExperimentalFullPtrParameters},
|
||||||
{"chromium_experimental_push_constant", Extension::kChromiumExperimentalPushConstant},
|
{"chromium_experimental_push_constant", Extension::kChromiumExperimentalPushConstant},
|
||||||
|
{"chromium_internal_relaxed_uniform_layout", Extension::kChromiumInternalRelaxedUniformLayout},
|
||||||
{"f16", Extension::kF16},
|
{"f16", Extension::kF16},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -64,9 +65,12 @@ static constexpr Case kInvalidCases[] = {
|
|||||||
{"chvomium_experimental_push_constiint", Extension::kUndefined},
|
{"chvomium_experimental_push_constiint", Extension::kUndefined},
|
||||||
{"chromiu8WWexperimental_push_constant", Extension::kUndefined},
|
{"chromiu8WWexperimental_push_constant", Extension::kUndefined},
|
||||||
{"chromium_experiMental_push_costanxx", Extension::kUndefined},
|
{"chromium_experiMental_push_costanxx", Extension::kUndefined},
|
||||||
{"fgg", Extension::kUndefined},
|
{"chromium_internal_relaxed_unXform_layugg", Extension::kUndefined},
|
||||||
{"X", Extension::kUndefined},
|
{"chromiuu_iVterna_relxed_unifXrm_layout", Extension::kUndefined},
|
||||||
{"316", Extension::kUndefined},
|
{"chromium_internal_relaxed_uni3orm_layout", Extension::kUndefined},
|
||||||
|
{"fE6", Extension::kUndefined},
|
||||||
|
{"fPTT", Extension::kUndefined},
|
||||||
|
{"dxx6", Extension::kUndefined},
|
||||||
};
|
};
|
||||||
|
|
||||||
using ExtensionParseTest = testing::TestWithParam<Case>;
|
using ExtensionParseTest = testing::TestWithParam<Case>;
|
||||||
|
@ -70,6 +70,8 @@ enum extension {
|
|||||||
// A Chromium-specific extension that enables passing of uniform, storage and workgroup
|
// A Chromium-specific extension that enables passing of uniform, storage and workgroup
|
||||||
// address-spaced pointers as parameters, as well as pointers into sub-objects.
|
// address-spaced pointers as parameters, as well as pointers into sub-objects.
|
||||||
chromium_experimental_full_ptr_parameters
|
chromium_experimental_full_ptr_parameters
|
||||||
|
// A Chromium-specific extension that relaxes memory layout requirements for uniform storage.
|
||||||
|
chromium_internal_relaxed_uniform_layout
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://gpuweb.github.io/gpuweb/wgsl/#storage-class
|
// https://gpuweb.github.io/gpuweb/wgsl/#storage-class
|
||||||
|
@ -62,7 +62,7 @@ TEST_F(EnableDirectiveTest, InvalidIdentifier) {
|
|||||||
// Error when unknown extension found
|
// Error when unknown extension found
|
||||||
EXPECT_TRUE(p->has_error());
|
EXPECT_TRUE(p->has_error());
|
||||||
EXPECT_EQ(p->error(), R"(1:8: expected extension
|
EXPECT_EQ(p->error(), R"(1:8: expected extension
|
||||||
Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_push_constant', 'f16')");
|
Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_push_constant', 'chromium_internal_relaxed_uniform_layout', 'f16')");
|
||||||
auto program = p->program();
|
auto program = p->program();
|
||||||
auto& ast = program.AST();
|
auto& ast = program.AST();
|
||||||
EXPECT_EQ(ast.Enables().Length(), 0u);
|
EXPECT_EQ(ast.Enables().Length(), 0u);
|
||||||
@ -76,7 +76,7 @@ TEST_F(EnableDirectiveTest, InvalidIdentifierSuggest) {
|
|||||||
EXPECT_TRUE(p->has_error());
|
EXPECT_TRUE(p->has_error());
|
||||||
EXPECT_EQ(p->error(), R"(1:8: expected extension
|
EXPECT_EQ(p->error(), R"(1:8: expected extension
|
||||||
Did you mean 'f16'?
|
Did you mean 'f16'?
|
||||||
Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_push_constant', 'f16')");
|
Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_push_constant', 'chromium_internal_relaxed_uniform_layout', 'f16')");
|
||||||
auto program = p->program();
|
auto program = p->program();
|
||||||
auto& ast = program.AST();
|
auto& ast = program.AST();
|
||||||
EXPECT_EQ(ast.Enables().Length(), 0u);
|
EXPECT_EQ(ast.Enables().Length(), 0u);
|
||||||
@ -124,7 +124,7 @@ TEST_F(EnableDirectiveTest, InvalidTokens) {
|
|||||||
p->translation_unit();
|
p->translation_unit();
|
||||||
EXPECT_TRUE(p->has_error());
|
EXPECT_TRUE(p->has_error());
|
||||||
EXPECT_EQ(p->error(), R"(1:8: expected extension
|
EXPECT_EQ(p->error(), R"(1:8: expected extension
|
||||||
Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_push_constant', 'f16')");
|
Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_push_constant', 'chromium_internal_relaxed_uniform_layout', 'f16')");
|
||||||
auto program = p->program();
|
auto program = p->program();
|
||||||
auto& ast = program.AST();
|
auto& ast = program.AST();
|
||||||
EXPECT_EQ(ast.Enables().Length(), 0u);
|
EXPECT_EQ(ast.Enables().Length(), 0u);
|
||||||
@ -135,7 +135,7 @@ Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_
|
|||||||
p->translation_unit();
|
p->translation_unit();
|
||||||
EXPECT_TRUE(p->has_error());
|
EXPECT_TRUE(p->has_error());
|
||||||
EXPECT_EQ(p->error(), R"(1:8: expected extension
|
EXPECT_EQ(p->error(), R"(1:8: expected extension
|
||||||
Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_push_constant', 'f16')");
|
Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_push_constant', 'chromium_internal_relaxed_uniform_layout', 'f16')");
|
||||||
auto program = p->program();
|
auto program = p->program();
|
||||||
auto& ast = program.AST();
|
auto& ast = program.AST();
|
||||||
EXPECT_EQ(ast.Enables().Length(), 0u);
|
EXPECT_EQ(ast.Enables().Length(), 0u);
|
||||||
@ -147,7 +147,7 @@ Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_
|
|||||||
EXPECT_TRUE(p->has_error());
|
EXPECT_TRUE(p->has_error());
|
||||||
EXPECT_EQ(p->error(), R"(1:8: expected extension
|
EXPECT_EQ(p->error(), R"(1:8: expected extension
|
||||||
Did you mean 'f16'?
|
Did you mean 'f16'?
|
||||||
Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_push_constant', 'f16')");
|
Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_push_constant', 'chromium_internal_relaxed_uniform_layout', 'f16')");
|
||||||
auto program = p->program();
|
auto program = p->program();
|
||||||
auto& ast = program.AST();
|
auto& ast = program.AST();
|
||||||
EXPECT_EQ(ast.Enables().Length(), 0u);
|
EXPECT_EQ(ast.Enables().Length(), 0u);
|
||||||
|
@ -603,5 +603,150 @@ TEST_F(ResolverAddressSpaceLayoutValidationTest, PushConstant_Aligned) {
|
|||||||
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ResolverAddressSpaceLayoutValidationTest, RelaxedUniformLayout_StructMemberOffset_Struct) {
|
||||||
|
// enable chromium_internal_relaxed_uniform_layout;
|
||||||
|
//
|
||||||
|
// struct Inner {
|
||||||
|
// scalar : i32;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// struct Outer {
|
||||||
|
// scalar : f32;
|
||||||
|
// inner : Inner;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// @group(0) @binding(0)
|
||||||
|
// var<uniform> a : Outer;
|
||||||
|
|
||||||
|
Enable(builtin::Extension::kChromiumInternalRelaxedUniformLayout);
|
||||||
|
|
||||||
|
Structure(Source{{12, 34}}, "Inner",
|
||||||
|
utils::Vector{
|
||||||
|
Member("scalar", ty.i32()),
|
||||||
|
});
|
||||||
|
|
||||||
|
Structure(Source{{34, 56}}, "Outer",
|
||||||
|
utils::Vector{
|
||||||
|
Member("scalar", ty.f32()),
|
||||||
|
Member(Source{{56, 78}}, "inner", ty("Inner")),
|
||||||
|
});
|
||||||
|
|
||||||
|
GlobalVar(Source{{78, 90}}, "a", ty("Outer"), builtin::AddressSpace::kUniform, Group(0_a),
|
||||||
|
Binding(0_a));
|
||||||
|
|
||||||
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ResolverAddressSpaceLayoutValidationTest, RelaxedUniformLayout_StructMemberOffset_Array) {
|
||||||
|
// enable chromium_internal_relaxed_uniform_layout;
|
||||||
|
//
|
||||||
|
// type Inner = @stride(16) array<f32, 10u>;
|
||||||
|
//
|
||||||
|
// struct Outer {
|
||||||
|
// scalar : f32;
|
||||||
|
// inner : Inner;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// @group(0) @binding(0)
|
||||||
|
// var<uniform> a : Outer;
|
||||||
|
|
||||||
|
Enable(builtin::Extension::kChromiumInternalRelaxedUniformLayout);
|
||||||
|
|
||||||
|
Alias("Inner", ty.array<f32, 10>(utils::Vector{Stride(16)}));
|
||||||
|
|
||||||
|
Structure(Source{{12, 34}}, "Outer",
|
||||||
|
utils::Vector{
|
||||||
|
Member("scalar", ty.f32()),
|
||||||
|
Member(Source{{56, 78}}, "inner", ty("Inner")),
|
||||||
|
});
|
||||||
|
|
||||||
|
GlobalVar(Source{{78, 90}}, "a", ty("Outer"), builtin::AddressSpace::kUniform, Group(0_a),
|
||||||
|
Binding(0_a));
|
||||||
|
|
||||||
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ResolverAddressSpaceLayoutValidationTest, RelaxedUniformLayout_MemberOffsetNotMutipleOf16) {
|
||||||
|
// enable chromium_internal_relaxed_uniform_layout;
|
||||||
|
//
|
||||||
|
// struct Inner {
|
||||||
|
// @align(1) @size(5) scalar : i32;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// struct Outer {
|
||||||
|
// inner : Inner;
|
||||||
|
// scalar : i32;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// @group(0) @binding(0)
|
||||||
|
// var<uniform> a : Outer;
|
||||||
|
|
||||||
|
Enable(builtin::Extension::kChromiumInternalRelaxedUniformLayout);
|
||||||
|
|
||||||
|
Structure(Source{{12, 34}}, "Inner",
|
||||||
|
utils::Vector{
|
||||||
|
Member("scalar", ty.i32(), utils::Vector{MemberAlign(1_i), MemberSize(5_a)}),
|
||||||
|
});
|
||||||
|
|
||||||
|
Structure(Source{{34, 56}}, "Outer",
|
||||||
|
utils::Vector{
|
||||||
|
Member(Source{{56, 78}}, "inner", ty("Inner")),
|
||||||
|
Member(Source{{78, 90}}, "scalar", ty.i32()),
|
||||||
|
});
|
||||||
|
|
||||||
|
GlobalVar(Source{{22, 24}}, "a", ty("Outer"), builtin::AddressSpace::kUniform, Group(0_a),
|
||||||
|
Binding(0_a));
|
||||||
|
|
||||||
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ResolverAddressSpaceLayoutValidationTest, RelaxedUniformLayout_ArrayStride_Scalar) {
|
||||||
|
// enable chromium_internal_relaxed_uniform_layout;
|
||||||
|
//
|
||||||
|
// struct Outer {
|
||||||
|
// arr : array<f32, 10u>;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// @group(0) @binding(0)
|
||||||
|
// var<uniform> a : Outer;
|
||||||
|
|
||||||
|
Enable(builtin::Extension::kChromiumInternalRelaxedUniformLayout);
|
||||||
|
|
||||||
|
Structure(Source{{12, 34}}, "Outer",
|
||||||
|
utils::Vector{
|
||||||
|
Member("arr", ty.array<f32, 10>()),
|
||||||
|
});
|
||||||
|
|
||||||
|
GlobalVar(Source{{78, 90}}, "a", ty("Outer"), builtin::AddressSpace::kUniform, Group(0_a),
|
||||||
|
Binding(0_a));
|
||||||
|
|
||||||
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ResolverAddressSpaceLayoutValidationTest, RelaxedUniformLayout_ArrayStride_Vech) {
|
||||||
|
// enable f16;
|
||||||
|
// enable chromium_internal_relaxed_uniform_layout;
|
||||||
|
//
|
||||||
|
// struct Outer {
|
||||||
|
// arr : array<vec3<f16>, 10u>;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// @group(0) @binding(0)
|
||||||
|
// var<uniform> a : Outer;
|
||||||
|
|
||||||
|
Enable(builtin::Extension::kF16);
|
||||||
|
Enable(builtin::Extension::kChromiumInternalRelaxedUniformLayout);
|
||||||
|
|
||||||
|
Structure(Source{{12, 34}}, "Outer",
|
||||||
|
utils::Vector{
|
||||||
|
Member("arr", ty.array(ty.vec3<f16>(), 10_u)),
|
||||||
|
});
|
||||||
|
|
||||||
|
GlobalVar(Source{{78, 90}}, "a", ty("Outer"), builtin::AddressSpace::kUniform, Group(0_a),
|
||||||
|
Binding(0_a));
|
||||||
|
|
||||||
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace tint::resolver
|
} // namespace tint::resolver
|
||||||
|
@ -467,7 +467,9 @@ bool Validator::AddressSpaceLayout(const type::Type* store_ty,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Validate that member is at a valid byte offset
|
// Validate that member is at a valid byte offset
|
||||||
if (m->Offset() % required_align != 0) {
|
if (m->Offset() % required_align != 0 &&
|
||||||
|
!enabled_extensions_.Contains(
|
||||||
|
builtin::Extension::kChromiumInternalRelaxedUniformLayout)) {
|
||||||
AddError("the offset of a struct member of type '" +
|
AddError("the offset of a struct member of type '" +
|
||||||
m->Type()->UnwrapRef()->FriendlyName(symbols_) +
|
m->Type()->UnwrapRef()->FriendlyName(symbols_) +
|
||||||
"' in address space '" + utils::ToString(address_space) +
|
"' in address space '" + utils::ToString(address_space) +
|
||||||
@ -493,7 +495,9 @@ bool Validator::AddressSpaceLayout(const type::Type* store_ty,
|
|||||||
auto* const prev_member = (i == 0) ? nullptr : str->Members()[i - 1];
|
auto* const prev_member = (i == 0) ? nullptr : str->Members()[i - 1];
|
||||||
if (prev_member && is_uniform_struct(prev_member->Type())) {
|
if (prev_member && is_uniform_struct(prev_member->Type())) {
|
||||||
const uint32_t prev_to_curr_offset = m->Offset() - prev_member->Offset();
|
const uint32_t prev_to_curr_offset = m->Offset() - prev_member->Offset();
|
||||||
if (prev_to_curr_offset % 16 != 0) {
|
if (prev_to_curr_offset % 16 != 0 &&
|
||||||
|
!enabled_extensions_.Contains(
|
||||||
|
builtin::Extension::kChromiumInternalRelaxedUniformLayout)) {
|
||||||
AddError(
|
AddError(
|
||||||
"uniform storage requires that the number of bytes between the "
|
"uniform storage requires that the number of bytes between the "
|
||||||
"start of the previous member of type struct and the current "
|
"start of the previous member of type struct and the current "
|
||||||
@ -526,7 +530,9 @@ bool Validator::AddressSpaceLayout(const type::Type* store_ty,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (address_space == builtin::AddressSpace::kUniform) {
|
if (address_space == builtin::AddressSpace::kUniform &&
|
||||||
|
!enabled_extensions_.Contains(
|
||||||
|
builtin::Extension::kChromiumInternalRelaxedUniformLayout)) {
|
||||||
// We already validated that this array member is itself aligned to 16 bytes above, so
|
// We already validated that this array member is itself aligned to 16 bytes above, so
|
||||||
// we only need to validate that stride is a multiple of 16 bytes.
|
// we only need to validate that stride is a multiple of 16 bytes.
|
||||||
if (arr->Stride() % 16 != 0) {
|
if (arr->Stride() % 16 != 0) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user