Remove struct member offset monotonicity check

Fixes #1822

* Remove check that struct member offsets must be monotonic
 * All environments match Vulkan behaviour now
 * updated offending tests
This commit is contained in:
Alan Baker 2018-08-28 08:46:39 -04:00
parent 482b1744ca
commit cb0f1f565b
4 changed files with 4 additions and 39 deletions

View File

@ -350,8 +350,6 @@ spv_result_t checkLayout(uint32_t struct_id, const char* storage_class_str,
// To check for member overlaps, we want to traverse the members in
// offset order.
const bool permit_non_monotonic_member_offsets =
vstate.features().non_monotonic_struct_member_offsets;
struct MemberOffsetPair {
uint32_t member;
uint32_t offset;
@ -381,7 +379,6 @@ spv_result_t checkLayout(uint32_t struct_id, const char* storage_class_str,
});
// Now scan from lowest offest to highest offset.
uint32_t prevOffset = 0;
uint32_t nextValidOffset = 0;
for (size_t ordered_member_idx = 0;
ordered_member_idx < member_offsets.size(); ordered_member_idx++) {
@ -418,19 +415,6 @@ spv_result_t checkLayout(uint32_t struct_id, const char* storage_class_str,
<< "at offset " << offset << " is not aligned to " << alignment;
}
}
// SPIR-V requires struct members to be specified in memory address order,
// and they should not overlap. Vulkan relaxes that rule.
if (!permit_non_monotonic_member_offsets) {
const auto out_of_order =
ordered_member_idx > 0 &&
(memberIdx < member_offsets[ordered_member_idx - 1].member);
if (out_of_order) {
return fail(memberIdx)
<< "at offset " << offset << " has a higher offset than member "
<< member_offsets[ordered_member_idx - 1].member << " at offset "
<< prevOffset;
}
}
if (offset < nextValidOffset)
return fail(memberIdx) << "at offset " << offset
<< " overlaps previous member ending at offset "
@ -483,7 +467,6 @@ spv_result_t checkLayout(uint32_t struct_id, const char* storage_class_str,
// or array.
nextValidOffset = align(nextValidOffset, alignment);
}
prevOffset = offset;
}
return SPV_SUCCESS;
}

View File

@ -176,8 +176,6 @@ ValidationState_t::ValidationState_t(const spv_const_context ctx,
const auto env = context_->target_env;
if (spvIsVulkanEnv(env)) {
features_.non_monotonic_struct_member_offsets = true;
// Vulkan 1.1 includes VK_KHR_relaxed_block_layout in core.
if (env != SPV_ENV_VULKAN_1_0) {
features_.env_relaxed_block_layout = true;

View File

@ -83,10 +83,6 @@ class ValidationState_t {
// Allow OpTypeInt with 8 bit width?
bool declare_int8_type = false;
// Allow non-monotonic offsets for struct members?
// Vulkan permits this.
bool non_monotonic_struct_member_offsets = false;
// Target environment uses relaxed block layout.
// This is true for Vulkan 1.1 or later.
bool env_relaxed_block_layout = false;

View File

@ -2522,7 +2522,7 @@ TEST_F(ValidateDecorations,
"offset 4 overlaps previous member ending at offset 15"));
}
TEST_F(ValidateDecorations, BlockLayoutOffsetOutOfOrderBadUniversal1_0) {
TEST_F(ValidateDecorations, BlockLayoutOffsetOutOfOrderGoodUniversal1_0) {
std::string spirv = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
@ -2547,17 +2547,11 @@ TEST_F(ValidateDecorations, BlockLayoutOffsetOutOfOrderBadUniversal1_0) {
)";
CompileSuccessfully(spirv);
EXPECT_EQ(SPV_ERROR_INVALID_ID,
EXPECT_EQ(SPV_SUCCESS,
ValidateAndRetrieveValidationState(SPV_ENV_UNIVERSAL_1_0));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr(
"Structure id 3 decorated as Block for variable in Uniform storage "
"class must follow standard uniform buffer layout rules: member 0 at "
"offset 4 has a higher offset than member 1 at offset 0"));
}
TEST_F(ValidateDecorations, BlockLayoutOffsetOutOfOrderBadOpenGL4_5) {
TEST_F(ValidateDecorations, BlockLayoutOffsetOutOfOrderGoodOpenGL4_5) {
std::string spirv = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
@ -2582,14 +2576,8 @@ TEST_F(ValidateDecorations, BlockLayoutOffsetOutOfOrderBadOpenGL4_5) {
)";
CompileSuccessfully(spirv);
EXPECT_EQ(SPV_ERROR_INVALID_ID,
EXPECT_EQ(SPV_SUCCESS,
ValidateAndRetrieveValidationState(SPV_ENV_OPENGL_4_5));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr(
"Structure id 3 decorated as Block for variable in Uniform storage "
"class must follow standard uniform buffer layout rules: member 0 at "
"offset 4 has a higher offset than member 1 at offset 0"));
}
TEST_F(ValidateDecorations, BlockLayoutOffsetOutOfOrderGoodVulkan1_1) {