spirv-val: Add Vulkan FP Mode VUID (#4088)

This commit is contained in:
sfricke-samsung 2021-01-06 09:45:28 -08:00 коммит произвёл GitHub
Родитель 6d05ed8410
Коммит 94d1a80159
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 104 добавлений и 2 удалений

Просмотреть файл

@ -1260,7 +1260,8 @@ spv_result_t CheckVulkanMemoryModelDeprecatedDecorations(
// decorations. Otherwise emits a diagnostic and returns something other than
// SPV_SUCCESS.
spv_result_t CheckFPRoundingModeForShaders(ValidationState_t& vstate,
const Instruction& inst) {
const Instruction& inst,
const Decoration& decoration) {
// Validates width-only conversion instruction for floating-point object
// i.e., OpFConvert
if (inst.opcode() != SpvOpFConvert) {
@ -1270,6 +1271,15 @@ spv_result_t CheckFPRoundingModeForShaders(ValidationState_t& vstate,
"object.";
}
if (spvIsVulkanEnv(vstate.context()->target_env)) {
const auto mode = decoration.params()[0];
if ((mode != SpvFPRoundingModeRTE) && (mode != SpvFPRoundingModeRTZ)) {
return vstate.diag(SPV_ERROR_INVALID_ID, &inst)
<< vstate.VkErrorID(4675)
<< "In Vulkan, the FPRoundingMode mode must only by RTE or RTZ.";
}
}
// Validates Object operand of an OpStore
for (const auto& use : inst.uses()) {
const auto store = use.first;
@ -1588,7 +1598,8 @@ spv_result_t CheckDecorationsFromDecoration(ValidationState_t& vstate) {
break;
case SpvDecorationFPRoundingMode:
if (is_shader)
PASS_OR_BAIL(CheckFPRoundingModeForShaders(vstate, *inst));
PASS_OR_BAIL(
CheckFPRoundingModeForShaders(vstate, *inst, decoration));
break;
case SpvDecorationNonWritable:
PASS_OR_BAIL(CheckNonWritableDecoration(vstate, *inst, decoration));

Просмотреть файл

@ -1671,6 +1671,8 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
return VUID_WRAP(VUID-StandaloneSpirv-OpTypeImage-04656);
case 4658:
return VUID_WRAP(VUID-StandaloneSpirv-OpImageTexelPointer-04658);
case 4675:
return VUID_WRAP(VUID-StandaloneSpirv-FPRoundingMode-04675);
case 4685:
return VUID_WRAP(VUID-StandaloneSpirv-OpGroupNonUniformBallotBitCount-04685);
case 4711:

Просмотреть файл

@ -4679,6 +4679,95 @@ OpFunctionEnd
"Object operand of an OpStore."));
}
TEST_F(ValidateDecorations, VulkanFPRoundingModeGood) {
std::string spirv = R"(
OpCapability Shader
OpCapability StorageBuffer16BitAccess
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %main "main" %_
OpExecutionMode %main LocalSize 1 1 1
OpMemberDecorate %ssbo 0 Offset 0
OpDecorate %ssbo Block
OpDecorate %_ DescriptorSet 0
OpDecorate %_ Binding 0
OpDecorate %17 FPRoundingMode RTE
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
%_ptr_Function_float = OpTypePointer Function %float
%float_1 = OpConstant %float 1
%half = OpTypeFloat 16
%ssbo = OpTypeStruct %half
%_ptr_StorageBuffer_ssbo = OpTypePointer StorageBuffer %ssbo
%_ = OpVariable %_ptr_StorageBuffer_ssbo StorageBuffer
%int = OpTypeInt 32 1
%int_0 = OpConstant %int 0
%_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
%main = OpFunction %void None %3
%5 = OpLabel
%b = OpVariable %_ptr_Function_float Function
OpStore %b %float_1
%16 = OpLoad %float %b
%17 = OpFConvert %half %16
%19 = OpAccessChain %_ptr_StorageBuffer_half %_ %int_0
OpStore %19 %17
OpReturn
OpFunctionEnd
)";
CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_2);
EXPECT_EQ(SPV_SUCCESS,
ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_2));
}
TEST_F(ValidateDecorations, VulkanFPRoundingModeBadMode) {
std::string spirv = R"(
OpCapability Shader
OpCapability StorageBuffer16BitAccess
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %main "main" %_
OpExecutionMode %main LocalSize 1 1 1
OpMemberDecorate %ssbo 0 Offset 0
OpDecorate %ssbo Block
OpDecorate %_ DescriptorSet 0
OpDecorate %_ Binding 0
OpDecorate %17 FPRoundingMode RTP
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
%_ptr_Function_float = OpTypePointer Function %float
%float_1 = OpConstant %float 1
%half = OpTypeFloat 16
%ssbo = OpTypeStruct %half
%_ptr_StorageBuffer_ssbo = OpTypePointer StorageBuffer %ssbo
%_ = OpVariable %_ptr_StorageBuffer_ssbo StorageBuffer
%int = OpTypeInt 32 1
%int_0 = OpConstant %int 0
%_ptr_StorageBuffer_half = OpTypePointer StorageBuffer %half
%main = OpFunction %void None %3
%5 = OpLabel
%b = OpVariable %_ptr_Function_float Function
OpStore %b %float_1
%16 = OpLoad %float %b
%17 = OpFConvert %half %16
%19 = OpAccessChain %_ptr_StorageBuffer_half %_ %int_0
OpStore %19 %17
OpReturn
OpFunctionEnd
)";
CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_2);
EXPECT_EQ(SPV_ERROR_INVALID_ID,
ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_2));
EXPECT_THAT(getDiagnosticString(),
AnyVUID("VUID-StandaloneSpirv-FPRoundingMode-04675"));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr("In Vulkan, the FPRoundingMode mode must only by RTE or RTZ."));
}
TEST_F(ValidateDecorations, GroupDecorateTargetsDecorationGroup) {
std::string spirv = R"(
OpCapability Shader