Add WebGPU specific validation for FrontFacing BuiltIn decoration (#2330)
Part of resolving #2276
diff --git a/source/val/validate_builtins.cpp b/source/val/validate_builtins.cpp
index 1efac90..508c26b 100644
--- a/source/val/validate_builtins.cpp
+++ b/source/val/validate_builtins.cpp
@@ -1063,12 +1063,14 @@
spv_result_t BuiltInsValidator::ValidateFrontFacingAtDefinition(
const Decoration& decoration, const Instruction& inst) {
- if (spvIsVulkanEnv(_.context()->target_env)) {
+ if (spvIsVulkanOrWebGPUEnv(_.context()->target_env)) {
if (spv_result_t error = ValidateBool(
decoration, inst,
[this, &inst](const std::string& message) -> spv_result_t {
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
- << "According to the Vulkan spec BuiltIn FrontFacing "
+ << "According to the "
+ << spvLogStringForEnv(_.context()->target_env)
+ << " spec BuiltIn FrontFacing "
"variable needs to be a bool scalar. "
<< message;
})) {
@@ -1084,12 +1086,13 @@
const Decoration& decoration, const Instruction& built_in_inst,
const Instruction& referenced_inst,
const Instruction& referenced_from_inst) {
- if (spvIsVulkanEnv(_.context()->target_env)) {
+ if (spvIsVulkanOrWebGPUEnv(_.context()->target_env)) {
const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst);
if (storage_class != SpvStorageClassMax &&
storage_class != SpvStorageClassInput) {
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
- << "Vulkan spec allows BuiltIn FrontFacing to be only used for "
+ << spvLogStringForEnv(_.context()->target_env)
+ << " spec allows BuiltIn FrontFacing to be only used for "
"variables with Input storage class. "
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
referenced_from_inst)
@@ -1099,7 +1102,8 @@
for (const SpvExecutionModel execution_model : execution_models_) {
if (execution_model != SpvExecutionModelFragment) {
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
- << "Vulkan spec allows BuiltIn FrontFacing to be used only with "
+ << spvLogStringForEnv(_.context()->target_env)
+ << " spec allows BuiltIn FrontFacing to be used only with "
"Fragment execution model. "
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
referenced_from_inst, execution_model);
diff --git a/test/val/val_builtins_test.cpp b/test/val/val_builtins_test.cpp
index d72ab97..85459ed 100644
--- a/test/val/val_builtins_test.cpp
+++ b/test/val/val_builtins_test.cpp
@@ -599,6 +599,12 @@
Values("Input"), Values("%bool"), Values(TestResult())));
INSTANTIATE_TEST_SUITE_P(
+ FrontFacingSuccess,
+ ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult,
+ Combine(Values("FrontFacing"), Values("Fragment"), Values("Input"),
+ Values("%bool"), Values(TestResult())));
+
+INSTANTIATE_TEST_SUITE_P(
FrontFacingAndHelperInvocationNotFragment,
ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
Combine(
@@ -610,6 +616,15 @@
"to be used only with Fragment execution model"))));
INSTANTIATE_TEST_SUITE_P(
+ FrontFacingNotFragment,
+ ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult,
+ Combine(
+ Values("FrontFacing"), Values("Vertex", "GLCompute"), Values("Input"),
+ Values("%bool"),
+ Values(TestResult(SPV_ERROR_INVALID_DATA,
+ "to be used only with Fragment execution model"))));
+
+INSTANTIATE_TEST_SUITE_P(
FrontFacingAndHelperInvocationNotInput,
ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
Combine(Values("FrontFacing", "HelperInvocation"), Values("Fragment"),
@@ -620,6 +635,16 @@
"uses storage class Output"))));
INSTANTIATE_TEST_SUITE_P(
+ FrontFacingNotInput,
+ ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult,
+ Combine(Values("FrontFacing"), Values("Fragment"), Values("Output"),
+ Values("%bool"),
+ Values(TestResult(
+ SPV_ERROR_INVALID_DATA,
+ "to be only used for variables with Input storage class",
+ "uses storage class Output"))));
+
+INSTANTIATE_TEST_SUITE_P(
FrontFacingAndHelperInvocationNotBool,
ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
Combine(Values("FrontFacing", "HelperInvocation"), Values("Fragment"),
@@ -629,6 +654,15 @@
"is not a bool scalar"))));
INSTANTIATE_TEST_SUITE_P(
+ FrontFacingNotBool,
+ ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult,
+ Combine(Values("FrontFacing"), Values("Fragment"), Values("Input"),
+ Values("%f32", "%u32"),
+ Values(TestResult(SPV_ERROR_INVALID_DATA,
+ "needs to be a bool scalar",
+ "is not a bool scalar"))));
+
+INSTANTIATE_TEST_SUITE_P(
ComputeShaderInputInt32Vec3Success,
ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
Combine(Values("GlobalInvocationId", "LocalInvocationId", "NumWorkgroups",