New spirv-1.3 rules for control barrier

Fixes https://github.com/KhronosGroup/SPIRV-Tools/issues/1427

Adjusting validation to the new rule:
"Before version 1.3, it is only valid to use this instruction with
TessellationControl, GLCompute, or Kernel execution models.
There is no such restriction starting with version 1.3."

Also fixed wrong version numbers in source/spirv_target_env.cpp.
This commit is contained in:
Andrey Tuganov 2018-03-27 12:01:21 -04:00
parent 5e07ab1358
commit 95843d7bd0
3 changed files with 34 additions and 18 deletions

View File

@ -39,9 +39,9 @@ const char* spvTargetEnvDescription(spv_target_env env) {
case SPV_ENV_OPENCL_EMBEDDED_2_1:
return "SPIR-V 1.0 (under OpenCL 2.1 Embedded Profile semantics)";
case SPV_ENV_OPENCL_2_2:
return "SPIR-V 1.1 (under OpenCL 2.2 Full Profile semantics)";
return "SPIR-V 1.2 (under OpenCL 2.2 Full Profile semantics)";
case SPV_ENV_OPENCL_EMBEDDED_2_2:
return "SPIR-V 1.1 (under OpenCL 2.2 Embedded Profile semantics)";
return "SPIR-V 1.2 (under OpenCL 2.2 Embedded Profile semantics)";
case SPV_ENV_OPENGL_4_0:
return "SPIR-V 1.0 (under OpenCL 4.0 semantics)";
case SPV_ENV_OPENGL_4_1:

View File

@ -18,6 +18,7 @@
#include "diagnostic.h"
#include "opcode.h"
#include "spirv_constant.h"
#include "spirv_target_env.h"
#include "util/bitutils.h"
#include "val/instruction.h"
@ -172,20 +173,24 @@ spv_result_t BarriersPass(ValidationState_t& _,
switch (opcode) {
case SpvOpControlBarrier: {
_.current_function().RegisterExecutionModelLimitation(
[](SpvExecutionModel model, std::string* message) {
if (model != SpvExecutionModelTessellationControl &&
model != SpvExecutionModelGLCompute &&
model != SpvExecutionModelKernel) {
if (message) {
*message =
"OpControlBarrier requires one of the following Execution "
"Models: TessellationControl, GLCompute or Kernel";
if (spvVersionForTargetEnv(_.context()->target_env) <
SPV_SPIRV_VERSION_WORD(1, 3)) {
_.current_function().RegisterExecutionModelLimitation(
[](SpvExecutionModel model, std::string* message) {
if (model != SpvExecutionModelTessellationControl &&
model != SpvExecutionModelGLCompute &&
model != SpvExecutionModelKernel) {
if (message) {
*message =
"OpControlBarrier requires one of the following "
"Execution "
"Models: TessellationControl, GLCompute or Kernel";
}
return false;
}
return false;
}
return true;
});
return true;
});
}
const uint32_t execution_scope = inst->words[1];
const uint32_t memory_scope = inst->words[2];

View File

@ -202,19 +202,30 @@ OpControlBarrier %workgroup %workgroup %acquire_release_uniform_workgroup
ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
}
TEST_F(ValidateBarriers, OpControlBarrierExecutionModelFragment) {
TEST_F(ValidateBarriers, OpControlBarrierExecutionModelFragmentSpirv12) {
const std::string body = R"(
OpControlBarrier %device %device %none
)";
CompileSuccessfully(GenerateShaderCode(body, "", "Fragment"));
ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
CompileSuccessfully(GenerateShaderCode(body, "", "Fragment"),
SPV_ENV_UNIVERSAL_1_2);
ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_2));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr("OpControlBarrier requires one of the following Execution "
"Models: TessellationControl, GLCompute or Kernel"));
}
TEST_F(ValidateBarriers, OpControlBarrierExecutionModelFragmentSpirv13) {
const std::string body = R"(
OpControlBarrier %device %device %none
)";
CompileSuccessfully(GenerateShaderCode(body, "", "Fragment"),
SPV_ENV_UNIVERSAL_1_3);
ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
}
TEST_F(ValidateBarriers, OpControlBarrierFloatExecutionScope) {
const std::string body = R"(
OpControlBarrier %f32_1 %device %none