From 8cd2a9d1878032c5b5f16097dae6f5e5f6b32b23 Mon Sep 17 00:00:00 2001 From: Ryan Harrison Date: Mon, 19 Nov 2018 14:32:18 -0500 Subject: [PATCH] Validate component literals for OpVectorShuffle in WebGPU environment (#2077) Validate component literals for OpVectorShuffle in WebGPU environment Fixes #2072 --- source/spirv_target_env.cpp | 28 +++++++++++++++++++++++++++ source/spirv_target_env.h | 3 +++ source/val/validate_composites.cpp | 9 +++++++++ test/val/val_id_test.cpp | 31 ++++++++++++++++++++++++++++++ 4 files changed, 71 insertions(+) diff --git a/source/spirv_target_env.cpp b/source/spirv_target_env.cpp index 631af6e22..a3aa0af03 100644 --- a/source/spirv_target_env.cpp +++ b/source/spirv_target_env.cpp @@ -220,3 +220,31 @@ bool spvIsOpenCLEnv(spv_target_env env) { } return false; } + +bool spvIsWebGPUEnv(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_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 false; + case SPV_ENV_WEBGPU_0: + return true; + } + return false; +} diff --git a/source/spirv_target_env.h b/source/spirv_target_env.h index fcf5faf28..d1bd83512 100644 --- a/source/spirv_target_env.h +++ b/source/spirv_target_env.h @@ -27,6 +27,9 @@ bool spvIsVulkanEnv(spv_target_env env); // Returns true if |env| is an OPENCL environment, false otherwise. bool spvIsOpenCLEnv(spv_target_env env); +// Returns true if |env| is an WEBGPU environment, false otherwise. +bool spvIsWebGPUEnv(spv_target_env env); + // Returns the version number for the given SPIR-V target environment. uint32_t spvVersionForTargetEnv(spv_target_env env); diff --git a/source/val/validate_composites.cpp b/source/val/validate_composites.cpp index 038873506..ccc558773 100644 --- a/source/val/validate_composites.cpp +++ b/source/val/validate_composites.cpp @@ -18,6 +18,7 @@ #include "source/diagnostic.h" #include "source/opcode.h" +#include "source/spirv_target_env.h" #include "source/val/instruction.h" #include "source/val/validation_state.h" @@ -464,10 +465,12 @@ spv_result_t ValidateVectorShuffle(ValidationState_t& _, } // All Component literals must either be FFFFFFFF or in [0, N - 1]. + // For WebGPU specifically, Component literals cannot be FFFFFFFF. auto vector1ComponentCount = vector1Type->GetOperandAs(2); auto vector2ComponentCount = vector2Type->GetOperandAs(2); auto N = vector1ComponentCount + vector2ComponentCount; auto firstLiteralIndex = 4; + const auto is_webgpu_env = spvIsWebGPUEnv(_.context()->target_env); for (size_t i = firstLiteralIndex; i < inst->operands().size(); ++i) { auto literal = inst->GetOperandAs(i); if (literal != 0xFFFFFFFF && literal >= N) { @@ -475,6 +478,12 @@ spv_result_t ValidateVectorShuffle(ValidationState_t& _, << "Component index " << literal << " is out of bounds for " << "combined (Vector1 + Vector2) size of " << N << "."; } + + if (is_webgpu_env && literal == 0xFFFFFFFF) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Component literal at operand " << i - firstLiteralIndex + << " cannot be 0xFFFFFFFF in WebGPU execution environment."; + } } return SPV_SUCCESS; diff --git a/test/val/val_id_test.cpp b/test/val/val_id_test.cpp index 0344dbc2c..dc36c27b7 100644 --- a/test/val/val_id_test.cpp +++ b/test/val/val_id_test.cpp @@ -4185,6 +4185,37 @@ TEST_F(ValidateIdWithMessage, OpVectorShuffleLiterals) { "size of 5.")); } +TEST_F(ValidateIdWithMessage, WebGPUOpVectorShuffle0xFFFFFFFFLiteralBad) { + std::string spirv = R"( + OpCapability Shader + OpMemoryModel Logical GLSL450 +%float = OpTypeFloat 32 +%vec2 = OpTypeVector %float 2 +%vec3 = OpTypeVector %float 3 +%vec4 = OpTypeVector %float 4 +%ptr_vec2 = OpTypePointer Function %vec2 +%ptr_vec3 = OpTypePointer Function %vec3 +%float_1 = OpConstant %float 1 +%float_2 = OpConstant %float 2 +%1 = OpConstantComposite %vec2 %float_2 %float_1 +%2 = OpConstantComposite %vec3 %float_1 %float_2 %float_2 +%3 = OpTypeFunction %vec4 +%4 = OpFunction %vec4 None %3 +%5 = OpLabel +%var = OpVariable %ptr_vec2 Function %1 +%var2 = OpVariable %ptr_vec3 Function %2 +%6 = OpLoad %vec2 %var +%7 = OpLoad %vec3 %var2 +%8 = OpVectorShuffle %vec4 %6 %7 4 3 1 0xffffffff + OpReturnValue %8 + OpFunctionEnd)"; + CompileSuccessfully(spirv.c_str(), SPV_ENV_WEBGPU_0); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_WEBGPU_0)); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Component literal at operand 3 cannot be 0xFFFFFFFF in" + " WebGPU execution environment.")); +} + // TODO: OpCompositeConstruct // TODO: OpCompositeExtract // TODO: OpCompositeInsert