allow atomics on Function pointers for OpenCL (#1955)

This commit is contained in:
Ben Ashbaugh 2018-10-09 08:33:01 -07:00 committed by alan-baker
parent 03cbf33a69
commit d3f88b0841
4 changed files with 74 additions and 7 deletions

View File

@ -195,3 +195,31 @@ bool spvIsVulkanEnv(spv_target_env env) {
}
return false;
}
bool spvIsOpenCLEnv(spv_target_env env) {
switch (env) {
case SPV_ENV_UNIVERSAL_1_0:
case SPV_ENV_VULKAN_1_0:
case SPV_ENV_UNIVERSAL_1_1:
case SPV_ENV_OPENGL_4_0:
case SPV_ENV_OPENGL_4_1:
case SPV_ENV_OPENGL_4_2:
case SPV_ENV_OPENGL_4_3:
case SPV_ENV_OPENGL_4_5:
case SPV_ENV_UNIVERSAL_1_2:
case SPV_ENV_UNIVERSAL_1_3:
case SPV_ENV_VULKAN_1_1:
case SPV_ENV_WEBGPU_0:
return false;
case SPV_ENV_OPENCL_1_2:
case SPV_ENV_OPENCL_EMBEDDED_1_2:
case SPV_ENV_OPENCL_2_0:
case SPV_ENV_OPENCL_EMBEDDED_2_0:
case SPV_ENV_OPENCL_EMBEDDED_2_1:
case SPV_ENV_OPENCL_EMBEDDED_2_2:
case SPV_ENV_OPENCL_2_1:
case SPV_ENV_OPENCL_2_2:
return true;
}
return false;
}

View File

@ -24,6 +24,9 @@ bool spvParseTargetEnv(const char* s, spv_target_env* env);
// Returns true if |env| is a VULKAN environment, false otherwise.
bool spvIsVulkanEnv(spv_target_env env);
// Returns true if |env| is an OPENCL environment, false otherwise.
bool spvIsOpenCLEnv(spv_target_env env);
// Returns the version number for the given SPIR-V target environment.
uint32_t spvVersionForTargetEnv(spv_target_env env);

View File

@ -252,11 +252,21 @@ spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) {
case SpvStorageClassStorageBuffer:
break;
default:
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< spvOpcodeString(opcode)
<< ": expected Pointer Storage Class to be Uniform, "
"Workgroup, CrossWorkgroup, Generic, AtomicCounter, Image "
"or StorageBuffer";
if (spvIsOpenCLEnv(_.context()->target_env)) {
if (storage_class != SpvStorageClassFunction) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< spvOpcodeString(opcode)
<< ": expected Pointer Storage Class to be Uniform, "
"Workgroup, CrossWorkgroup, Generic, AtomicCounter, "
"Image, StorageBuffer or Function";
}
} else {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< spvOpcodeString(opcode)
<< ": expected Pointer Storage Class to be Uniform, "
"Workgroup, CrossWorkgroup, Generic, AtomicCounter, "
"Image or StorageBuffer";
}
}
if (opcode == SpvOpAtomicFlagTestAndSet ||

View File

@ -159,6 +159,8 @@ OpMemoryModel Physical32 OpenCL
%f32vec4_var = OpVariable %f32vec4_ptr Workgroup
%f32_ptr_function = OpTypePointer Function %f32
%f32_ptr_uniformconstant = OpTypePointer UniformConstant %f32
%f32_uc_var = OpVariable %f32_ptr_uniformconstant UniformConstant
%main = OpFunction %void None %func
%main_entry = OpLabel
@ -205,6 +207,31 @@ TEST_F(ValidateAtomics, AtomicLoadVulkanSuccess) {
ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
}
TEST_F(ValidateAtomics, AtomicStoreOpenCLFunctionPointerStorageTypeSuccess) {
const std::string body = R"(
%f32_var_function = OpVariable %f32_ptr_function Function
OpAtomicStore %f32_var_function %device %relaxed %f32_1
)";
CompileSuccessfully(GenerateKernelCode(body), SPV_ENV_OPENCL_1_2);
ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_OPENCL_1_2));
}
TEST_F(ValidateAtomics, AtomicStoreVulkanFunctionPointerStorageType) {
const std::string body = R"(
%f32_var_function = OpVariable %f32_ptr_function Function
OpAtomicStore %f32_var_function %device %relaxed %f32_1
)";
CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0);
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr("AtomicStore: expected Pointer Storage Class to be Uniform, "
"Workgroup, CrossWorkgroup, Generic, AtomicCounter, Image or "
"StorageBuffer"));
}
// TODO(atgoo@github.com): the corresponding check fails Vulkan CTS,
// reenable once fixed.
TEST_F(ValidateAtomics, DISABLED_AtomicLoadVulkanSubgroup) {
@ -488,8 +515,7 @@ OpAtomicStore %f32vec4_var %device %relaxed %f32_1
TEST_F(ValidateAtomics, AtomicStoreWrongPointerStorageType) {
const std::string body = R"(
%f32_var_function = OpVariable %f32_ptr_function Function
OpAtomicStore %f32_var_function %device %relaxed %f32_1
OpAtomicStore %f32_uc_var %device %relaxed %f32_1
)";
CompileSuccessfully(GenerateKernelCode(body));