diff --git a/Android.mk b/Android.mk index 0b64ea6d6e..1000f4221b 100644 --- a/Android.mk +++ b/Android.mk @@ -93,7 +93,6 @@ SPVTOOLS_OPT_SRC_FILES := \ source/opt/dead_branch_elim_pass.cpp \ source/opt/dead_insert_elim_pass.cpp \ source/opt/dead_variable_elimination.cpp \ - source/opt/decompose_initialized_variables_pass.cpp \ source/opt/decoration_manager.cpp \ source/opt/debug_info_manager.cpp \ source/opt/def_use_manager.cpp \ @@ -112,7 +111,6 @@ SPVTOOLS_OPT_SRC_FILES := \ source/opt/fold_spec_constant_op_and_composite_pass.cpp \ source/opt/freeze_spec_constant_value_pass.cpp \ source/opt/function.cpp \ - source/opt/generate_webgpu_initializers_pass.cpp \ source/opt/graphics_robust_access_pass.cpp \ source/opt/if_conversion.cpp \ source/opt/inline_pass.cpp \ @@ -126,7 +124,6 @@ SPVTOOLS_OPT_SRC_FILES := \ source/opt/instrument_pass.cpp \ source/opt/ir_context.cpp \ source/opt/ir_loader.cpp \ - source/opt/legalize_vector_shuffle_pass.cpp \ source/opt/licm_pass.cpp \ source/opt/local_access_chain_convert_pass.cpp \ source/opt/local_redundancy_elimination.cpp \ @@ -161,10 +158,8 @@ SPVTOOLS_OPT_SRC_FILES := \ source/opt/scalar_replacement_pass.cpp \ source/opt/set_spec_constant_default_value_pass.cpp \ source/opt/simplification_pass.cpp \ - source/opt/split_invalid_unreachable_pass.cpp \ source/opt/ssa_rewrite_pass.cpp \ source/opt/strength_reduction_pass.cpp \ - source/opt/strip_atomic_counter_memory_pass.cpp \ source/opt/strip_debug_info_pass.cpp \ source/opt/strip_reflect_info_pass.cpp \ source/opt/struct_cfg_analysis.cpp \ diff --git a/BUILD.gn b/BUILD.gn index 2387fc6ae8..845eb29e7c 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -539,8 +539,6 @@ static_library("spvtools_opt") { "source/opt/dead_insert_elim_pass.h", "source/opt/dead_variable_elimination.cpp", "source/opt/dead_variable_elimination.h", - "source/opt/decompose_initialized_variables_pass.cpp", - "source/opt/decompose_initialized_variables_pass.h", "source/opt/decoration_manager.cpp", "source/opt/decoration_manager.h", "source/opt/debug_info_manager.cpp", @@ -578,8 +576,6 @@ static_library("spvtools_opt") { "source/opt/freeze_spec_constant_value_pass.h", "source/opt/function.cpp", "source/opt/function.h", - "source/opt/generate_webgpu_initializers_pass.cpp", - "source/opt/generate_webgpu_initializers_pass.h", "source/opt/graphics_robust_access_pass.cpp", "source/opt/graphics_robust_access_pass.h", "source/opt/if_conversion.cpp", @@ -608,8 +604,6 @@ static_library("spvtools_opt") { "source/opt/ir_loader.cpp", "source/opt/ir_loader.h", "source/opt/iterator.h", - "source/opt/legalize_vector_shuffle_pass.cpp", - "source/opt/legalize_vector_shuffle_pass.h", "source/opt/licm_pass.cpp", "source/opt/licm_pass.h", "source/opt/local_access_chain_convert_pass.cpp", @@ -680,14 +674,10 @@ static_library("spvtools_opt") { "source/opt/set_spec_constant_default_value_pass.h", "source/opt/simplification_pass.cpp", "source/opt/simplification_pass.h", - "source/opt/split_invalid_unreachable_pass.cpp", - "source/opt/split_invalid_unreachable_pass.h", "source/opt/ssa_rewrite_pass.cpp", "source/opt/ssa_rewrite_pass.h", "source/opt/strength_reduction_pass.cpp", "source/opt/strength_reduction_pass.h", - "source/opt/strip_atomic_counter_memory_pass.cpp", - "source/opt/strip_atomic_counter_memory_pass.h", "source/opt/strip_debug_info_pass.cpp", "source/opt/strip_debug_info_pass.h", "source/opt/strip_reflect_info_pass.cpp", diff --git a/README.md b/README.md index 44f582fb8a..3637305bae 100644 --- a/README.md +++ b/README.md @@ -136,7 +136,6 @@ As of this writing, there are 67 transforms including examples such as: * Loop-invariant code motion * Loop unroll * Other - * Generate WebGPU initializers * Graphics robust access * Upgrade memory model to VulkanKHR diff --git a/include/spirv-tools/libspirv.h b/include/spirv-tools/libspirv.h index a0114c3f4b..8f412a6684 100644 --- a/include/spirv-tools/libspirv.h +++ b/include/spirv-tools/libspirv.h @@ -482,7 +482,7 @@ typedef enum { SPV_ENV_OPENCL_EMBEDDED_2_2, // OpenCL Embedded Profile 2.2 latest revision. SPV_ENV_UNIVERSAL_1_3, // SPIR-V 1.3 latest revision, no other restrictions. SPV_ENV_VULKAN_1_1, // Vulkan 1.1 latest revision. - SPV_ENV_WEBGPU_0, // Work in progress WebGPU 1.0. + SPV_ENV_WEBGPU_0, // DEPRECATED, may be removed in the future. SPV_ENV_UNIVERSAL_1_4, // SPIR-V 1.4 latest revision, no other restrictions. // Vulkan 1.1 with VK_KHR_spirv_1_4, i.e. SPIR-V 1.4 binary. diff --git a/include/spirv-tools/optimizer.hpp b/include/spirv-tools/optimizer.hpp index 27352b2505..1683d077f5 100644 --- a/include/spirv-tools/optimizer.hpp +++ b/include/spirv-tools/optimizer.hpp @@ -68,11 +68,6 @@ class Optimizer { // The instance will have an empty message consumer, which ignores all // messages from the library. Use SetMessageConsumer() to supply a consumer // if messages are of concern. - // - // For collections of passes that are meant to transform the input into - // another execution environment, then the source environment should be - // supplied. e.g. for VulkanToWebGPUPasses the environment should be - // SPV_ENV_VULKAN_1_1 not SPV_ENV_WEBGPU_0. explicit Optimizer(spv_target_env env); // Disables copy/move constructor/assignment operations. @@ -106,16 +101,6 @@ class Optimizer { // from time to time. Optimizer& RegisterSizePasses(); - // Registers passes that have been prescribed for converting from Vulkan to - // WebGPU. This sequence of passes is subject to constant review and will - // change from time to time. - Optimizer& RegisterVulkanToWebGPUPasses(); - - // Registers passes that have been prescribed for converting from WebGPU to - // Vulkan. This sequence of passes is subject to constant review and will - // change from time to time. - Optimizer& RegisterWebGPUToVulkanPasses(); - // Registers passes that attempt to legalize the generated code. // // Note: this recipe is specially designed for legalizing SPIR-V. It should be @@ -238,13 +223,6 @@ class Optimizer { // A null pass does nothing to the SPIR-V module to be optimized. Optimizer::PassToken CreateNullPass(); -// Creates a strip-atomic-counter-memory pass. -// A strip-atomic-counter-memory pass removes all usages of the -// AtomicCounterMemory bit in Memory Semantics bitmasks. This bit is a no-op in -// Vulkan, so isn't needed in that env. And the related capability is not -// allowed in WebGPU, so it is not allowed in that env. -Optimizer::PassToken CreateStripAtomicCounterMemoryPass(); - // Creates a strip-debug-info pass. // A strip-debug-info pass removes all debug instructions (as documented in // Section 3.32.2 of the SPIR-V spec) of the SPIR-V module to be optimized. @@ -802,30 +780,11 @@ Optimizer::PassToken CreateUpgradeMemoryModelPass(); // where an instruction is moved into a more deeply nested construct. Optimizer::PassToken CreateCodeSinkingPass(); -// Create a pass to adds initializers for OpVariable calls that require them -// in WebGPU. Currently this pass naively initializes variables that are -// missing an initializer with a null value. In the future it may initialize -// variables to the first value stored in them, if that is a constant. -Optimizer::PassToken CreateGenerateWebGPUInitializersPass(); - // Create a pass to fix incorrect storage classes. In order to make code // generation simpler, DXC may generate code where the storage classes do not // match up correctly. This pass will fix the errors that it can. Optimizer::PassToken CreateFixStorageClassPass(); -// Create a pass to legalize OpVectorShuffle operands going into WebGPU. WebGPU -// forbids using 0xFFFFFFFF, which indicates an undefined result, so this pass -// converts those literals to 0. -Optimizer::PassToken CreateLegalizeVectorShufflePass(); - -// Create a pass to decompose initialized variables into a seperate variable -// declaration and an initial store. -Optimizer::PassToken CreateDecomposeInitializedVariablesPass(); - -// Create a pass to attempt to split up invalid unreachable merge-blocks and -// continue-targets to legalize for WebGPU. -Optimizer::PassToken CreateSplitInvalidUnreachablePass(); - // Creates a graphics robust access pass. // // This pass injects code to clamp indexed accesses to buffers and internal diff --git a/source/ext_inst.cpp b/source/ext_inst.cpp index 3471ebe0d2..795cb0f3f7 100644 --- a/source/ext_inst.cpp +++ b/source/ext_inst.cpp @@ -89,7 +89,6 @@ spv_result_t spvExtInstTableGet(spv_ext_inst_table* pExtInstTable, case SPV_ENV_UNIVERSAL_1_3: case SPV_ENV_VULKAN_1_1: case SPV_ENV_VULKAN_1_1_SPIRV_1_4: - case SPV_ENV_WEBGPU_0: case SPV_ENV_UNIVERSAL_1_4: case SPV_ENV_UNIVERSAL_1_5: case SPV_ENV_VULKAN_1_2: diff --git a/source/libspirv.cpp b/source/libspirv.cpp index a1ed11d3fb..0bc0935083 100644 --- a/source/libspirv.cpp +++ b/source/libspirv.cpp @@ -14,8 +14,8 @@ #include "spirv-tools/libspirv.hpp" +#include #include - #include #include #include @@ -60,7 +60,9 @@ struct SpirvTools::Impl { spv_context context; // C interface context object. }; -SpirvTools::SpirvTools(spv_target_env env) : impl_(new Impl(env)) {} +SpirvTools::SpirvTools(spv_target_env env) : impl_(new Impl(env)) { + assert(env != SPV_ENV_WEBGPU_0); +} SpirvTools::~SpirvTools() {} diff --git a/source/opt/CMakeLists.txt b/source/opt/CMakeLists.txt index f3ac59060c..14a6bee7dc 100644 --- a/source/opt/CMakeLists.txt +++ b/source/opt/CMakeLists.txt @@ -32,7 +32,6 @@ set(SPIRV_TOOLS_OPT_SOURCES dead_branch_elim_pass.h dead_insert_elim_pass.h dead_variable_elimination.h - decompose_initialized_variables_pass.h decoration_manager.h debug_info_manager.h def_use_manager.h @@ -52,7 +51,6 @@ set(SPIRV_TOOLS_OPT_SOURCES fold_spec_constant_op_and_composite_pass.h freeze_spec_constant_value_pass.h function.h - generate_webgpu_initializers_pass.h graphics_robust_access_pass.h if_conversion.h inline_exhaustive_pass.h @@ -103,10 +101,8 @@ set(SPIRV_TOOLS_OPT_SOURCES scalar_replacement_pass.h set_spec_constant_default_value_pass.h simplification_pass.h - split_invalid_unreachable_pass.h ssa_rewrite_pass.h strength_reduction_pass.h - strip_atomic_counter_memory_pass.h strip_debug_info_pass.h strip_reflect_info_pass.h struct_cfg_analysis.h @@ -140,7 +136,6 @@ set(SPIRV_TOOLS_OPT_SOURCES dead_branch_elim_pass.cpp dead_insert_elim_pass.cpp dead_variable_elimination.cpp - decompose_initialized_variables_pass.cpp decoration_manager.cpp debug_info_manager.cpp def_use_manager.cpp @@ -160,7 +155,6 @@ set(SPIRV_TOOLS_OPT_SOURCES freeze_spec_constant_value_pass.cpp function.cpp graphics_robust_access_pass.cpp - generate_webgpu_initializers_pass.cpp if_conversion.cpp inline_exhaustive_pass.cpp inline_opaque_pass.cpp @@ -173,7 +167,6 @@ set(SPIRV_TOOLS_OPT_SOURCES instrument_pass.cpp ir_context.cpp ir_loader.cpp - legalize_vector_shuffle_pass.cpp licm_pass.cpp local_access_chain_convert_pass.cpp local_redundancy_elimination.cpp @@ -208,10 +201,8 @@ set(SPIRV_TOOLS_OPT_SOURCES scalar_replacement_pass.cpp set_spec_constant_default_value_pass.cpp simplification_pass.cpp - split_invalid_unreachable_pass.cpp ssa_rewrite_pass.cpp strength_reduction_pass.cpp - strip_atomic_counter_memory_pass.cpp strip_debug_info_pass.cpp strip_reflect_info_pass.cpp struct_cfg_analysis.cpp diff --git a/source/opt/decompose_initialized_variables_pass.cpp b/source/opt/decompose_initialized_variables_pass.cpp deleted file mode 100644 index 875bf7e85c..0000000000 --- a/source/opt/decompose_initialized_variables_pass.cpp +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (c) 2019 Google LLC. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "source/opt/decompose_initialized_variables_pass.h" - -#include "source/opt/ir_context.h" - -namespace spvtools { -namespace opt { - -using inst_iterator = InstructionList::iterator; - -namespace { - -bool HasInitializer(Instruction* inst) { - if (inst->opcode() != SpvOpVariable) return false; - if (inst->NumOperands() < 4) return false; - - return true; -} - -} // namespace - -Pass::Status DecomposeInitializedVariablesPass::Process() { - auto* module = context()->module(); - std::unordered_set changed; - - std::vector> global_stores; - for (auto iter = module->types_values_begin(); - iter != module->types_values_end(); ++iter) { - Instruction* inst = &(*iter); - if (!HasInitializer(inst)) continue; - - auto var_id = inst->result_id(); - auto val_id = inst->GetOperand(3).words[0]; - global_stores.push_back(std::make_tuple(var_id, val_id)); - iter->RemoveOperand(3); - changed.insert(&*iter); - } - - std::unordered_set entry_ids; - for (auto entry = module->entry_points().begin(); - entry != module->entry_points().end(); ++entry) { - entry_ids.insert(entry->GetSingleWordInOperand(1)); - } - - for (auto func = module->begin(); func != module->end(); ++func) { - std::vector function_stores; - auto first_block = func->entry().get(); - inst_iterator insert_point = first_block->begin(); - for (auto iter = first_block->begin(); - iter != first_block->end() && iter->opcode() == SpvOpVariable; - ++iter) { - // For valid SPIRV-V, there is guaranteed to be at least one instruction - // after the OpVariable instructions. - insert_point = (*iter).NextNode(); - Instruction* inst = &(*iter); - if (!HasInitializer(inst)) continue; - - auto var_id = inst->result_id(); - auto val_id = inst->GetOperand(3).words[0]; - Instruction* store_inst = new Instruction( - context(), SpvOpStore, 0, 0, - {{SPV_OPERAND_TYPE_ID, {var_id}}, {SPV_OPERAND_TYPE_ID, {val_id}}}); - function_stores.push_back(store_inst); - iter->RemoveOperand(3); - changed.insert(&*iter); - } - - if (entry_ids.find(func->result_id()) != entry_ids.end()) { - for (auto store_ids : global_stores) { - uint32_t var_id; - uint32_t val_id; - std::tie(var_id, val_id) = store_ids; - auto* store_inst = new Instruction( - context(), SpvOpStore, 0, 0, - {{SPV_OPERAND_TYPE_ID, {var_id}}, {SPV_OPERAND_TYPE_ID, {val_id}}}); - context()->set_instr_block(store_inst, &*first_block); - first_block->AddInstruction(std::unique_ptr(store_inst)); - store_inst->InsertBefore(&*insert_point); - changed.insert(store_inst); - } - } - - for (auto store = function_stores.begin(); store != function_stores.end(); - ++store) { - context()->set_instr_block(*store, first_block); - (*store)->InsertBefore(&*insert_point); - changed.insert(*store); - } - } - - auto* def_use_mgr = get_def_use_mgr(); - for (auto* inst : changed) def_use_mgr->UpdateDefUse(inst); - - return !changed.empty() ? Pass::Status::SuccessWithChange - : Pass::Status::SuccessWithoutChange; -} - -} // namespace opt -} // namespace spvtools diff --git a/source/opt/decompose_initialized_variables_pass.h b/source/opt/decompose_initialized_variables_pass.h deleted file mode 100644 index c0bd35e760..0000000000 --- a/source/opt/decompose_initialized_variables_pass.h +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) 2019 Google LLC. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef SOURCE_OPT_DECOMPOSE_INITALIZED_VAIRABLES_PASS_H_ -#define SOURCE_OPT_DECOMPOSE_INITALIZED_VAIRABLES_PASS_H_ - -#include "source/opt/ir_context.h" -#include "source/opt/module.h" -#include "source/opt/pass.h" - -namespace spvtools { -namespace opt { - -// Converts variable declartions with initializers into seperate declaration and -// assignment statements. This is done due to known issues with some Vulkan -// implementations' handling of initialized variables. -// -// Only decomposes variables with storage classes that are valid in Vulkan -// execution environments; Output, Private, and Function. -// Currently only Function is implemented. -class DecomposeInitializedVariablesPass : public Pass { - public: - const char* name() const override { - return "decompose-initialized-variables"; - } - Status Process() override; - - IRContext::Analysis GetPreservedAnalyses() override { - return IRContext::kAnalysisInstrToBlockMapping | - IRContext::kAnalysisDecorations | IRContext::kAnalysisCombinators | - IRContext::kAnalysisCFG | IRContext::kAnalysisDominatorAnalysis | - IRContext::kAnalysisLoopAnalysis | IRContext::kAnalysisNameMap | - IRContext::kAnalysisScalarEvolution | - IRContext::kAnalysisRegisterPressure | - IRContext::kAnalysisValueNumberTable | - IRContext::kAnalysisStructuredCFG | - IRContext::kAnalysisBuiltinVarId | - IRContext::kAnalysisIdToFuncMapping | IRContext::kAnalysisTypes | - IRContext::kAnalysisDefUse | IRContext::kAnalysisConstants; - } -}; - -} // namespace opt -} // namespace spvtools - -#endif // SOURCE_OPT_DECOMPOSE_INITALIZED_VAIRABLES_PASS_H_ diff --git a/source/opt/generate_webgpu_initializers_pass.cpp b/source/opt/generate_webgpu_initializers_pass.cpp deleted file mode 100644 index eaed3c28e2..0000000000 --- a/source/opt/generate_webgpu_initializers_pass.cpp +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright (c) 2019 Google LLC. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "source/opt/generate_webgpu_initializers_pass.h" -#include "source/opt/ir_context.h" - -namespace spvtools { -namespace opt { - -using inst_iterator = InstructionList::iterator; - -namespace { - -bool NeedsWebGPUInitializer(Instruction* inst) { - if (inst->opcode() != SpvOpVariable) return false; - - auto storage_class = inst->GetSingleWordOperand(2); - if (storage_class != SpvStorageClassOutput && - storage_class != SpvStorageClassPrivate && - storage_class != SpvStorageClassFunction) { - return false; - } - - if (inst->NumOperands() > 3) return false; - - return true; -} - -} // namespace - -Pass::Status GenerateWebGPUInitializersPass::Process() { - auto* module = context()->module(); - bool changed = false; - - // Handle global/module scoped variables - for (auto iter = module->types_values_begin(); - iter != module->types_values_end(); ++iter) { - Instruction* inst = &(*iter); - - if (inst->opcode() == SpvOpConstantNull) { - null_constant_type_map_[inst->type_id()] = inst; - seen_null_constants_.insert(inst); - continue; - } - - if (!NeedsWebGPUInitializer(inst)) continue; - - changed = true; - - auto* constant_inst = GetNullConstantForVariable(inst); - if (!constant_inst) return Status::Failure; - - if (seen_null_constants_.find(constant_inst) == - seen_null_constants_.end()) { - constant_inst->InsertBefore(inst); - null_constant_type_map_[inst->type_id()] = inst; - seen_null_constants_.insert(inst); - } - AddNullInitializerToVariable(constant_inst, inst); - } - - // Handle local/function scoped variables - for (auto func = module->begin(); func != module->end(); ++func) { - auto block = func->entry().get(); - for (auto iter = block->begin(); - iter != block->end() && iter->opcode() == SpvOpVariable; ++iter) { - Instruction* inst = &(*iter); - if (!NeedsWebGPUInitializer(inst)) continue; - - changed = true; - auto* constant_inst = GetNullConstantForVariable(inst); - if (!constant_inst) return Status::Failure; - - AddNullInitializerToVariable(constant_inst, inst); - } - } - - return changed ? Status::SuccessWithChange : Status::SuccessWithoutChange; -} - -Instruction* GenerateWebGPUInitializersPass::GetNullConstantForVariable( - Instruction* variable_inst) { - auto constant_mgr = context()->get_constant_mgr(); - auto* def_use_mgr = get_def_use_mgr(); - - auto* ptr_inst = def_use_mgr->GetDef(variable_inst->type_id()); - auto type_id = ptr_inst->GetInOperand(1).words[0]; - if (null_constant_type_map_.find(type_id) == null_constant_type_map_.end()) { - auto* constant_type = context()->get_type_mgr()->GetType(type_id); - auto* constant = constant_mgr->GetConstant(constant_type, {}); - return constant_mgr->GetDefiningInstruction(constant, type_id); - } else { - return null_constant_type_map_[type_id]; - } -} - -void GenerateWebGPUInitializersPass::AddNullInitializerToVariable( - Instruction* constant_inst, Instruction* variable_inst) { - auto constant_id = constant_inst->result_id(); - variable_inst->AddOperand(Operand(SPV_OPERAND_TYPE_ID, {constant_id})); - get_def_use_mgr()->AnalyzeInstUse(variable_inst); -} - -} // namespace opt -} // namespace spvtools diff --git a/source/opt/generate_webgpu_initializers_pass.h b/source/opt/generate_webgpu_initializers_pass.h deleted file mode 100644 index f95e84c5b0..0000000000 --- a/source/opt/generate_webgpu_initializers_pass.h +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) 2019 Google LLC. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef SOURCE_OPT_GENERATE_WEBGPU_INITIALIZERS_PASS_H_ -#define SOURCE_OPT_GENERATE_WEBGPU_INITIALIZERS_PASS_H_ - -#include "source/opt/ir_context.h" -#include "source/opt/module.h" -#include "source/opt/pass.h" - -namespace spvtools { -namespace opt { - -// Adds initializers to variables with storage classes Output, Private, and -// Function if they are missing. In the WebGPU environment these storage classes -// require that the variables are initialized. Currently they are initialized to -// NULL, though in the future some of them may be initialized to the first value -// that is stored in them, if that was a constant. -class GenerateWebGPUInitializersPass : public Pass { - public: - const char* name() const override { return "generate-webgpu-initializers"; } - Status Process() override; - - IRContext::Analysis GetPreservedAnalyses() override { - return IRContext::kAnalysisInstrToBlockMapping | - IRContext::kAnalysisDecorations | IRContext::kAnalysisCombinators | - IRContext::kAnalysisCFG | IRContext::kAnalysisDominatorAnalysis | - IRContext::kAnalysisLoopAnalysis | IRContext::kAnalysisNameMap | - IRContext::kAnalysisScalarEvolution | - IRContext::kAnalysisRegisterPressure | - IRContext::kAnalysisValueNumberTable | - IRContext::kAnalysisStructuredCFG | - IRContext::kAnalysisBuiltinVarId | - IRContext::kAnalysisIdToFuncMapping | IRContext::kAnalysisTypes | - IRContext::kAnalysisDefUse | IRContext::kAnalysisConstants; - } - - private: - using NullConstantTypeMap = std::unordered_map; - NullConstantTypeMap null_constant_type_map_; - std::unordered_set seen_null_constants_; - - Instruction* GetNullConstantForVariable(Instruction* variable_inst); - void AddNullInitializerToVariable(Instruction* constant_inst, - Instruction* variable_inst); -}; - -} // namespace opt -} // namespace spvtools - -#endif // SOURCE_OPT_GENERATE_WEBGPU_INITIALIZERS_PASS_H_ diff --git a/source/opt/legalize_vector_shuffle_pass.cpp b/source/opt/legalize_vector_shuffle_pass.cpp deleted file mode 100644 index b5d5d5993c..0000000000 --- a/source/opt/legalize_vector_shuffle_pass.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2019 Google LLC. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "source/opt/legalize_vector_shuffle_pass.h" - -#include "source/opt/ir_context.h" - -namespace spvtools { -namespace opt { - -Pass::Status LegalizeVectorShufflePass::Process() { - bool changed = false; - context()->module()->ForEachInst([&changed](Instruction* inst) { - if (inst->opcode() != SpvOpVectorShuffle) return; - - for (uint32_t idx = 2; idx < inst->NumInOperands(); ++idx) { - auto literal = inst->GetSingleWordInOperand(idx); - if (literal != 0xFFFFFFFF) continue; - changed = true; - inst->SetInOperand(idx, {0}); - } - }); - - return changed ? Status::SuccessWithChange : Status::SuccessWithoutChange; -} - -} // namespace opt -} // namespace spvtools diff --git a/source/opt/legalize_vector_shuffle_pass.h b/source/opt/legalize_vector_shuffle_pass.h deleted file mode 100644 index ca6e1dfbe2..0000000000 --- a/source/opt/legalize_vector_shuffle_pass.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2019 Google LLC. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef SOURCE_OPT_LEGALIZE_VECTOR_SHUFFLE_PASS_H_ -#define SOURCE_OPT_LEGALIZE_VECTOR_SHUFFLE_PASS_H_ - -#include "source/opt/ir_context.h" -#include "source/opt/module.h" -#include "source/opt/pass.h" - -namespace spvtools { -namespace opt { - -// Converts any usages of 0xFFFFFFFF for the literals in OpVectorShuffle to a -// literal 0. This is needed because using OxFFFFFFFF is forbidden by the WebGPU -// spec. 0xFFFFFFFF in the main spec indicates that the result for this -// component has no source, thus is undefined. Since this is undefined -// behaviour we are free to use 0. -class LegalizeVectorShufflePass : public Pass { - public: - const char* name() const override { return "legalize-vector-shuffle"; } - Status Process() override; - - IRContext::Analysis GetPreservedAnalyses() override { - return IRContext::kAnalysisInstrToBlockMapping | - IRContext::kAnalysisDecorations | IRContext::kAnalysisCombinators | - IRContext::kAnalysisCFG | IRContext::kAnalysisDominatorAnalysis | - IRContext::kAnalysisLoopAnalysis | IRContext::kAnalysisNameMap | - IRContext::kAnalysisScalarEvolution | - IRContext::kAnalysisRegisterPressure | - IRContext::kAnalysisValueNumberTable | - IRContext::kAnalysisStructuredCFG | - IRContext::kAnalysisBuiltinVarId | - IRContext::kAnalysisIdToFuncMapping | IRContext::kAnalysisTypes | - IRContext::kAnalysisDefUse | IRContext::kAnalysisConstants; - } -}; - -} // namespace opt -} // namespace spvtools - -#endif // SOURCE_OPT_LEGALIZE_VECTOR_SHUFFLE_PASS_H_ diff --git a/source/opt/optimizer.cpp b/source/opt/optimizer.cpp index 8726ff93d6..98d52de360 100644 --- a/source/opt/optimizer.cpp +++ b/source/opt/optimizer.cpp @@ -62,7 +62,9 @@ struct Optimizer::Impl { opt::PassManager pass_manager; // Internal implementation pass manager. }; -Optimizer::Optimizer(spv_target_env env) : impl_(new Impl(env)) {} +Optimizer::Optimizer(spv_target_env env) : impl_(new Impl(env)) { + assert(env != SPV_ENV_WEBGPU_0); +} Optimizer::~Optimizer() {} @@ -239,23 +241,6 @@ Optimizer& Optimizer::RegisterSizePasses() { .RegisterPass(CreateCFGCleanupPass()); } -Optimizer& Optimizer::RegisterVulkanToWebGPUPasses() { - return RegisterPass(CreateStripAtomicCounterMemoryPass()) - .RegisterPass(CreateGenerateWebGPUInitializersPass()) - .RegisterPass(CreateLegalizeVectorShufflePass()) - .RegisterPass(CreateSplitInvalidUnreachablePass()) - .RegisterPass(CreateEliminateDeadConstantPass()) - .RegisterPass(CreateFlattenDecorationPass()) - .RegisterPass(CreateAggressiveDCEPass()) - .RegisterPass(CreateDeadBranchElimPass()) - .RegisterPass(CreateCompactIdsPass()); -} - -Optimizer& Optimizer::RegisterWebGPUToVulkanPasses() { - return RegisterPass(CreateDecomposeInitializedVariablesPass()) - .RegisterPass(CreateCompactIdsPass()); -} - bool Optimizer::RegisterPassesFromFlags(const std::vector& flags) { for (const auto& flag : flags) { if (!RegisterPassFromFlag(flag)) { @@ -298,9 +283,7 @@ bool Optimizer::RegisterPassFromFlag(const std::string& flag) { // // Both Pass::name() and Pass::desc() should be static class members so they // can be invoked without creating a pass instance. - if (pass_name == "strip-atomic-counter-memory") { - RegisterPass(CreateStripAtomicCounterMemoryPass()); - } else if (pass_name == "strip-debug") { + if (pass_name == "strip-debug") { RegisterPass(CreateStripDebugInfoPass()); } else if (pass_name == "strip-reflect") { RegisterPass(CreateStripReflectInfoPass()); @@ -505,14 +488,6 @@ bool Optimizer::RegisterPassFromFlag(const std::string& flag) { RegisterSizePasses(); } else if (pass_name == "legalize-hlsl") { RegisterLegalizationPasses(); - } else if (pass_name == "generate-webgpu-initializers") { - RegisterPass(CreateGenerateWebGPUInitializersPass()); - } else if (pass_name == "legalize-vector-shuffle") { - RegisterPass(CreateLegalizeVectorShufflePass()); - } else if (pass_name == "split-invalid-unreachable") { - RegisterPass(CreateSplitInvalidUnreachablePass()); - } else if (pass_name == "decompose-initialized-variables") { - RegisterPass(CreateDecomposeInitializedVariablesPass()); } else if (pass_name == "graphics-robust-access") { RegisterPass(CreateGraphicsRobustAccessPass()); } else if (pass_name == "wrap-opkill") { @@ -627,11 +602,6 @@ Optimizer::PassToken CreateNullPass() { return MakeUnique(MakeUnique()); } -Optimizer::PassToken CreateStripAtomicCounterMemoryPass() { - return MakeUnique( - MakeUnique()); -} - Optimizer::PassToken CreateStripDebugInfoPass() { return MakeUnique( MakeUnique()); @@ -929,31 +899,11 @@ Optimizer::PassToken CreateCodeSinkingPass() { MakeUnique()); } -Optimizer::PassToken CreateGenerateWebGPUInitializersPass() { - return MakeUnique( - MakeUnique()); -} - Optimizer::PassToken CreateFixStorageClassPass() { return MakeUnique( MakeUnique()); } -Optimizer::PassToken CreateLegalizeVectorShufflePass() { - return MakeUnique( - MakeUnique()); -} - -Optimizer::PassToken CreateDecomposeInitializedVariablesPass() { - return MakeUnique( - MakeUnique()); -} - -Optimizer::PassToken CreateSplitInvalidUnreachablePass() { - return MakeUnique( - MakeUnique()); -} - Optimizer::PassToken CreateGraphicsRobustAccessPass() { return MakeUnique( MakeUnique()); diff --git a/source/opt/passes.h b/source/opt/passes.h index d47cc1cee2..1bc94c7e22 100644 --- a/source/opt/passes.h +++ b/source/opt/passes.h @@ -30,7 +30,6 @@ #include "source/opt/dead_branch_elim_pass.h" #include "source/opt/dead_insert_elim_pass.h" #include "source/opt/dead_variable_elimination.h" -#include "source/opt/decompose_initialized_variables_pass.h" #include "source/opt/desc_sroa.h" #include "source/opt/eliminate_dead_constant_pass.h" #include "source/opt/eliminate_dead_functions_pass.h" @@ -40,7 +39,6 @@ #include "source/opt/flatten_decoration_pass.h" #include "source/opt/fold_spec_constant_op_and_composite_pass.h" #include "source/opt/freeze_spec_constant_value_pass.h" -#include "source/opt/generate_webgpu_initializers_pass.h" #include "source/opt/graphics_robust_access_pass.h" #include "source/opt/if_conversion.h" #include "source/opt/inline_exhaustive_pass.h" @@ -48,7 +46,6 @@ #include "source/opt/inst_bindless_check_pass.h" #include "source/opt/inst_buff_addr_check_pass.h" #include "source/opt/inst_debug_printf_pass.h" -#include "source/opt/legalize_vector_shuffle_pass.h" #include "source/opt/licm_pass.h" #include "source/opt/local_access_chain_convert_pass.h" #include "source/opt/local_redundancy_elimination.h" @@ -70,10 +67,8 @@ #include "source/opt/scalar_replacement_pass.h" #include "source/opt/set_spec_constant_default_value_pass.h" #include "source/opt/simplification_pass.h" -#include "source/opt/split_invalid_unreachable_pass.h" #include "source/opt/ssa_rewrite_pass.h" #include "source/opt/strength_reduction_pass.h" -#include "source/opt/strip_atomic_counter_memory_pass.h" #include "source/opt/strip_debug_info_pass.h" #include "source/opt/strip_reflect_info_pass.h" #include "source/opt/unify_const_pass.h" diff --git a/source/opt/split_invalid_unreachable_pass.cpp b/source/opt/split_invalid_unreachable_pass.cpp deleted file mode 100644 index 31cfbc330b..0000000000 --- a/source/opt/split_invalid_unreachable_pass.cpp +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) 2019 Google LLC. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "source/opt/split_invalid_unreachable_pass.h" - -#include "source/opt/ir_builder.h" -#include "source/opt/ir_context.h" - -namespace spvtools { -namespace opt { - -Pass::Status SplitInvalidUnreachablePass::Process() { - bool changed = false; - std::unordered_set entry_points; - for (auto entry_point : context()->module()->entry_points()) { - entry_points.insert(entry_point.GetSingleWordOperand(1)); - } - - for (auto func = context()->module()->begin(); - func != context()->module()->end(); ++func) { - if (entry_points.find(func->result_id()) == entry_points.end()) continue; - std::unordered_set continue_targets; - std::unordered_set merge_blocks; - std::unordered_set unreachable_blocks; - for (auto block = func->begin(); block != func->end(); ++block) { - unreachable_blocks.insert(&*block); - uint32_t continue_target = block->ContinueBlockIdIfAny(); - if (continue_target != 0) continue_targets.insert(continue_target); - uint32_t merge_block = block->MergeBlockIdIfAny(); - if (merge_block != 0) merge_blocks.insert(merge_block); - } - - cfg()->ForEachBlockInPostOrder( - func->entry().get(), [&unreachable_blocks](BasicBlock* inner_block) { - unreachable_blocks.erase(inner_block); - }); - - for (auto unreachable : unreachable_blocks) { - uint32_t block_id = unreachable->id(); - if (continue_targets.find(block_id) == continue_targets.end() || - merge_blocks.find(block_id) == merge_blocks.end()) { - continue; - } - - std::vector> usages; - context()->get_def_use_mgr()->ForEachUse( - unreachable->GetLabelInst(), - [&usages](Instruction* use, uint32_t idx) { - if ((use->opcode() == SpvOpLoopMerge && idx == 0) || - use->opcode() == SpvOpSelectionMerge) { - usages.push_back(std::make_pair(use, idx)); - } - }); - - for (auto usage : usages) { - Instruction* use; - uint32_t idx; - std::tie(use, idx) = usage; - uint32_t new_id = context()->TakeNextId(); - std::unique_ptr new_label( - new Instruction(context(), SpvOpLabel, 0, new_id, {})); - get_def_use_mgr()->AnalyzeInstDefUse(new_label.get()); - std::unique_ptr new_block( - new BasicBlock(std::move(new_label))); - auto* block_ptr = new_block.get(); - InstructionBuilder builder(context(), new_block.get(), - IRContext::kAnalysisDefUse | - IRContext::kAnalysisInstrToBlockMapping); - builder.AddUnreachable(); - cfg()->RegisterBlock(block_ptr); - (&*func)->InsertBasicBlockBefore(std::move(new_block), unreachable); - use->SetInOperand(0, {new_id}); - get_def_use_mgr()->UpdateDefUse(use); - cfg()->AddEdges(block_ptr); - changed = true; - } - } - } - - return changed ? Status::SuccessWithChange : Status::SuccessWithoutChange; -} - -} // namespace opt -} // namespace spvtools diff --git a/source/opt/split_invalid_unreachable_pass.h b/source/opt/split_invalid_unreachable_pass.h deleted file mode 100644 index a5613448e7..0000000000 --- a/source/opt/split_invalid_unreachable_pass.h +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2019 Google LLC. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef SOURCE_OPT_SPLIT_INVALID_UNREACHABLE_PASS_H_ -#define SOURCE_OPT_SPLIT_INVALID_UNREACHABLE_PASS_H_ - -#include "source/opt/ir_context.h" -#include "source/opt/module.h" -#include "source/opt/pass.h" - -namespace spvtools { -namespace opt { - -// Attempts to legalize for WebGPU by splitting up invalid unreachable blocks. -// Specifically, looking for cases of unreachable merge-blocks and -// continue-targets that are used more then once, which is illegal in WebGPU. -class SplitInvalidUnreachablePass : public Pass { - public: - const char* name() const override { return "split-invalid-unreachable"; } - Status Process() override; - - IRContext::Analysis GetPreservedAnalyses() override { - return IRContext::kAnalysisInstrToBlockMapping | - IRContext::kAnalysisDecorations | IRContext::kAnalysisCombinators | - IRContext::kAnalysisCFG | IRContext::kAnalysisDominatorAnalysis | - IRContext::kAnalysisLoopAnalysis | IRContext::kAnalysisNameMap | - IRContext::kAnalysisScalarEvolution | - IRContext::kAnalysisRegisterPressure | - IRContext::kAnalysisValueNumberTable | - IRContext::kAnalysisStructuredCFG | - IRContext::kAnalysisBuiltinVarId | - IRContext::kAnalysisIdToFuncMapping | IRContext::kAnalysisTypes | - IRContext::kAnalysisDefUse | IRContext::kAnalysisConstants; - } -}; - -} // namespace opt -} // namespace spvtools - -#endif // SOURCE_OPT_SPLIT_INVALID_UNREACHABLE_PASS_H_ diff --git a/source/opt/strip_atomic_counter_memory_pass.cpp b/source/opt/strip_atomic_counter_memory_pass.cpp deleted file mode 100644 index 47714b7469..0000000000 --- a/source/opt/strip_atomic_counter_memory_pass.cpp +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) 2019 Google LLC. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "source/opt/strip_atomic_counter_memory_pass.h" -#include "source/opt/ir_context.h" - -namespace spvtools { -namespace opt { - -Pass::Status StripAtomicCounterMemoryPass::Process() { - bool changed = false; - context()->module()->ForEachInst([this, &changed](Instruction* inst) { - auto indices = spvOpcodeMemorySemanticsOperandIndices(inst->opcode()); - if (indices.empty()) return; - - for (auto idx : indices) { - auto mem_sem_id = inst->GetSingleWordOperand(idx); - const auto& mem_sem_inst = - context()->get_def_use_mgr()->GetDef(mem_sem_id); - // The spec explicitly says that this id must be an OpConstant - auto mem_sem_val = mem_sem_inst->GetSingleWordOperand(2); - if (!(mem_sem_val & SpvMemorySemanticsAtomicCounterMemoryMask)) { - continue; - } - mem_sem_val &= ~SpvMemorySemanticsAtomicCounterMemoryMask; - - analysis::Integer int_type(32, false); - const analysis::Type* uint32_type = - context()->get_type_mgr()->GetRegisteredType(&int_type); - auto* new_const = context()->get_constant_mgr()->GetConstant( - uint32_type, {mem_sem_val}); - auto* new_const_inst = - context()->get_constant_mgr()->GetDefiningInstruction(new_const); - auto new_const_id = new_const_inst->result_id(); - - inst->SetOperand(idx, {new_const_id}); - context()->UpdateDefUse(inst); - changed = true; - } - }); - - return changed ? Status::SuccessWithChange : Status::SuccessWithoutChange; -} - -} // namespace opt -} // namespace spvtools diff --git a/source/opt/strip_atomic_counter_memory_pass.h b/source/opt/strip_atomic_counter_memory_pass.h deleted file mode 100644 index 62e274a197..0000000000 --- a/source/opt/strip_atomic_counter_memory_pass.h +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2019 Google LLC. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef SOURCE_OPT_STRIP_ATOMIC_COUNT_MEMORY_PASS_H_ -#define SOURCE_OPT_STRIP_ATOMIC_COUNT_MEMORY_PASS_H_ - -#include "source/opt/ir_context.h" -#include "source/opt/module.h" -#include "source/opt/pass.h" - -namespace spvtools { -namespace opt { - -// Removes the AtomicCounterMemory bit from the value being passed into memory -// semantics. This bit being set is ignored in Vulkan environments and -// forbidden WebGPU ones. -class StripAtomicCounterMemoryPass : public Pass { - public: - const char* name() const override { return "strip-atomic-counter-memory"; } - Status Process() override; - - IRContext::Analysis GetPreservedAnalyses() override { - return IRContext::kAnalysisInstrToBlockMapping | - IRContext::kAnalysisDecorations | IRContext::kAnalysisCombinators | - IRContext::kAnalysisCFG | IRContext::kAnalysisDominatorAnalysis | - IRContext::kAnalysisLoopAnalysis | IRContext::kAnalysisNameMap | - IRContext::kAnalysisScalarEvolution | - IRContext::kAnalysisRegisterPressure | - IRContext::kAnalysisValueNumberTable | - IRContext::kAnalysisStructuredCFG | - IRContext::kAnalysisBuiltinVarId | - IRContext::kAnalysisIdToFuncMapping | IRContext::kAnalysisTypes | - IRContext::kAnalysisDefUse | IRContext::kAnalysisConstants; - } -}; - -} // namespace opt -} // namespace spvtools - -#endif // SOURCE_OPT_STRIP_ATOMIC_COUNT_MEMORY_PASS_H_ diff --git a/source/spirv_target_env.cpp b/source/spirv_target_env.cpp index e2ff99cb04..f20ebb4fb5 100644 --- a/source/spirv_target_env.cpp +++ b/source/spirv_target_env.cpp @@ -14,6 +14,7 @@ #include "source/spirv_target_env.h" +#include #include #include @@ -61,7 +62,8 @@ const char* spvTargetEnvDescription(spv_target_env env) { case SPV_ENV_VULKAN_1_1: return "SPIR-V 1.3 (under Vulkan 1.1 semantics)"; case SPV_ENV_WEBGPU_0: - return "SPIR-V 1.3 (under WIP WebGPU semantics)"; + assert(false); + break; case SPV_ENV_UNIVERSAL_1_4: return "SPIR-V 1.4"; case SPV_ENV_VULKAN_1_1_SPIRV_1_4: @@ -98,8 +100,10 @@ uint32_t spvVersionForTargetEnv(spv_target_env env) { return SPV_SPIRV_VERSION_WORD(1, 2); case SPV_ENV_UNIVERSAL_1_3: case SPV_ENV_VULKAN_1_1: - case SPV_ENV_WEBGPU_0: return SPV_SPIRV_VERSION_WORD(1, 3); + case SPV_ENV_WEBGPU_0: + assert(false); + break; case SPV_ENV_UNIVERSAL_1_4: case SPV_ENV_VULKAN_1_1_SPIRV_1_4: return SPV_SPIRV_VERSION_WORD(1, 4); @@ -134,7 +138,6 @@ static const std::pair spvTargetEnvNameMap[] = { {"opengl4.2", SPV_ENV_OPENGL_4_2}, {"opengl4.3", SPV_ENV_OPENGL_4_3}, {"opengl4.5", SPV_ENV_OPENGL_4_5}, - {"webgpu0", SPV_ENV_WEBGPU_0}, }; bool spvParseTargetEnv(const char* s, spv_target_env* env) { @@ -200,7 +203,6 @@ bool spvIsVulkanEnv(spv_target_env env) { case SPV_ENV_OPENCL_2_2: case SPV_ENV_OPENCL_EMBEDDED_2_2: case SPV_ENV_UNIVERSAL_1_3: - case SPV_ENV_WEBGPU_0: case SPV_ENV_UNIVERSAL_1_4: case SPV_ENV_UNIVERSAL_1_5: return false; @@ -209,6 +211,9 @@ bool spvIsVulkanEnv(spv_target_env env) { case SPV_ENV_VULKAN_1_1_SPIRV_1_4: case SPV_ENV_VULKAN_1_2: return true; + case SPV_ENV_WEBGPU_0: + assert(false); + break; } return false; } @@ -226,7 +231,6 @@ bool spvIsOpenCLEnv(spv_target_env env) { case SPV_ENV_UNIVERSAL_1_2: case SPV_ENV_UNIVERSAL_1_3: case SPV_ENV_VULKAN_1_1: - case SPV_ENV_WEBGPU_0: case SPV_ENV_UNIVERSAL_1_4: case SPV_ENV_VULKAN_1_1_SPIRV_1_4: case SPV_ENV_UNIVERSAL_1_5: @@ -241,38 +245,9 @@ bool spvIsOpenCLEnv(spv_target_env env) { case SPV_ENV_OPENCL_2_1: case SPV_ENV_OPENCL_2_2: return true; - } - 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: - case SPV_ENV_UNIVERSAL_1_4: - case SPV_ENV_VULKAN_1_1_SPIRV_1_4: - case SPV_ENV_UNIVERSAL_1_5: - case SPV_ENV_VULKAN_1_2: - return false; case SPV_ENV_WEBGPU_0: - return true; + assert(false); + break; } return false; } @@ -293,7 +268,6 @@ bool spvIsOpenGLEnv(spv_target_env env) { case SPV_ENV_OPENCL_EMBEDDED_2_2: case SPV_ENV_OPENCL_2_1: case SPV_ENV_OPENCL_2_2: - case SPV_ENV_WEBGPU_0: case SPV_ENV_UNIVERSAL_1_4: case SPV_ENV_VULKAN_1_1_SPIRV_1_4: case SPV_ENV_UNIVERSAL_1_5: @@ -305,14 +279,13 @@ bool spvIsOpenGLEnv(spv_target_env env) { case SPV_ENV_OPENGL_4_3: case SPV_ENV_OPENGL_4_5: return true; + case SPV_ENV_WEBGPU_0: + assert(false); + break; } return false; } -bool spvIsVulkanOrWebGPUEnv(spv_target_env env) { - return spvIsVulkanEnv(env) || spvIsWebGPUEnv(env); -} - std::string spvLogStringForEnv(spv_target_env env) { switch (env) { case SPV_ENV_OPENCL_1_2: @@ -338,9 +311,6 @@ std::string spvLogStringForEnv(spv_target_env env) { case SPV_ENV_VULKAN_1_2: return "Vulkan"; } - case SPV_ENV_WEBGPU_0: { - return "WebGPU"; - } case SPV_ENV_UNIVERSAL_1_0: case SPV_ENV_UNIVERSAL_1_1: case SPV_ENV_UNIVERSAL_1_2: @@ -349,6 +319,9 @@ std::string spvLogStringForEnv(spv_target_env env) { case SPV_ENV_UNIVERSAL_1_5: { return "Universal"; } + case SPV_ENV_WEBGPU_0: + assert(false); + break; } return "Unknown"; } diff --git a/source/spirv_target_env.h b/source/spirv_target_env.h index 1bdedf917f..a804d615c5 100644 --- a/source/spirv_target_env.h +++ b/source/spirv_target_env.h @@ -25,20 +25,14 @@ 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 true if |env| is an OPENGL environment, false otherwise. bool spvIsOpenGLEnv(spv_target_env env); -// Returns true if |env| is a VULKAN or WEBGPU environment, false otherwise. -bool spvIsVulkanOrWebGPUEnv(spv_target_env env); - // Returns the version number for the given SPIR-V target environment. uint32_t spvVersionForTargetEnv(spv_target_env env); // Returns a string to use in logging messages that indicates the class of -// environment, i.e. "Vulkan", "WebGPU", "OpenCL", etc. +// environment, i.e. "Vulkan", "OpenCL", etc. std::string spvLogStringForEnv(spv_target_env env); // Returns a formatted list of all SPIR-V target environment names that diff --git a/source/table.cpp b/source/table.cpp index 8340e8e210..d4a2d7e967 100644 --- a/source/table.cpp +++ b/source/table.cpp @@ -38,7 +38,6 @@ spv_context spvContextCreate(spv_target_env env) { case SPV_ENV_UNIVERSAL_1_3: case SPV_ENV_VULKAN_1_1: case SPV_ENV_VULKAN_1_1_SPIRV_1_4: - case SPV_ENV_WEBGPU_0: case SPV_ENV_UNIVERSAL_1_4: case SPV_ENV_UNIVERSAL_1_5: case SPV_ENV_VULKAN_1_2: diff --git a/source/val/validate.cpp b/source/val/validate.cpp index d6e992b15b..a2e116b131 100644 --- a/source/val/validate.cpp +++ b/source/val/validate.cpp @@ -111,57 +111,6 @@ spv_result_t ValidateForwardDecls(ValidationState_t& _) { << id_str.substr(0, id_str.size() - 1); } -std::vector CalculateNamesForEntryPoint(ValidationState_t& _, - const uint32_t id) { - auto id_descriptions = _.entry_point_descriptions(id); - auto id_names = std::vector(); - id_names.reserve((id_descriptions.size())); - - for (auto description : id_descriptions) id_names.push_back(description.name); - - return id_names; -} - -spv_result_t ValidateEntryPointNameUnique(ValidationState_t& _, - const uint32_t id) { - auto id_names = CalculateNamesForEntryPoint(_, id); - const auto names = - std::unordered_set(id_names.begin(), id_names.end()); - - if (id_names.size() != names.size()) { - std::sort(id_names.begin(), id_names.end()); - for (size_t i = 0; i < id_names.size() - 1; i++) { - if (id_names[i] == id_names[i + 1]) { - return _.diag(SPV_ERROR_INVALID_BINARY, _.FindDef(id)) - << "Entry point name \"" << id_names[i] - << "\" is not unique, which is not allow in WebGPU env."; - } - } - } - - for (const auto other_id : _.entry_points()) { - if (other_id == id) continue; - const auto other_id_names = CalculateNamesForEntryPoint(_, other_id); - for (const auto& other_id_name : other_id_names) { - if (names.find(other_id_name) != names.end()) { - return _.diag(SPV_ERROR_INVALID_BINARY, _.FindDef(id)) - << "Entry point name \"" << other_id_name - << "\" is not unique, which is not allow in WebGPU env."; - } - } - } - - return SPV_SUCCESS; -} - -spv_result_t ValidateEntryPointNamesUnique(ValidationState_t& _) { - for (const auto id : _.entry_points()) { - auto result = ValidateEntryPointNameUnique(_, id); - if (result != SPV_SUCCESS) return result; - } - return SPV_SUCCESS; -} - // Entry point validation. Based on 2.16.1 (Universal Validation Rules) of the // SPIRV spec: // * There is at least one OpEntryPoint instruction, unless the Linkage @@ -169,8 +118,7 @@ spv_result_t ValidateEntryPointNamesUnique(ValidationState_t& _) { // * No function can be targeted by both an OpEntryPoint instruction and an // OpFunctionCall instruction. // -// Additionally enforces that entry points for Vulkan and WebGPU should not have -// recursion. And that entry names should be unique for WebGPU. +// Additionally enforces that entry points for Vulkan should not have recursion. spv_result_t ValidateEntryPoints(ValidationState_t& _) { _.ComputeFunctionToEntryPointMapping(); _.ComputeRecursiveEntryPoints(); @@ -189,21 +137,15 @@ spv_result_t ValidateEntryPoints(ValidationState_t& _) { "an OpFunctionCall instruction."; } - // For Vulkan and WebGPU, the static function-call graph for an entry point + // For Vulkan, the static function-call graph for an entry point // must not contain cycles. - if (spvIsVulkanOrWebGPUEnv(_.context()->target_env)) { + if (spvIsVulkanEnv(_.context()->target_env)) { if (_.recursive_entry_points().find(entry_point) != _.recursive_entry_points().end()) { return _.diag(SPV_ERROR_INVALID_BINARY, _.FindDef(entry_point)) << "Entry points may not have a call graph with cycles."; } } - - // For WebGPU all entry point names must be unique. - if (spvIsWebGPUEnv(_.context()->target_env)) { - const auto result = ValidateEntryPointNamesUnique(_); - if (result != SPV_SUCCESS) return result; - } } return SPV_SUCCESS; @@ -223,12 +165,6 @@ spv_result_t ValidateBinaryUsingContextAndValidationState( << "Invalid SPIR-V magic number."; } - if (spvIsWebGPUEnv(context.target_env) && endian != SPV_ENDIANNESS_LITTLE) { - return DiagnosticStream(position, context.consumer, "", - SPV_ERROR_INVALID_BINARY) - << "WebGPU requires SPIR-V to be little endian."; - } - spv_header_t header; if (spvBinaryHeaderGet(binary.get(), endian, &header)) { return DiagnosticStream(position, context.consumer, "", @@ -321,13 +257,6 @@ spv_result_t ValidateBinaryUsingContextAndValidationState( } const auto called_id = inst->GetOperandAs(2); - if (spvIsWebGPUEnv(context.target_env) && - !vstate->IsFunctionCallDefined(called_id)) { - return vstate->diag(SPV_ERROR_INVALID_LAYOUT, &instruction) - << "For WebGPU, functions need to be defined before being " - "called."; - } - vstate->AddFunctionCallTarget(called_id); } diff --git a/source/val/validate_annotation.cpp b/source/val/validate_annotation.cpp index 8acdb9846b..85d2b7515a 100644 --- a/source/val/validate_annotation.cpp +++ b/source/val/validate_annotation.cpp @@ -22,36 +22,6 @@ namespace spvtools { namespace val { namespace { -bool IsValidWebGPUDecoration(uint32_t decoration) { - switch (decoration) { - case SpvDecorationSpecId: - case SpvDecorationBlock: - case SpvDecorationRowMajor: - case SpvDecorationColMajor: - case SpvDecorationArrayStride: - case SpvDecorationMatrixStride: - case SpvDecorationBuiltIn: - case SpvDecorationNoPerspective: - case SpvDecorationFlat: - case SpvDecorationCentroid: - case SpvDecorationRestrict: - case SpvDecorationAliased: - case SpvDecorationNonWritable: - case SpvDecorationNonReadable: - case SpvDecorationUniform: - case SpvDecorationLocation: - case SpvDecorationComponent: - case SpvDecorationIndex: - case SpvDecorationBinding: - case SpvDecorationDescriptorSet: - case SpvDecorationOffset: - case SpvDecorationNoContraction: - return true; - default: - return false; - } -} - std::string LogStringForDecoration(uint32_t decoration) { switch (decoration) { case SpvDecorationRelaxedPrecision: @@ -212,13 +182,6 @@ spv_result_t ValidateDecorate(ValidationState_t& _, const Instruction* inst) { } } - if (spvIsWebGPUEnv(_.context()->target_env) && - !IsValidWebGPUDecoration(decoration)) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "OpDecorate decoration '" << LogStringForDecoration(decoration) - << "' is not valid for the WebGPU execution environment."; - } - if (spvIsVulkanEnv(_.context()->target_env)) { if ((decoration == SpvDecorationGLSLShared) || (decoration == SpvDecorationGLSLPacked)) { @@ -271,25 +234,11 @@ spv_result_t ValidateMemberDecorate(ValidationState_t& _, << " members. Largest valid index is " << member_count - 1 << "."; } - const auto decoration = inst->GetOperandAs(2); - if (spvIsWebGPUEnv(_.context()->target_env) && - !IsValidWebGPUDecoration(decoration)) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "OpMemberDecorate decoration '" << _.getIdName(decoration) - << "' is not valid for the WebGPU execution environment."; - } - return SPV_SUCCESS; } spv_result_t ValidateDecorationGroup(ValidationState_t& _, const Instruction* inst) { - if (spvIsWebGPUEnv(_.context()->target_env)) { - return _.diag(SPV_ERROR_INVALID_BINARY, inst) - << "OpDecorationGroup is not allowed in the WebGPU execution " - << "environment."; - } - const auto decoration_group_id = inst->GetOperandAs(0); const auto decoration_group = _.FindDef(decoration_group_id); for (auto pair : decoration_group->uses()) { @@ -309,12 +258,6 @@ spv_result_t ValidateDecorationGroup(ValidationState_t& _, spv_result_t ValidateGroupDecorate(ValidationState_t& _, const Instruction* inst) { - if (spvIsWebGPUEnv(_.context()->target_env)) { - return _.diag(SPV_ERROR_INVALID_BINARY, inst) - << "OpGroupDecorate is not allowed in the WebGPU execution " - << "environment."; - } - const auto decoration_group_id = inst->GetOperandAs(0); auto decoration_group = _.FindDef(decoration_group_id); if (!decoration_group || SpvOpDecorationGroup != decoration_group->opcode()) { @@ -337,12 +280,6 @@ spv_result_t ValidateGroupDecorate(ValidationState_t& _, spv_result_t ValidateGroupMemberDecorate(ValidationState_t& _, const Instruction* inst) { - if (spvIsWebGPUEnv(_.context()->target_env)) { - return _.diag(SPV_ERROR_INVALID_BINARY, inst) - << "OpGroupMemberDecorate is not allowed in the WebGPU execution " - << "environment."; - } - const auto decoration_group_id = inst->GetOperandAs(0); const auto decoration_group = _.FindDef(decoration_group_id); if (!decoration_group || SpvOpDecorationGroup != decoration_group->opcode()) { diff --git a/source/val/validate_builtins.cpp b/source/val/validate_builtins.cpp index 4f2a3b111c..7fb99089c9 100644 --- a/source/val/validate_builtins.cpp +++ b/source/val/validate_builtins.cpp @@ -113,28 +113,6 @@ SpvStorageClass GetStorageClass(const Instruction& inst) { return SpvStorageClassMax; } -bool IsBuiltInValidForWebGPU(SpvBuiltIn label) { - switch (label) { - case SpvBuiltInPosition: - case SpvBuiltInVertexIndex: - case SpvBuiltInInstanceIndex: - case SpvBuiltInFrontFacing: - case SpvBuiltInFragCoord: - case SpvBuiltInFragDepth: - case SpvBuiltInNumWorkgroups: - case SpvBuiltInWorkgroupSize: - case SpvBuiltInLocalInvocationId: - case SpvBuiltInGlobalInvocationId: - case SpvBuiltInLocalInvocationIndex: { - return true; - } - default: - break; - } - - return false; -} - typedef enum VUIDError_ { VUIDErrorExecutionModel = 0, VUIDErrorStorageClass = 1, @@ -1260,7 +1238,7 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference( spv_result_t BuiltInsValidator::ValidateFragCoordAtDefinition( const Decoration& decoration, const Instruction& inst) { - if (spvIsVulkanOrWebGPUEnv(_.context()->target_env)) { + if (spvIsVulkanEnv(_.context()->target_env)) { if (spv_result_t error = ValidateF32Vec( decoration, inst, 4, [this, &inst](const std::string& message) -> spv_result_t { @@ -1284,7 +1262,7 @@ spv_result_t BuiltInsValidator::ValidateFragCoordAtReference( const Decoration& decoration, const Instruction& built_in_inst, const Instruction& referenced_inst, const Instruction& referenced_from_inst) { - if (spvIsVulkanOrWebGPUEnv(_.context()->target_env)) { + if (spvIsVulkanEnv(_.context()->target_env)) { const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); if (storage_class != SpvStorageClassMax && storage_class != SpvStorageClassInput) { @@ -1322,7 +1300,7 @@ spv_result_t BuiltInsValidator::ValidateFragCoordAtReference( spv_result_t BuiltInsValidator::ValidateFragDepthAtDefinition( const Decoration& decoration, const Instruction& inst) { - if (spvIsVulkanOrWebGPUEnv(_.context()->target_env)) { + if (spvIsVulkanEnv(_.context()->target_env)) { if (spv_result_t error = ValidateF32( decoration, inst, [this, &inst](const std::string& message) -> spv_result_t { @@ -1345,7 +1323,7 @@ spv_result_t BuiltInsValidator::ValidateFragDepthAtReference( const Decoration& decoration, const Instruction& built_in_inst, const Instruction& referenced_inst, const Instruction& referenced_from_inst) { - if (spvIsVulkanOrWebGPUEnv(_.context()->target_env)) { + if (spvIsVulkanEnv(_.context()->target_env)) { const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); if (storage_class != SpvStorageClassMax && storage_class != SpvStorageClassOutput) { @@ -1398,7 +1376,7 @@ spv_result_t BuiltInsValidator::ValidateFragDepthAtReference( spv_result_t BuiltInsValidator::ValidateFrontFacingAtDefinition( const Decoration& decoration, const Instruction& inst) { - if (spvIsVulkanOrWebGPUEnv(_.context()->target_env)) { + if (spvIsVulkanEnv(_.context()->target_env)) { if (spv_result_t error = ValidateBool( decoration, inst, [this, &inst](const std::string& message) -> spv_result_t { @@ -1421,7 +1399,7 @@ spv_result_t BuiltInsValidator::ValidateFrontFacingAtReference( const Decoration& decoration, const Instruction& built_in_inst, const Instruction& referenced_inst, const Instruction& referenced_from_inst) { - if (spvIsVulkanOrWebGPUEnv(_.context()->target_env)) { + if (spvIsVulkanEnv(_.context()->target_env)) { const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); if (storage_class != SpvStorageClassMax && storage_class != SpvStorageClassInput) { @@ -1579,7 +1557,7 @@ spv_result_t BuiltInsValidator::ValidateInvocationIdAtReference( spv_result_t BuiltInsValidator::ValidateInstanceIndexAtDefinition( const Decoration& decoration, const Instruction& inst) { - if (spvIsVulkanOrWebGPUEnv(_.context()->target_env)) { + if (spvIsVulkanEnv(_.context()->target_env)) { if (spv_result_t error = ValidateI32( decoration, inst, [this, &inst](const std::string& message) -> spv_result_t { @@ -1602,7 +1580,7 @@ spv_result_t BuiltInsValidator::ValidateInstanceIndexAtReference( const Decoration& decoration, const Instruction& built_in_inst, const Instruction& referenced_inst, const Instruction& referenced_from_inst) { - if (spvIsVulkanOrWebGPUEnv(_.context()->target_env)) { + if (spvIsVulkanEnv(_.context()->target_env)) { const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); if (storage_class != SpvStorageClassMax && storage_class != SpvStorageClassInput) { @@ -1992,46 +1970,6 @@ spv_result_t BuiltInsValidator::ValidatePositionAtReference( } } - if (spvIsWebGPUEnv(_.context()->target_env)) { - const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); - if (storage_class != SpvStorageClassMax && - storage_class != SpvStorageClassOutput) { - return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) - << "WebGPU spec allows BuiltIn Position to be only used for " - "variables with Output storage class. " - << GetReferenceDesc(decoration, built_in_inst, referenced_inst, - referenced_from_inst) - << " " << GetStorageClassDesc(referenced_from_inst); - } - - for (const SpvExecutionModel execution_model : execution_models_) { - switch (execution_model) { - case SpvExecutionModelVertex: { - if (spv_result_t error = ValidateF32Vec( - decoration, built_in_inst, 4, - [this, &referenced_from_inst]( - const std::string& message) -> spv_result_t { - return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) - << "According to the WebGPU spec BuiltIn Position " - "variable needs to be a 4-component 32-bit float " - "vector. " - << message; - })) { - return error; - } - break; - } - default: { - return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) - << "WebGPU spec allows BuiltIn Position to be used only " - "with the Vertex execution model. " - << GetReferenceDesc(decoration, built_in_inst, referenced_inst, - referenced_from_inst, execution_model); - } - } - } - } - if (function_id_ == 0) { // Propagate this rule to all dependant ids in the global scope. id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( @@ -2547,7 +2485,7 @@ spv_result_t BuiltInsValidator::ValidateTessLevelAtReference( spv_result_t BuiltInsValidator::ValidateVertexIndexAtDefinition( const Decoration& decoration, const Instruction& inst) { - if (spvIsVulkanOrWebGPUEnv(_.context()->target_env)) { + if (spvIsVulkanEnv(_.context()->target_env)) { if (spv_result_t error = ValidateI32( decoration, inst, [this, &inst](const std::string& message) -> spv_result_t { @@ -2580,51 +2518,14 @@ spv_result_t BuiltInsValidator::ValidateVertexIdAtDefinition( spv_result_t BuiltInsValidator::ValidateLocalInvocationIndexAtDefinition( const Decoration& decoration, const Instruction& inst) { - if (spvIsWebGPUEnv(_.context()->target_env)) { - if (spv_result_t error = ValidateI32( - decoration, inst, - [this, &inst](const std::string& message) -> spv_result_t { - return _.diag(SPV_ERROR_INVALID_DATA, &inst) - << "According to the WebGPU spec BuiltIn " - "LocalInvocationIndex variable needs to be a 32-bit " - "int." - << message; - })) { - return error; - } - } - // Seed at reference checks with this built-in. return ValidateLocalInvocationIndexAtReference(decoration, inst, inst, inst); } spv_result_t BuiltInsValidator::ValidateLocalInvocationIndexAtReference( const Decoration& decoration, const Instruction& built_in_inst, - const Instruction& referenced_inst, + const Instruction&, const Instruction& referenced_from_inst) { - if (spvIsWebGPUEnv(_.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) - << "WebGPU spec allows BuiltIn LocalInvocationIndex to be only " - "used for variables with Input storage class. " - << GetReferenceDesc(decoration, built_in_inst, referenced_inst, - referenced_from_inst) - << " " << GetStorageClassDesc(referenced_from_inst); - } - - for (const SpvExecutionModel execution_model : execution_models_) { - if (execution_model != SpvExecutionModelGLCompute) { - return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) - << "WebGPU spec allows BuiltIn VertexIndex to be used only " - "with GLCompute execution model. " - << GetReferenceDesc(decoration, built_in_inst, referenced_inst, - referenced_from_inst, execution_model); - } - } - } - if (function_id_ == 0) { // Propagate this rule to all dependant ids in the global scope. id_to_at_reference_checks_[referenced_from_inst.id()].push_back( @@ -2640,7 +2541,7 @@ spv_result_t BuiltInsValidator::ValidateVertexIndexAtReference( const Decoration& decoration, const Instruction& built_in_inst, const Instruction& referenced_inst, const Instruction& referenced_from_inst) { - if (spvIsVulkanOrWebGPUEnv(_.context()->target_env)) { + if (spvIsVulkanEnv(_.context()->target_env)) { const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); if (storage_class != SpvStorageClassMax && storage_class != SpvStorageClassInput) { @@ -2838,7 +2739,7 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtReference( spv_result_t BuiltInsValidator::ValidateComputeShaderI32Vec3InputAtDefinition( const Decoration& decoration, const Instruction& inst) { - if (spvIsVulkanOrWebGPUEnv(_.context()->target_env)) { + if (spvIsVulkanEnv(_.context()->target_env)) { const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); if (spv_result_t error = ValidateI32Vec( decoration, inst, 3, @@ -2867,7 +2768,7 @@ spv_result_t BuiltInsValidator::ValidateComputeShaderI32Vec3InputAtReference( const Decoration& decoration, const Instruction& built_in_inst, const Instruction& referenced_inst, const Instruction& referenced_from_inst) { - if (spvIsVulkanOrWebGPUEnv(_.context()->target_env)) { + if (spvIsVulkanEnv(_.context()->target_env)) { const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]); const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst); if (storage_class != SpvStorageClassMax && @@ -2887,9 +2788,7 @@ spv_result_t BuiltInsValidator::ValidateComputeShaderI32Vec3InputAtReference( bool has_vulkan_model = execution_model == SpvExecutionModelGLCompute || execution_model == SpvExecutionModelTaskNV || execution_model == SpvExecutionModelMeshNV; - bool has_webgpu_model = execution_model == SpvExecutionModelGLCompute; - if ((spvIsVulkanEnv(_.context()->target_env) && !has_vulkan_model) || - (spvIsWebGPUEnv(_.context()->target_env) && !has_webgpu_model)) { + if (spvIsVulkanEnv(_.context()->target_env) && !has_vulkan_model) { uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) @@ -3086,7 +2985,7 @@ spv_result_t BuiltInsValidator::ValidateI32Vec4InputAtDefinition( spv_result_t BuiltInsValidator::ValidateWorkgroupSizeAtDefinition( const Decoration& decoration, const Instruction& inst) { - if (spvIsVulkanOrWebGPUEnv(_.context()->target_env)) { + if (spvIsVulkanEnv(_.context()->target_env)) { if (spvIsVulkanEnv(_.context()->target_env) && !spvOpcodeIsConstant(inst.opcode())) { return _.diag(SPV_ERROR_INVALID_DATA, &inst) @@ -3118,7 +3017,7 @@ spv_result_t BuiltInsValidator::ValidateWorkgroupSizeAtReference( const Decoration& decoration, const Instruction& built_in_inst, const Instruction& referenced_inst, const Instruction& referenced_from_inst) { - if (spvIsVulkanOrWebGPUEnv(_.context()->target_env)) { + if (spvIsVulkanEnv(_.context()->target_env)) { for (const SpvExecutionModel execution_model : execution_models_) { if (execution_model != SpvExecutionModelGLCompute) { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) @@ -3768,26 +3667,17 @@ spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition( << "BuiltIns can only target variables, structs or constants"; } - if (!spvIsVulkanOrWebGPUEnv(_.context()->target_env)) { - // Early return. All currently implemented rules are based on Vulkan or - // WebGPU spec. + if (!spvIsVulkanEnv(_.context()->target_env)) { + // Early return. All currently implemented rules are based on Vulkan spec. // // TODO: If you are adding validation rules for environments other than - // Vulkan or WebGPU (or general rules which are not environment - // independent), then you need to modify or remove this condition. Consider - // also adding early returns into BuiltIn-specific rules, so that the system - // doesn't spawn new rules which don't do anything. + // Vulkan (or general rules which are not environment independent), then + // you need to modify or remove this condition. Consider also adding early + // returns into BuiltIn-specific rules, so that the system doesn't spawn new + // rules which don't do anything. return SPV_SUCCESS; } - if (spvIsWebGPUEnv(_.context()->target_env) && - !IsBuiltInValidForWebGPU(label)) { - return _.diag(SPV_ERROR_INVALID_DATA, &inst) - << "WebGPU does not allow BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, - decoration.params()[0]); - } - // If you are adding a new BuiltIn enum, please register it here. // If the newly added enum has validation rules associated with it // consider leaving a TODO and/or creating an issue. diff --git a/source/val/validate_capability.cpp b/source/val/validate_capability.cpp index 4b98bc19c2..8efd55420d 100644 --- a/source/val/validate_capability.cpp +++ b/source/val/validate_capability.cpp @@ -260,19 +260,6 @@ bool IsEnabledByCapabilityOpenCL_2_0(ValidationState_t& _, return false; } -bool IsSupportGuaranteedWebGPU(uint32_t capability) { - switch (capability) { - case SpvCapabilityMatrix: - case SpvCapabilityShader: - case SpvCapabilitySampled1D: - case SpvCapabilityImage1D: - case SpvCapabilityDerivativeControl: - case SpvCapabilityImageQuery: - return true; - } - return false; -} - } // namespace // Validates that capability declarations use operands allowed in the current @@ -365,14 +352,6 @@ spv_result_t CapabilityPass(ValidationState_t& _, const Instruction* inst) { << " Profile specification" << " (or requires extension or capability)"; } - } else if (env == SPV_ENV_WEBGPU_0) { - if (!IsSupportGuaranteedWebGPU(capability) && - !IsEnabledByExtension(_, capability)) { - return _.diag(SPV_ERROR_INVALID_CAPABILITY, inst) - << "Capability " << capability_str() - << " is not allowed by WebGPU specification" - << " (or requires extension)"; - } } return SPV_SUCCESS; diff --git a/source/val/validate_cfg.cpp b/source/val/validate_cfg.cpp index ca2ae1aee1..a5f6e6a17e 100644 --- a/source/val/validate_cfg.cpp +++ b/source/val/validate_cfg.cpp @@ -820,120 +820,6 @@ spv_result_t StructuredControlFlowChecks( return SPV_SUCCESS; } -spv_result_t PerformWebGPUCfgChecks(ValidationState_t& _, Function* function) { - for (auto& block : function->ordered_blocks()) { - if (block->reachable()) continue; - if (block->is_type(kBlockTypeMerge)) { - // 1. Find the referencing merge and confirm that it is reachable. - BasicBlock* merge_header = function->GetMergeHeader(block); - assert(merge_header != nullptr); - if (!merge_header->reachable()) { - return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(block->id())) - << "For WebGPU, unreachable merge-blocks must be referenced by " - "a reachable merge instruction."; - } - - // 2. Check that the only instructions are OpLabel and OpUnreachable. - auto* label_inst = block->label(); - auto* terminator_inst = block->terminator(); - assert(label_inst != nullptr); - assert(terminator_inst != nullptr); - - if (terminator_inst->opcode() != SpvOpUnreachable) { - return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(block->id())) - << "For WebGPU, unreachable merge-blocks must terminate with " - "OpUnreachable."; - } - - auto label_idx = label_inst - &_.ordered_instructions()[0]; - auto terminator_idx = terminator_inst - &_.ordered_instructions()[0]; - if (label_idx + 1 != terminator_idx) { - return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(block->id())) - << "For WebGPU, unreachable merge-blocks must only contain an " - "OpLabel and OpUnreachable instruction."; - } - - // 3. Use label instruction to confirm there is no uses by branches. - for (auto use : label_inst->uses()) { - const auto* use_inst = use.first; - if (spvOpcodeIsBranch(use_inst->opcode())) { - return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(block->id())) - << "For WebGPU, unreachable merge-blocks cannot be the target " - "of a branch."; - } - } - } else if (block->is_type(kBlockTypeContinue)) { - // 1. Find referencing loop and confirm that it is reachable. - std::vector continue_headers = - function->GetContinueHeaders(block); - if (continue_headers.empty()) { - return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(block->id())) - << "For WebGPU, unreachable continue-target must be referenced " - "by a loop instruction."; - } - - std::vector reachable_headers(continue_headers.size()); - auto iter = - std::copy_if(continue_headers.begin(), continue_headers.end(), - reachable_headers.begin(), - [](BasicBlock* header) { return header->reachable(); }); - reachable_headers.resize(std::distance(reachable_headers.begin(), iter)); - - if (reachable_headers.empty()) { - return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(block->id())) - << "For WebGPU, unreachable continue-target must be referenced " - "by a reachable loop instruction."; - } - - // 2. Check that the only instructions are OpLabel and OpBranch. - auto* label_inst = block->label(); - auto* terminator_inst = block->terminator(); - assert(label_inst != nullptr); - assert(terminator_inst != nullptr); - - if (terminator_inst->opcode() != SpvOpBranch) { - return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(block->id())) - << "For WebGPU, unreachable continue-target must terminate with " - "OpBranch."; - } - - auto label_idx = label_inst - &_.ordered_instructions()[0]; - auto terminator_idx = terminator_inst - &_.ordered_instructions()[0]; - if (label_idx + 1 != terminator_idx) { - return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(block->id())) - << "For WebGPU, unreachable continue-target must only contain " - "an OpLabel and an OpBranch instruction."; - } - - // 3. Use label instruction to confirm there is no uses by branches. - for (auto use : label_inst->uses()) { - const auto* use_inst = use.first; - if (spvOpcodeIsBranch(use_inst->opcode())) { - return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(block->id())) - << "For WebGPU, unreachable continue-target cannot be the " - "target of a branch."; - } - } - - // 4. Confirm that continue-target has a back edge to a reachable loop - // header block. - auto branch_target = terminator_inst->GetOperandAs(0); - for (auto* continue_header : reachable_headers) { - if (branch_target != continue_header->id()) { - return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(block->id())) - << "For WebGPU, unreachable continue-target must only have a " - "back edge to a single reachable loop instruction."; - } - } - } else { - return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(block->id())) - << "For WebGPU, all blocks must be reachable, unless they are " - << "degenerate cases of merge-block or continue-target."; - } - } - return SPV_SUCCESS; -} - spv_result_t PerformCfgChecks(ValidationState_t& _) { for (auto& function : _.functions()) { // Check all referenced blocks are defined within a function @@ -1014,13 +900,6 @@ spv_result_t PerformCfgChecks(ValidationState_t& _) { << _.getIdName(idom->id()); } } - - // For WebGPU check that all unreachable blocks are degenerate cases for - // merge-block or continue-target. - if (spvIsWebGPUEnv(_.context()->target_env)) { - spv_result_t result = PerformWebGPUCfgChecks(_, &function); - if (result != SPV_SUCCESS) return result; - } } // If we have structed control flow, check that no block has a control // flow nesting depth larger than the limit. diff --git a/source/val/validate_composites.cpp b/source/val/validate_composites.cpp index d5b978fff7..5d6c5e3770 100644 --- a/source/val/validate_composites.cpp +++ b/source/val/validate_composites.cpp @@ -535,12 +535,10 @@ 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) { @@ -548,12 +546,6 @@ 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."; - } } if (_.HasCapability(SpvCapabilityShader) && diff --git a/source/val/validate_extensions.cpp b/source/val/validate_extensions.cpp index 17b0446013..af6ae2b7aa 100644 --- a/source/val/validate_extensions.cpp +++ b/source/val/validate_extensions.cpp @@ -685,34 +685,9 @@ bool IsDebugVariableWithIntScalarType(ValidationState_t& _, } // anonymous namespace -spv_result_t ValidateExtension(ValidationState_t& _, const Instruction* inst) { - if (spvIsWebGPUEnv(_.context()->target_env)) { - std::string extension = GetExtensionString(&(inst->c_inst())); - - if (extension != ExtensionToString(kSPV_KHR_vulkan_memory_model)) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "For WebGPU, the only valid parameter to OpExtension is " - << "\"" << ExtensionToString(kSPV_KHR_vulkan_memory_model) - << "\"."; - } - } - - return SPV_SUCCESS; -} - spv_result_t ValidateExtInstImport(ValidationState_t& _, const Instruction* inst) { const auto name_id = 1; - if (spvIsWebGPUEnv(_.context()->target_env)) { - const std::string name(reinterpret_cast( - inst->words().data() + inst->operands()[name_id].offset)); - if (name != "GLSL.std.450") { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "For WebGPU, the only valid parameter to OpExtInstImport is " - "\"GLSL.std.450\"."; - } - } - if (!_.HasExtension(kSPV_KHR_non_semantic_info)) { const std::string name(reinterpret_cast( inst->words().data() + inst->operands()[name_id].offset)); @@ -3149,7 +3124,6 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) { spv_result_t ExtensionPass(ValidationState_t& _, const Instruction* inst) { const SpvOp opcode = inst->opcode(); - if (opcode == SpvOpExtension) return ValidateExtension(_, inst); if (opcode == SpvOpExtInstImport) return ValidateExtInstImport(_, inst); if (opcode == SpvOpExtInst) return ValidateExtInst(_, inst); diff --git a/source/val/validate_image.cpp b/source/val/validate_image.cpp index 9597630b28..f5ba5d1a82 100644 --- a/source/val/validate_image.cpp +++ b/source/val/validate_image.cpp @@ -821,12 +821,11 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) { << "Invalid Sampled " << info.sampled << " (must be 0, 1 or 2)"; } - if (spvIsVulkanEnv(target_env) || spvIsWebGPUEnv(target_env)) { + if (spvIsVulkanEnv(target_env)) { if (info.sampled == 0) { return _.diag(SPV_ERROR_INVALID_DATA, inst) - << _.VkErrorID(4657) << "Sampled must be 1 or 2 in the " - << (spvIsVulkanEnv(target_env) ? "Vulkan" : "WebGPU") - << " environment."; + << _.VkErrorID(4657) + << "Sampled must be 1 or 2 in the Vulkan environment."; } } @@ -1469,9 +1468,9 @@ spv_result_t ValidateImageRead(ValidationState_t& _, const Instruction* inst) { } const auto target_env = _.context()->target_env; - // Vulkan and WebGPU require the result to be a 4-element int or float + // Vulkan requires the result to be a 4-element int or float // vector. - if (spvIsVulkanEnv(target_env) || spvIsWebGPUEnv(target_env)) { + if (spvIsVulkanEnv(target_env)) { if (_.GetDimension(actual_result_type) != 4) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected " << GetActualResultTypeStr(opcode) diff --git a/source/val/validate_memory.cpp b/source/val/validate_memory.cpp index 34ca301bbb..45a232dafc 100644 --- a/source/val/validate_memory.cpp +++ b/source/val/validate_memory.cpp @@ -578,12 +578,12 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { } } - // WebGPU & Vulkan Appendix A: Check that if contains initializer, then + // Vulkan Appendix A: Check that if contains initializer, then // storage class is Output, Private, or Function. if (inst->operands().size() > 3 && storage_class != SpvStorageClassOutput && storage_class != SpvStorageClassPrivate && storage_class != SpvStorageClassFunction) { - if (spvIsVulkanOrWebGPUEnv(_.context()->target_env)) { + if (spvIsVulkanEnv(_.context()->target_env)) { return _.diag(SPV_ERROR_INVALID_ID, inst) << _.VkErrorID(4651) << "OpVariable, '" << _.getIdName(inst->id()) @@ -597,20 +597,6 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { } } - // WebGPU: All variables with storage class Output, Private, or Function MUST - // have an initializer. - if (spvIsWebGPUEnv(_.context()->target_env) && inst->operands().size() <= 3 && - (storage_class == SpvStorageClassOutput || - storage_class == SpvStorageClassPrivate || - storage_class == SpvStorageClassFunction)) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "OpVariable, '" << _.getIdName(inst->id()) - << "', must have an initializer.\n" - << "From WebGPU execution environment spec:\n" - << "All variables in the following storage classes must have an " - << "initializer: Output, Private, or Function"; - } - if (storage_class == SpvStorageClassPhysicalStorageBufferEXT) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "PhysicalStorageBufferEXT must not be used with OpVariable."; @@ -703,41 +689,6 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) { } } - // WebGPU specific validation rules for OpTypeRuntimeArray - if (spvIsWebGPUEnv(_.context()->target_env)) { - // OpTypeRuntimeArray should only ever be in an OpTypeStruct, - // so should never appear as a bare variable. - if (value_type && value_type->opcode() == SpvOpTypeRuntimeArray) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "OpVariable, '" << _.getIdName(inst->id()) - << "', is attempting to create memory for an illegal type, " - << "OpTypeRuntimeArray.\nFor WebGPU OpTypeRuntimeArray can only " - << "appear as the final member of an OpTypeStruct, thus cannot " - << "be instantiated via OpVariable"; - } - - // If an OpStruct has an OpTypeRuntimeArray somewhere within it, then it - // must have the storage class StorageBuffer and be decorated - // with Block. - if (value_type && value_type->opcode() == SpvOpTypeStruct) { - if (DoesStructContainRTA(_, value_type)) { - if (storage_class == SpvStorageClassStorageBuffer) { - if (!_.HasDecoration(value_id, SpvDecorationBlock)) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "For WebGPU, an OpTypeStruct variable containing an " - << "OpTypeRuntimeArray must be decorated with Block if it " - << "has storage class StorageBuffer."; - } - } else { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "For WebGPU, OpTypeStruct variables containing " - << "OpTypeRuntimeArray must have storage class of " - << "StorageBuffer"; - } - } - } - } - // Cooperative matrix types can only be allocated in Function or Private if ((storage_class != SpvStorageClassFunction && storage_class != SpvStorageClassPrivate) && diff --git a/source/val/validate_memory_semantics.cpp b/source/val/validate_memory_semantics.cpp index 6af720f50d..8e47f8a359 100644 --- a/source/val/validate_memory_semantics.cpp +++ b/source/val/validate_memory_semantics.cpp @@ -56,55 +56,6 @@ spv_result_t ValidateMemorySemantics(ValidationState_t& _, return SPV_SUCCESS; } - if (spvIsWebGPUEnv(_.context()->target_env)) { - uint32_t valid_bits; - switch (inst->opcode()) { - case SpvOpControlBarrier: - if (!(value & SpvMemorySemanticsAcquireReleaseMask)) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "For WebGPU, AcquireRelease must be set for Memory " - "Semantics of OpControlBarrier."; - } - - if (!(value & SpvMemorySemanticsWorkgroupMemoryMask)) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "For WebGPU, WorkgroupMemory must be set for Memory " - "Semantics of OpControlBarrier."; - } - - valid_bits = SpvMemorySemanticsAcquireReleaseMask | - SpvMemorySemanticsWorkgroupMemoryMask; - if (value & ~valid_bits) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "For WebGPU only WorkgroupMemory and AcquireRelease may be " - "set for Memory Semantics of OpControlBarrier."; - } - break; - case SpvOpMemoryBarrier: - if (!(value & SpvMemorySemanticsImageMemoryMask)) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "For WebGPU, ImageMemory must be set for Memory Semantics " - "of OpMemoryBarrier."; - } - valid_bits = SpvMemorySemanticsImageMemoryMask; - if (value & ~valid_bits) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "For WebGPU only ImageMemory may be set for Memory " - "Semantics of OpMemoryBarrier."; - } - break; - default: - if (spvOpcodeIsAtomicOp(inst->opcode())) { - if (value != 0) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "For WebGPU Memory no bits may be set for Memory " - "Semantics of OpAtomic* instructions."; - } - } - break; - } - } - const size_t num_memory_order_set_bits = spvtools::utils::CountSetBits( value & (SpvMemorySemanticsAcquireMask | SpvMemorySemanticsReleaseMask | SpvMemorySemanticsAcquireReleaseMask | diff --git a/source/val/validate_misc.cpp b/source/val/validate_misc.cpp index b0bc921968..0c30f3ca72 100644 --- a/source/val/validate_misc.cpp +++ b/source/val/validate_misc.cpp @@ -37,10 +37,6 @@ spv_result_t ValidateUndef(ValidationState_t& _, const Instruction* inst) { << "Cannot create undefined values with 8- or 16-bit types"; } - if (spvIsWebGPUEnv(_.context()->target_env)) { - return _.diag(SPV_ERROR_INVALID_BINARY, inst) << "OpUndef is disallowed"; - } - return SPV_SUCCESS; } diff --git a/source/val/validate_mode_setting.cpp b/source/val/validate_mode_setting.cpp index 6facd1deed..ab550a9236 100644 --- a/source/val/validate_mode_setting.cpp +++ b/source/val/validate_mode_setting.cpp @@ -471,21 +471,6 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _, } } - if (spvIsWebGPUEnv(_.context()->target_env)) { - if (mode != SpvExecutionModeOriginUpperLeft && - mode != SpvExecutionModeDepthReplacing && - mode != SpvExecutionModeDepthGreater && - mode != SpvExecutionModeDepthLess && - mode != SpvExecutionModeDepthUnchanged && - mode != SpvExecutionModeLocalSize && - mode != SpvExecutionModeLocalSizeHint) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Execution mode must be one of OriginUpperLeft, " - "DepthReplacing, DepthGreater, DepthLess, DepthUnchanged, " - "LocalSize, or LocalSizeHint for WebGPU environment."; - } - } - return SPV_SUCCESS; } @@ -500,13 +485,6 @@ spv_result_t ValidateMemoryModel(ValidationState_t& _, "the VulkanKHR memory model is used."; } - if (spvIsWebGPUEnv(_.context()->target_env)) { - if (_.addressing_model() != SpvAddressingModelLogical) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << "Addressing model must be Logical for WebGPU environment."; - } - } - if (spvIsOpenCLEnv(_.context()->target_env)) { if ((_.addressing_model() != SpvAddressingModelPhysical32) && (_.addressing_model() != SpvAddressingModelPhysical64)) { diff --git a/source/val/validate_scopes.cpp b/source/val/validate_scopes.cpp index 73cd6ca244..636d54c43a 100644 --- a/source/val/validate_scopes.cpp +++ b/source/val/validate_scopes.cpp @@ -137,30 +137,6 @@ spv_result_t ValidateExecutionScope(ValidationState_t& _, } } - // WebGPU Specific rules - if (spvIsWebGPUEnv(_.context()->target_env)) { - if (value != SpvScopeWorkgroup) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << spvOpcodeString(opcode) - << ": in WebGPU environment Execution Scope is limited to " - << "Workgroup"; - } else { - _.function(inst->function()->id()) - ->RegisterExecutionModelLimitation( - [](SpvExecutionModel model, std::string* message) { - if (model != SpvExecutionModelGLCompute) { - if (message) { - *message = - ": in WebGPU environment, Workgroup Execution Scope is " - "limited to GLCompute execution model"; - } - return false; - } - return true; - }); - } - } - // TODO(atgoo@github.com) Add checks for OpenCL and OpenGL environments. // General SPIRV rules @@ -260,62 +236,6 @@ spv_result_t ValidateMemoryScope(ValidationState_t& _, const Instruction* inst, } } - // WebGPU specific rules - if (spvIsWebGPUEnv(_.context()->target_env)) { - switch (inst->opcode()) { - case SpvOpControlBarrier: - if (value != SpvScopeWorkgroup) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << spvOpcodeString(opcode) - << ": in WebGPU environment Memory Scope is limited to " - << "Workgroup for OpControlBarrier"; - } - break; - case SpvOpMemoryBarrier: - if (value != SpvScopeWorkgroup) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << spvOpcodeString(opcode) - << ": in WebGPU environment Memory Scope is limited to " - << "Workgroup for OpMemoryBarrier"; - } - break; - default: - if (spvOpcodeIsAtomicOp(inst->opcode())) { - if (value != SpvScopeQueueFamilyKHR) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << spvOpcodeString(opcode) - << ": in WebGPU environment Memory Scope is limited to " - << "QueueFamilyKHR for OpAtomic* operations"; - } - } - - if (value != SpvScopeWorkgroup && value != SpvScopeInvocation && - value != SpvScopeQueueFamilyKHR) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << spvOpcodeString(opcode) - << ": in WebGPU environment Memory Scope is limited to " - << "Workgroup, Invocation, and QueueFamilyKHR"; - } - break; - } - - if (value == SpvScopeWorkgroup) { - _.function(inst->function()->id()) - ->RegisterExecutionModelLimitation( - [](SpvExecutionModel model, std::string* message) { - if (model != SpvExecutionModelGLCompute) { - if (message) { - *message = - ": in WebGPU environment, Workgroup Memory Scope is " - "limited to GLCompute execution model"; - } - return false; - } - return true; - }); - } - } - // TODO(atgoo@github.com) Add checks for OpenCL and OpenGL environments. return SPV_SUCCESS; diff --git a/source/val/validate_type.cpp b/source/val/validate_type.cpp index 8352301b70..6a5ea3c151 100644 --- a/source/val/validate_type.cpp +++ b/source/val/validate_type.cpp @@ -40,21 +40,6 @@ int64_t ConstantLiteralAsInt64(uint32_t width, return static_cast(uint64_t(lo_word) | uint64_t(hi_word) << 32); } -// Returns, as an uint64_t, the literal value from an OpConstant or the -// default value of an OpSpecConstant, assuming it is an integral type. -// For signed integers, relies the rule that literal value is sign extended -// to fill out to word granularity. Assumes that the constant value -// has -int64_t ConstantLiteralAsUint64(uint32_t width, - const std::vector& const_words) { - const uint32_t lo_word = const_words[3]; - if (width <= 32) return lo_word; - assert(width <= 64); - assert(const_words.size() > 4); - const uint32_t hi_word = const_words[4]; // Must exist, per spec. - return (uint64_t(lo_word) | uint64_t(hi_word) << 32); -} - // Validates that type declarations are unique, unless multiple declarations // of the same data type are allowed by the specification. // (see section 2.8 Types and Variables) @@ -240,7 +225,7 @@ spv_result_t ValidateTypeArray(ValidationState_t& _, const Instruction* inst) { << "' is a void type."; } - if (spvIsVulkanOrWebGPUEnv(_.context()->target_env) && + if (spvIsVulkanEnv(_.context()->target_env) && element_type->opcode() == SpvOpTypeRuntimeArray) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpTypeArray Element Type '" << _.getIdName(element_type_id) @@ -279,18 +264,6 @@ spv_result_t ValidateTypeArray(ValidationState_t& _, const Instruction* inst) { << "OpTypeArray Length '" << _.getIdName(length_id) << "' default value must be at least 1: found " << ivalue; } - if (spvIsWebGPUEnv(_.context()->target_env)) { - // WebGPU has maximum integer width of 32 bits, and max array size - // is one more than the max signed integer representation. - const uint64_t max_permitted = (uint64_t(1) << 31); - const uint64_t uvalue = ConstantLiteralAsUint64(width, length->words()); - if (uvalue > max_permitted) { - return _.diag(SPV_ERROR_INVALID_ID, inst) - << "OpTypeArray Length '" << _.getIdName(length_id) - << "' size exceeds max value " << max_permitted - << " permitted by WebGPU: got " << uvalue; - } - } } break; case SpvOpConstantNull: return _.diag(SPV_ERROR_INVALID_ID, inst) @@ -322,7 +295,7 @@ spv_result_t ValidateTypeRuntimeArray(ValidationState_t& _, << _.getIdName(element_id) << "' is a void type."; } - if (spvIsVulkanOrWebGPUEnv(_.context()->target_env) && + if (spvIsVulkanEnv(_.context()->target_env) && element_type->opcode() == SpvOpTypeRuntimeArray) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "OpTypeRuntimeArray Element Type '" @@ -394,7 +367,7 @@ spv_result_t ValidateTypeStruct(ValidationState_t& _, const Instruction* inst) { << "."; } - if (spvIsVulkanOrWebGPUEnv(_.context()->target_env) && + if (spvIsVulkanEnv(_.context()->target_env) && member_type->opcode() == SpvOpTypeRuntimeArray) { const bool is_last_member = member_type_index == inst->operands().size() - 1; diff --git a/source/val/validation_state.cpp b/source/val/validation_state.cpp index fb1069de23..9ecb4eaab5 100644 --- a/source/val/validation_state.cpp +++ b/source/val/validation_state.cpp @@ -1240,23 +1240,6 @@ bool ValidationState_t::ContainsLimitedUseIntOrFloatType(uint32_t id) const { bool ValidationState_t::IsValidStorageClass( SpvStorageClass storage_class) const { - if (spvIsWebGPUEnv(context()->target_env)) { - switch (storage_class) { - case SpvStorageClassUniformConstant: - case SpvStorageClassUniform: - case SpvStorageClassStorageBuffer: - case SpvStorageClassInput: - case SpvStorageClassOutput: - case SpvStorageClassImage: - case SpvStorageClassWorkgroup: - case SpvStorageClassPrivate: - case SpvStorageClassFunction: - return true; - default: - return false; - } - } - if (spvIsVulkanEnv(context()->target_env)) { switch (storage_class) { case SpvStorageClassUniformConstant: diff --git a/test/fuzzers/BUILD.gn b/test/fuzzers/BUILD.gn index be1258a459..ec09b2b067 100644 --- a/test/fuzzers/BUILD.gn +++ b/test/fuzzers/BUILD.gn @@ -39,10 +39,7 @@ if (!build_with_chromium || use_fuzzing_engine) { ":spvtools_opt_legalization_fuzzer", ":spvtools_opt_performance_fuzzer", ":spvtools_opt_size_fuzzer", - ":spvtools_opt_webgputovulkan_fuzzer", - ":spvtools_opt_vulkantowebgpu_fuzzer", ":spvtools_val_fuzzer", - ":spvtools_val_webgpu_fuzzer", ] } } @@ -104,31 +101,12 @@ spvtools_fuzzer("spvtools_opt_size_fuzzer_src") { ] } - -spvtools_fuzzer("spvtools_opt_webgputovulkan_fuzzer_src") { - sources = [ - "spvtools_opt_webgputovulkan_fuzzer.cpp", - ] -} - -spvtools_fuzzer("spvtools_opt_vulkantowebgpu_fuzzer_src") { - sources = [ - "spvtools_opt_vulkantowebgpu_fuzzer.cpp", - ] -} - spvtools_fuzzer("spvtools_val_fuzzer_src") { sources = [ "spvtools_val_fuzzer.cpp", ] } -spvtools_fuzzer("spvtools_val_webgpu_fuzzer_src") { - sources = [ - "spvtools_val_webgpu_fuzzer.cpp", - ] -} - if (!build_with_chromium || use_fuzzing_engine) { fuzzer_test("spvtools_as_fuzzer") { sources = [] @@ -181,22 +159,6 @@ if (!build_with_chromium || use_fuzzing_engine) { seed_corpus = "corpora/spv" } - fuzzer_test("spvtools_opt_webgputovulkan_fuzzer") { - sources = [] - deps = [ - ":spvtools_opt_webgputovulkan_fuzzer_src", - ] - seed_corpus = "corpora/spv" - } - - fuzzer_test("spvtools_opt_vulkantowebgpu_fuzzer") { - sources = [] - deps = [ - ":spvtools_opt_vulkantowebgpu_fuzzer_src", - ] - seed_corpus = "corpora/spv" - } - fuzzer_test("spvtools_val_fuzzer") { sources = [] deps = [ @@ -204,12 +166,4 @@ if (!build_with_chromium || use_fuzzing_engine) { ] seed_corpus = "corpora/spv" } - - fuzzer_test("spvtools_val_webgpu_fuzzer") { - sources = [] - deps = [ - ":spvtools_val_webgpu_fuzzer_src", - ] - seed_corpus = "corpora/spv" - } } diff --git a/test/fuzzers/spvtools_opt_vulkantowebgpu_fuzzer.cpp b/test/fuzzers/spvtools_opt_vulkantowebgpu_fuzzer.cpp deleted file mode 100644 index 9371c0df08..0000000000 --- a/test/fuzzers/spvtools_opt_vulkantowebgpu_fuzzer.cpp +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2019 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include -#include - -#include "spirv-tools/optimizer.hpp" - -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - spvtools::Optimizer optimizer(SPV_ENV_VULKAN_1_1); - optimizer.SetMessageConsumer([](spv_message_level_t, const char*, - const spv_position_t&, const char*) {}); - - std::vector input; - input.resize(size >> 2); - - size_t count = 0; - for (size_t i = 0; (i + 3) < size; i += 4) { - input[count++] = data[i] | (data[i + 1] << 8) | (data[i + 2] << 16) | - (data[i + 3]) << 24; - } - - optimizer.RegisterVulkanToWebGPUPasses(); - optimizer.Run(input.data(), input.size(), &input); - - return 0; -} diff --git a/test/fuzzers/spvtools_opt_webgputovulkan_fuzzer.cpp b/test/fuzzers/spvtools_opt_webgputovulkan_fuzzer.cpp deleted file mode 100644 index 78ddbb75c0..0000000000 --- a/test/fuzzers/spvtools_opt_webgputovulkan_fuzzer.cpp +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2019 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include -#include - -#include "spirv-tools/optimizer.hpp" - -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - spvtools::Optimizer optimizer(SPV_ENV_WEBGPU_0); - optimizer.SetMessageConsumer([](spv_message_level_t, const char*, - const spv_position_t&, const char*) {}); - - std::vector input; - input.resize(size >> 2); - - size_t count = 0; - for (size_t i = 0; (i + 3) < size; i += 4) { - input[count++] = data[i] | (data[i + 1] << 8) | (data[i + 2] << 16) | - (data[i + 3]) << 24; - } - - optimizer.RegisterWebGPUToVulkanPasses(); - optimizer.Run(input.data(), input.size(), &input); - - return 0; -} diff --git a/test/fuzzers/spvtools_val_webgpu_fuzzer.cpp b/test/fuzzers/spvtools_val_webgpu_fuzzer.cpp deleted file mode 100644 index bed6e1a21f..0000000000 --- a/test/fuzzers/spvtools_val_webgpu_fuzzer.cpp +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) 2019 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include -#include - -#include "spirv-tools/libspirv.hpp" - -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - spvtools::SpirvTools tools(SPV_ENV_WEBGPU_0); - tools.SetMessageConsumer([](spv_message_level_t, const char*, - const spv_position_t&, const char*) {}); - - std::vector input; - input.resize(size >> 2); - - size_t count = 0; - for (size_t i = 0; (i + 3) < size; i += 4) { - input[count++] = data[i] | (data[i + 1] << 8) | (data[i + 2] << 16) | - (data[i + 3]) << 24; - } - - tools.Validate(input); - return 0; -} diff --git a/test/opt/CMakeLists.txt b/test/opt/CMakeLists.txt index 3426958783..79cb3fc44c 100644 --- a/test/opt/CMakeLists.txt +++ b/test/opt/CMakeLists.txt @@ -34,7 +34,6 @@ add_spvtools_unittest(TARGET opt dead_insert_elim_test.cpp dead_variable_elim_test.cpp debug_info_manager_test.cpp - decompose_initialized_variables_test.cpp decoration_manager_test.cpp def_use_test.cpp desc_sroa_test.cpp @@ -48,7 +47,6 @@ add_spvtools_unittest(TARGET opt fold_test.cpp freeze_spec_const_test.cpp function_test.cpp - generate_webgpu_initializers_test.cpp graphics_robust_access_test.cpp if_conversion_test.cpp inline_opaque_test.cpp @@ -63,7 +61,6 @@ add_spvtools_unittest(TARGET opt ir_context_test.cpp ir_loader_test.cpp iterator_test.cpp - legalize_vector_shuffle_test.cpp line_debug_info_test.cpp local_access_chain_convert_test.cpp local_redundancy_elimination_test.cpp @@ -88,9 +85,7 @@ add_spvtools_unittest(TARGET opt scalar_replacement_test.cpp set_spec_const_default_value_test.cpp simplification_test.cpp - split_invalid_unreachable_test.cpp strength_reduction_test.cpp - strip_atomic_counter_memory_test.cpp strip_debug_info_test.cpp strip_reflect_info_test.cpp struct_cfg_analysis_test.cpp diff --git a/test/opt/decompose_initialized_variables_test.cpp b/test/opt/decompose_initialized_variables_test.cpp deleted file mode 100644 index 06ba59a584..0000000000 --- a/test/opt/decompose_initialized_variables_test.cpp +++ /dev/null @@ -1,252 +0,0 @@ -// Copyright (c) 2019 Google LLC. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include - -#include "test/opt/pass_fixture.h" -#include "test/opt/pass_utils.h" - -namespace spvtools { -namespace opt { -namespace { - -using DecomposeInitializedVariablesTest = PassTest<::testing::Test>; - -std::string single_entry_header = R"(OpCapability Shader -OpCapability VulkanMemoryModel -OpExtension "SPV_KHR_vulkan_memory_model" -OpMemoryModel Logical Vulkan -OpEntryPoint Vertex %1 "shader" -%uint = OpTypeInt 32 0 -%uint_1 = OpConstant %uint 1 -%4 = OpConstantNull %uint -%void = OpTypeVoid -%6 = OpTypeFunction %void -)"; - -std::string GetFunctionTest(std::string body) { - auto result = single_entry_header; - result += "%_ptr_Function_uint = OpTypePointer Function %uint\n"; - result += "%1 = OpFunction %void None %6\n"; - result += "%8 = OpLabel\n"; - result += body + "\n"; - result += "OpReturn\n"; - result += "OpFunctionEnd\n"; - return result; -} - -TEST_F(DecomposeInitializedVariablesTest, FunctionChanged) { - std::string input = "%9 = OpVariable %_ptr_Function_uint Function %uint_1"; - std::string expected = R"(%9 = OpVariable %_ptr_Function_uint Function -OpStore %9 %uint_1)"; - - SinglePassRunAndCheck( - GetFunctionTest(input), GetFunctionTest(expected), - /* skip_nop = */ false); -} - -TEST_F(DecomposeInitializedVariablesTest, FunctionUnchanged) { - std::string input = "%9 = OpVariable %_ptr_Function_uint Function"; - - SinglePassRunAndCheck( - GetFunctionTest(input), GetFunctionTest(input), /* skip_nop = */ false); -} - -TEST_F(DecomposeInitializedVariablesTest, FunctionMultipleVariables) { - std::string input = R"(%9 = OpVariable %_ptr_Function_uint Function %uint_1 -%10 = OpVariable %_ptr_Function_uint Function %4)"; - std::string expected = R"(%9 = OpVariable %_ptr_Function_uint Function -%10 = OpVariable %_ptr_Function_uint Function -OpStore %9 %uint_1 -OpStore %10 %4)"; - - SinglePassRunAndCheck( - GetFunctionTest(input), GetFunctionTest(expected), - /* skip_nop = */ false); -} - -std::string GetGlobalTest(std::string storage_class, bool initialized, - bool decomposed) { - auto result = single_entry_header; - - result += "%_ptr_" + storage_class + "_uint = OpTypePointer " + - storage_class + " %uint\n"; - if (initialized) { - result += "%8 = OpVariable %_ptr_" + storage_class + "_uint " + - storage_class + " %4\n"; - } else { - result += "%8 = OpVariable %_ptr_" + storage_class + "_uint " + - storage_class + "\n"; - } - result += R"(%1 = OpFunction %void None %9 -%9 = OpLabel -)"; - if (decomposed) result += "OpStore %8 %4\n"; - result += R"(OpReturn -OpFunctionEnd -)"; - return result; -} - -TEST_F(DecomposeInitializedVariablesTest, PrivateChanged) { - std::string input = GetGlobalTest("Private", true, false); - std::string expected = GetGlobalTest("Private", false, true); - SinglePassRunAndCheck( - input, expected, /* skip_nop = */ false); -} - -TEST_F(DecomposeInitializedVariablesTest, PrivateUnchanged) { - std::string input = GetGlobalTest("Private", false, false); - SinglePassRunAndCheck( - input, input, /* skip_nop = */ false); -} - -TEST_F(DecomposeInitializedVariablesTest, OutputChanged) { - std::string input = GetGlobalTest("Output", true, false); - std::string expected = GetGlobalTest("Output", false, true); - SinglePassRunAndCheck( - input, expected, /* skip_nop = */ false); -} - -TEST_F(DecomposeInitializedVariablesTest, OutputUnchanged) { - std::string input = GetGlobalTest("Output", false, false); - SinglePassRunAndCheck( - input, input, /* skip_nop = */ false); -} - -std::string multiple_entry_header = R"(OpCapability Shader -OpCapability VulkanMemoryModel -OpExtension "SPV_KHR_vulkan_memory_model" -OpMemoryModel Logical Vulkan -OpEntryPoint Vertex %1 "vertex" -OpEntryPoint Fragment %2 "fragment" -%uint = OpTypeInt 32 0 -%4 = OpConstantNull %uint -%void = OpTypeVoid -%6 = OpTypeFunction %void -)"; - -std::string GetGlobalMultipleEntryTest(std::string storage_class, - bool initialized, bool decomposed) { - auto result = multiple_entry_header; - result += "%_ptr_" + storage_class + "_uint = OpTypePointer " + - storage_class + " %uint\n"; - if (initialized) { - result += "%8 = OpVariable %_ptr_" + storage_class + "_uint " + - storage_class + " %4\n"; - } else { - result += "%8 = OpVariable %_ptr_" + storage_class + "_uint " + - storage_class + "\n"; - } - result += R"(%1 = OpFunction %void None %9 -%9 = OpLabel -)"; - if (decomposed) result += "OpStore %8 %4\n"; - result += R"(OpReturn -OpFunctionEnd -%2 = OpFunction %void None %10 -%10 = OpLabel -)"; - if (decomposed) result += "OpStore %8 %4\n"; - result += R"(OpReturn -OpFunctionEnd -)"; - - return result; -} - -TEST_F(DecomposeInitializedVariablesTest, PrivateMultipleEntryChanged) { - std::string input = GetGlobalMultipleEntryTest("Private", true, false); - std::string expected = GetGlobalMultipleEntryTest("Private", false, true); - SinglePassRunAndCheck( - input, expected, /* skip_nop = */ false); -} - -TEST_F(DecomposeInitializedVariablesTest, PrivateMultipleEntryUnchanged) { - std::string input = GetGlobalMultipleEntryTest("Private", false, false); - SinglePassRunAndCheck( - input, input, /* skip_nop = */ false); -} - -TEST_F(DecomposeInitializedVariablesTest, OutputMultipleEntryChanged) { - std::string input = GetGlobalMultipleEntryTest("Output", true, false); - std::string expected = GetGlobalMultipleEntryTest("Output", false, true); - SinglePassRunAndCheck( - input, expected, /* skip_nop = */ false); -} - -TEST_F(DecomposeInitializedVariablesTest, OutputMultipleEntryUnchanged) { - std::string input = GetGlobalMultipleEntryTest("Output", false, false); - SinglePassRunAndCheck( - input, input, /* skip_nop = */ false); -} - -std::string GetGlobalWithNonEntryPointTest(std::string storage_class, - bool initialized, bool decomposed) { - auto result = single_entry_header; - result += "%_ptr_" + storage_class + "_uint = OpTypePointer " + - storage_class + " %uint\n"; - if (initialized) { - result += "%8 = OpVariable %_ptr_" + storage_class + "_uint " + - storage_class + " %4\n"; - } else { - result += "%8 = OpVariable %_ptr_" + storage_class + "_uint " + - storage_class + "\n"; - } - result += R"(%1 = OpFunction %void None %9 -%9 = OpLabel -)"; - if (decomposed) result += "OpStore %8 %4\n"; - result += R"(OpReturn -OpFunctionEnd -%10 = OpFunction %void None %11 -%11 = OpLabel -OpReturn -OpFunctionEnd -)"; - - return result; -} - -TEST_F(DecomposeInitializedVariablesTest, PrivateWithNonEntryPointChanged) { - std::string input = GetGlobalWithNonEntryPointTest("Private", true, false); - std::string expected = GetGlobalWithNonEntryPointTest("Private", false, true); - SinglePassRunAndCheck( - input, expected, /* skip_nop = */ false); -} - -TEST_F(DecomposeInitializedVariablesTest, PrivateWithNonEntryPointUnchanged) { - std::string input = GetGlobalWithNonEntryPointTest("Private", false, false); - // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndCheck( - input, input, /* skip_nop = */ false); -} - -TEST_F(DecomposeInitializedVariablesTest, OutputWithNonEntryPointChanged) { - std::string input = GetGlobalWithNonEntryPointTest("Output", true, false); - std::string expected = GetGlobalWithNonEntryPointTest("Output", false, true); - SinglePassRunAndCheck( - input, expected, /* skip_nop = */ false); -} - -TEST_F(DecomposeInitializedVariablesTest, OutputWithNonEntryPointUnchanged) { - std::string input = GetGlobalWithNonEntryPointTest("Output", false, false); - // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS); - SinglePassRunAndCheck( - input, input, /* skip_nop = */ false); -} - -} // namespace -} // namespace opt -} // namespace spvtools diff --git a/test/opt/generate_webgpu_initializers_test.cpp b/test/opt/generate_webgpu_initializers_test.cpp deleted file mode 100644 index 4aab2ce21f..0000000000 --- a/test/opt/generate_webgpu_initializers_test.cpp +++ /dev/null @@ -1,347 +0,0 @@ -// Copyright (c) 2019 Google LLC. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include - -#include "test/opt/pass_fixture.h" -#include "test/opt/pass_utils.h" - -namespace spvtools { -namespace opt { -namespace { - -typedef std::tuple GenerateWebGPUInitializersParam; - -using GlobalVariableTest = - PassTest<::testing::TestWithParam>; -using LocalVariableTest = - PassTest<::testing::TestWithParam>; - -using GenerateWebGPUInitializersTest = PassTest<::testing::Test>; - -void operator+=(std::vector& lhs, const char* rhs) { - lhs.push_back(rhs); -} - -void operator+=(std::vector& lhs, - const std::vector& rhs) { - lhs.reserve(lhs.size() + rhs.size()); - for (auto* c : rhs) lhs.push_back(c); -} - -std::string GetGlobalVariableTestString(std::string ptr_str, - std::string var_str, - std::string const_str = "") { - std::vector result = { - // clang-format off - "OpCapability Shader", - "OpCapability VulkanMemoryModel", - "OpExtension \"SPV_KHR_vulkan_memory_model\"", - "OpMemoryModel Logical Vulkan", - "OpEntryPoint Vertex %1 \"shader\"", - "%uint = OpTypeInt 32 0", - ptr_str.c_str()}; - // clang-format on - - if (!const_str.empty()) result += const_str.c_str(); - - result += { - // clang-format off - var_str.c_str(), - "%uint_0 = OpConstant %uint 0", - "%void = OpTypeVoid", - "%7 = OpTypeFunction %void", - "%1 = OpFunction %void None %7", - "%8 = OpLabel", - "OpStore %4 %uint_0", - "OpReturn", - "OpFunctionEnd" - // clang-format on - }; - return JoinAllInsts(result); -} - -std::string GetPointerString(std::string storage_type) { - std::string result = "%_ptr_"; - result += storage_type + "_uint = OpTypePointer "; - result += storage_type + " %uint"; - return result; -} - -std::string GetGlobalVariableString(std::string storage_type, - bool initialized) { - std::string result = "%4 = OpVariable %_ptr_"; - result += storage_type + "_uint "; - result += storage_type; - if (initialized) result += " %9"; - return result; -} - -std::string GetUninitializedGlobalVariableTestString(std::string storage_type) { - return GetGlobalVariableTestString( - GetPointerString(storage_type), - GetGlobalVariableString(storage_type, false)); -} - -std::string GetNullConstantString() { return "%9 = OpConstantNull %uint"; } - -std::string GetInitializedGlobalVariableTestString(std::string storage_type) { - return GetGlobalVariableTestString( - GetPointerString(storage_type), - GetGlobalVariableString(storage_type, true), GetNullConstantString()); -} - -TEST_P(GlobalVariableTest, Check) { - std::string storage_class = std::get<0>(GetParam()); - bool changed = std::get<1>(GetParam()); - std::string input = GetUninitializedGlobalVariableTestString(storage_class); - std::string expected = - changed ? GetInitializedGlobalVariableTestString(storage_class) : input; - - SinglePassRunAndCheck(input, expected, - /* skip_nop = */ false); -} - -// clang-format off -INSTANTIATE_TEST_SUITE_P( - GenerateWebGPUInitializers, GlobalVariableTest, - ::testing::ValuesIn(std::vector({ - std::make_tuple("Private", true), - std::make_tuple("Output", true), - std::make_tuple("Function", true), - std::make_tuple("UniformConstant", false), - std::make_tuple("Input", false), - std::make_tuple("Uniform", false), - std::make_tuple("Workgroup", false) - }))); -// clang-format on - -std::string GetLocalVariableTestString(std::string ptr_str, std::string var_str, - std::string const_str = "") { - std::vector result = { - // clang-format off - "OpCapability Shader", - "OpCapability VulkanMemoryModel", - "OpExtension \"SPV_KHR_vulkan_memory_model\"", - "OpMemoryModel Logical Vulkan", - "OpEntryPoint Vertex %1 \"shader\"", - "%uint = OpTypeInt 32 0", - ptr_str.c_str(), - "%uint_0 = OpConstant %uint 0", - "%void = OpTypeVoid", - "%6 = OpTypeFunction %void"}; - // clang-format on - - if (!const_str.empty()) result += const_str.c_str(); - - result += { - // clang-format off - "%1 = OpFunction %void None %6", - "%7 = OpLabel", - var_str.c_str(), - "OpStore %8 %uint_0" - // clang-format on - }; - return JoinAllInsts(result); -} - -std::string GetLocalVariableString(std::string storage_type, bool initialized) { - std::string result = "%8 = OpVariable %_ptr_"; - result += storage_type + "_uint "; - result += storage_type; - if (initialized) result += " %9"; - return result; -} - -std::string GetUninitializedLocalVariableTestString(std::string storage_type) { - return GetLocalVariableTestString( - GetPointerString(storage_type), - GetLocalVariableString(storage_type, false)); -} - -std::string GetInitializedLocalVariableTestString(std::string storage_type) { - return GetLocalVariableTestString(GetPointerString(storage_type), - GetLocalVariableString(storage_type, true), - GetNullConstantString()); -} - -TEST_P(LocalVariableTest, Check) { - std::string storage_class = std::get<0>(GetParam()); - bool changed = std::get<1>(GetParam()); - - std::string input = GetUninitializedLocalVariableTestString(storage_class); - std::string expected = - changed ? GetInitializedLocalVariableTestString(storage_class) : input; - - SinglePassRunAndCheck(input, expected, - /* skip_nop = */ false); -} - -// clang-format off -INSTANTIATE_TEST_SUITE_P( - GenerateWebGPUInitializers, LocalVariableTest, - ::testing::ValuesIn(std::vector({ - std::make_tuple("Private", true), - std::make_tuple("Output", true), - std::make_tuple("Function", true), - std::make_tuple("UniformConstant", false), - std::make_tuple("Input", false), - std::make_tuple("Uniform", false), - std::make_tuple("Workgroup", false) - }))); -// clang-format on - -TEST_F(GenerateWebGPUInitializersTest, AlreadyInitializedUnchanged) { - std::vector spirv = { - // clang-format off - "OpCapability Shader", - "OpCapability VulkanMemoryModel", - "OpExtension \"SPV_KHR_vulkan_memory_model\"", - "OpMemoryModel Logical Vulkan", - "OpEntryPoint Vertex %1 \"shader\"", - "%uint = OpTypeInt 32 0", - "%_ptr_Private_uint = OpTypePointer Private %uint", - "%uint_0 = OpConstant %uint 0", - "%5 = OpVariable %_ptr_Private_uint Private %uint_0", - "%void = OpTypeVoid", - "%7 = OpTypeFunction %void", - "%1 = OpFunction %void None %7", - "%8 = OpLabel", - "OpReturn", - "OpFunctionEnd" - // clang-format on - }; - std::string str = JoinAllInsts(spirv); - - SinglePassRunAndCheck(str, str, - /* skip_nop = */ false); -} - -TEST_F(GenerateWebGPUInitializersTest, AmbigiousArrays) { - std::vector input_spirv = { - // clang-format off - "OpCapability Shader", - "OpCapability VulkanMemoryModel", - "OpExtension \"SPV_KHR_vulkan_memory_model\"", - "OpMemoryModel Logical Vulkan", - "OpEntryPoint Vertex %1 \"shader\"", - "%uint = OpTypeInt 32 0", - "%uint_2 = OpConstant %uint 2", - "%_arr_uint_uint_2 = OpTypeArray %uint %uint_2", - "%_arr_uint_uint_2_0 = OpTypeArray %uint %uint_2", - "%_ptr_Private__arr_uint_uint_2 = OpTypePointer Private %_arr_uint_uint_2", -"%_ptr_Private__arr_uint_uint_2_0 = OpTypePointer Private %_arr_uint_uint_2_0", - "%8 = OpConstantNull %_arr_uint_uint_2_0", - "%9 = OpVariable %_ptr_Private__arr_uint_uint_2 Private", - "%10 = OpVariable %_ptr_Private__arr_uint_uint_2_0 Private %8", - "%void = OpTypeVoid", - "%12 = OpTypeFunction %void", - "%1 = OpFunction %void None %12", - "%13 = OpLabel", - "OpReturn", - "OpFunctionEnd" - // clang-format on - }; - std::string input_str = JoinAllInsts(input_spirv); - - std::vector expected_spirv = { - // clang-format off - "OpCapability Shader", - "OpCapability VulkanMemoryModel", - "OpExtension \"SPV_KHR_vulkan_memory_model\"", - "OpMemoryModel Logical Vulkan", - "OpEntryPoint Vertex %1 \"shader\"", - "%uint = OpTypeInt 32 0", - "%uint_2 = OpConstant %uint 2", - "%_arr_uint_uint_2 = OpTypeArray %uint %uint_2", - "%_arr_uint_uint_2_0 = OpTypeArray %uint %uint_2", - "%_ptr_Private__arr_uint_uint_2 = OpTypePointer Private %_arr_uint_uint_2", -"%_ptr_Private__arr_uint_uint_2_0 = OpTypePointer Private %_arr_uint_uint_2_0", - "%8 = OpConstantNull %_arr_uint_uint_2_0", - "%14 = OpConstantNull %_arr_uint_uint_2", - "%9 = OpVariable %_ptr_Private__arr_uint_uint_2 Private %14", - "%10 = OpVariable %_ptr_Private__arr_uint_uint_2_0 Private %8", - "%void = OpTypeVoid", - "%12 = OpTypeFunction %void", - "%1 = OpFunction %void None %12", - "%13 = OpLabel", - "OpReturn", - "OpFunctionEnd" - // clang-format on - }; - std::string expected_str = JoinAllInsts(expected_spirv); - - SinglePassRunAndCheck(input_str, expected_str, - /* skip_nop = */ false); -} - -TEST_F(GenerateWebGPUInitializersTest, AmbigiousStructs) { - std::vector input_spirv = { - // clang-format off - "OpCapability Shader", - "OpCapability VulkanMemoryModel", - "OpExtension \"SPV_KHR_vulkan_memory_model\"", - "OpMemoryModel Logical Vulkan", - "OpEntryPoint Vertex %1 \"shader\"", - "%uint = OpTypeInt 32 0", - "%_struct_3 = OpTypeStruct %uint", - "%_struct_4 = OpTypeStruct %uint", -"%_ptr_Private__struct_3 = OpTypePointer Private %_struct_3", -"%_ptr_Private__struct_4 = OpTypePointer Private %_struct_4", - "%7 = OpConstantNull %_struct_3", - "%8 = OpVariable %_ptr_Private__struct_3 Private %7", - "%9 = OpVariable %_ptr_Private__struct_4 Private", - "%void = OpTypeVoid", - "%11 = OpTypeFunction %void", - "%1 = OpFunction %void None %11", - "%12 = OpLabel", - "OpReturn", - "OpFunctionEnd" - // clang-format on - }; - std::string input_str = JoinAllInsts(input_spirv); - - std::vector expected_spirv = { - // clang-format off - "OpCapability Shader", - "OpCapability VulkanMemoryModel", - "OpExtension \"SPV_KHR_vulkan_memory_model\"", - "OpMemoryModel Logical Vulkan", - "OpEntryPoint Vertex %1 \"shader\"", - "%uint = OpTypeInt 32 0", - "%_struct_3 = OpTypeStruct %uint", - "%_struct_4 = OpTypeStruct %uint", -"%_ptr_Private__struct_3 = OpTypePointer Private %_struct_3", -"%_ptr_Private__struct_4 = OpTypePointer Private %_struct_4", - "%7 = OpConstantNull %_struct_3", - "%8 = OpVariable %_ptr_Private__struct_3 Private %7", - "%13 = OpConstantNull %_struct_4", - "%9 = OpVariable %_ptr_Private__struct_4 Private %13", - "%void = OpTypeVoid", - "%11 = OpTypeFunction %void", - "%1 = OpFunction %void None %11", - "%12 = OpLabel", - "OpReturn", - "OpFunctionEnd" - // clang-format on - }; - std::string expected_str = JoinAllInsts(expected_spirv); - - SinglePassRunAndCheck(input_str, expected_str, - /* skip_nop = */ false); -} - -} // namespace -} // namespace opt -} // namespace spvtools diff --git a/test/opt/legalize_vector_shuffle_test.cpp b/test/opt/legalize_vector_shuffle_test.cpp deleted file mode 100644 index 07d96eb379..0000000000 --- a/test/opt/legalize_vector_shuffle_test.cpp +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (c) 2019 Google LLC. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include - -#include "test/opt/pass_fixture.h" -#include "test/opt/pass_utils.h" - -namespace spvtools { -namespace opt { -namespace { - -using LegalizeVectorShuffleTest = PassTest<::testing::Test>; - -void operator+=(std::vector& lhs, const char* rhs) { - lhs.push_back(rhs); -} - -void operator+=(std::vector& lhs, - const std::vector rhs) { - for (auto elem : rhs) lhs.push_back(elem); -} - -std::vector header = { - "OpCapability Shader", - "OpCapability VulkanMemoryModel", - "OpExtension \"SPV_KHR_vulkan_memory_model\"", - "OpMemoryModel Logical Vulkan", - "OpEntryPoint Vertex %1 \"shader\"", - "%uint = OpTypeInt 32 0", - "%v3uint = OpTypeVector %uint 3"}; - -std::string GetTestString(const char* shuffle) { - std::vector result = header; - result += {"%_ptr_Function_v3uint = OpTypePointer Function %v3uint", - "%void = OpTypeVoid", - "%6 = OpTypeFunction %void", - "%1 = OpFunction %void None %6", - "%7 = OpLabel", - "%8 = OpVariable %_ptr_Function_v3uint Function", - "%9 = OpLoad %v3uint %8", - "%10 = OpLoad %v3uint %8"}; - result += shuffle; - result += {"OpReturn", "OpFunctionEnd"}; - return JoinAllInsts(result); -} - -TEST_F(LegalizeVectorShuffleTest, Changed) { - std::string input = - GetTestString("%11 = OpVectorShuffle %v3uint %9 %10 2 1 0xFFFFFFFF"); - std::string expected = - GetTestString("%11 = OpVectorShuffle %v3uint %9 %10 2 1 0"); - - SinglePassRunAndCheck(input, expected, - /* skip_nop = */ false); -} - -TEST_F(LegalizeVectorShuffleTest, FunctionUnchanged) { - std::string input = - GetTestString("%11 = OpVectorShuffle %v3uint %9 %10 2 1 0"); - std::string expected = - GetTestString("%11 = OpVectorShuffle %v3uint %9 %10 2 1 0"); - - SinglePassRunAndCheck(input, expected, - /* skip_nop = */ false); -} - -} // namespace -} // namespace opt -} // namespace spvtools diff --git a/test/opt/optimizer_test.cpp b/test/opt/optimizer_test.cpp index 945aa78265..5287c4da69 100644 --- a/test/opt/optimizer_test.cpp +++ b/test/opt/optimizer_test.cpp @@ -221,498 +221,6 @@ TEST(Optimizer, CanRegisterPassesFromFlags) { EXPECT_EQ(msg_level, SPV_MSG_ERROR); } -TEST(Optimizer, VulkanToWebGPUSetsCorrectPasses) { - Optimizer opt(SPV_ENV_VULKAN_1_1); - opt.RegisterVulkanToWebGPUPasses(); - std::vector pass_names = opt.GetPassNames(); - - std::vector registered_passes; - for (auto name = pass_names.begin(); name != pass_names.end(); ++name) - registered_passes.push_back(*name); - - std::vector expected_passes = {"eliminate-dead-branches", - "eliminate-dead-code-aggressive", - "eliminate-dead-const", - "flatten-decorations", - "strip-atomic-counter-memory", - "generate-webgpu-initializers", - "legalize-vector-shuffle", - "split-invalid-unreachable", - "compact-ids"}; - std::sort(registered_passes.begin(), registered_passes.end()); - std::sort(expected_passes.begin(), expected_passes.end()); - - ASSERT_EQ(registered_passes.size(), expected_passes.size()); - for (size_t i = 0; i < registered_passes.size(); i++) - EXPECT_EQ(registered_passes[i], expected_passes[i]); -} - -struct VulkanToWebGPUPassCase { - // Input SPIR-V - std::string input; - // Expected result SPIR-V - std::string expected; - // Specific pass under test, used for logging messages. - std::string pass; -}; - -using VulkanToWebGPUPassTest = - PassTest<::testing::TestWithParam>; - -TEST_P(VulkanToWebGPUPassTest, Ran) { - std::vector binary; - { - SpirvTools tools(SPV_ENV_VULKAN_1_1); - tools.Assemble(GetParam().input, &binary); - } - - Optimizer opt(SPV_ENV_VULKAN_1_1); - opt.RegisterVulkanToWebGPUPasses(); - - std::vector optimized; - class ValidatorOptions validator_options; - ASSERT_TRUE(opt.Run(binary.data(), binary.size(), &optimized, - validator_options, true)) - << GetParam().input << "\n"; - std::string disassembly; - { - SpirvTools tools(SPV_ENV_WEBGPU_0); - tools.Disassemble(optimized.data(), optimized.size(), &disassembly); - } - - EXPECT_EQ(GetParam().expected, disassembly) - << "Was expecting pass '" << GetParam().pass << "' to have been run.\n"; -} - -INSTANTIATE_TEST_SUITE_P( - Optimizer, VulkanToWebGPUPassTest, - ::testing::ValuesIn(std::vector{ - // FlattenDecorations - {// input - "OpCapability Shader\n" - "OpCapability VulkanMemoryModel\n" - "OpExtension \"SPV_KHR_vulkan_memory_model\"\n" - "OpMemoryModel Logical Vulkan\n" - "OpEntryPoint Fragment %main \"main\" %hue %saturation %value\n" - "OpExecutionMode %main OriginUpperLeft\n" - "OpDecorate %group Flat\n" - "OpDecorate %group NoPerspective\n" - "%group = OpDecorationGroup\n" - "%void = OpTypeVoid\n" - "%void_fn = OpTypeFunction %void\n" - "%float = OpTypeFloat 32\n" - "%_ptr_Input_float = OpTypePointer Input %float\n" - "%hue = OpVariable %_ptr_Input_float Input\n" - "%saturation = OpVariable %_ptr_Input_float Input\n" - "%value = OpVariable %_ptr_Input_float Input\n" - "%main = OpFunction %void None %void_fn\n" - "%entry = OpLabel\n" - "OpReturn\n" - "OpFunctionEnd\n", - // expected - "OpCapability Shader\n" - "OpCapability VulkanMemoryModel\n" - "OpExtension \"SPV_KHR_vulkan_memory_model\"\n" - "OpMemoryModel Logical Vulkan\n" - "OpEntryPoint Fragment %1 \"main\" %2 %3 %4\n" - "OpExecutionMode %1 OriginUpperLeft\n" - "%void = OpTypeVoid\n" - "%6 = OpTypeFunction %void\n" - "%float = OpTypeFloat 32\n" - "%_ptr_Input_float = OpTypePointer Input %float\n" - "%2 = OpVariable %_ptr_Input_float Input\n" - "%3 = OpVariable %_ptr_Input_float Input\n" - "%4 = OpVariable %_ptr_Input_float Input\n" - "%1 = OpFunction %void None %6\n" - "%9 = OpLabel\n" - "OpReturn\n" - "OpFunctionEnd\n", - // pass - "flatten-decorations"}, - // Eliminate Dead Constants - {// input - "OpCapability Shader\n" - "OpCapability VulkanMemoryModel\n" - "OpExtension \"SPV_KHR_vulkan_memory_model\"\n" - "OpMemoryModel Logical Vulkan\n" - "OpEntryPoint Vertex %func \"shader\"\n" - "%u32 = OpTypeInt 32 0\n" - "%u32_ptr = OpTypePointer Workgroup %u32\n" - "%u32_var = OpVariable %u32_ptr Workgroup\n" - "%u32_1 = OpConstant %u32 1\n" - "%cross_device = OpConstant %u32 0\n" - "%relaxed = OpConstant %u32 0\n" - "%acquire_release_atomic_counter_workgroup = OpConstant %u32 1288\n" - "%void = OpTypeVoid\n" - "%void_f = OpTypeFunction %void\n" - "%func = OpFunction %void None %void_f\n" - "%label = OpLabel\n" - "OpReturn\n" - "OpFunctionEnd\n", - // expected - "OpCapability Shader\n" - "OpCapability VulkanMemoryModel\n" - "OpExtension \"SPV_KHR_vulkan_memory_model\"\n" - "OpMemoryModel Logical Vulkan\n" - "OpEntryPoint Vertex %1 \"shader\"\n" - "%uint = OpTypeInt 32 0\n" - "%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint\n" - "%4 = OpVariable %_ptr_Workgroup_uint Workgroup\n" - "%void = OpTypeVoid\n" - "%6 = OpTypeFunction %void\n" - "%1 = OpFunction %void None %6\n" - "%7 = OpLabel\n" - "OpReturn\n" - "OpFunctionEnd\n", - "eliminate-dead-const"}, - // Strip Atomic Counter Memory - {// input - "OpCapability Shader\n" - "OpCapability VulkanMemoryModel\n" - "OpExtension \"SPV_KHR_vulkan_memory_model\"\n" - "OpMemoryModel Logical Vulkan\n" - "OpEntryPoint Vertex %func \"shader\"\n" - "%u32 = OpTypeInt 32 0\n" - "%u32_ptr = OpTypePointer Workgroup %u32\n" - "%u32_var = OpVariable %u32_ptr Workgroup\n" - "%u32_0 = OpConstant %u32 0\n" - "%u32_1 = OpConstant %u32 1\n" - "%cross_device = OpConstant %u32 0\n" - "%acquire_release_atomic_counter_workgroup = OpConstant %u32 1288\n" - "%void = OpTypeVoid\n" - "%void_f = OpTypeFunction %void\n" - "%func = OpFunction %void None %void_f\n" - "%label = OpLabel\n" - " OpAtomicStore %u32_var %cross_device " - "%acquire_release_atomic_counter_workgroup %u32_1\n" - "%val1 = OpAtomicIIncrement %u32 %u32_var %cross_device " - "%acquire_release_atomic_counter_workgroup\n" - "%val2 = OpAtomicCompareExchange %u32 %u32_var %cross_device " - "%acquire_release_atomic_counter_workgroup " - "%acquire_release_atomic_counter_workgroup %u32_0 %u32_0\n" - "OpReturn\n" - "OpFunctionEnd\n", - // expected - "OpCapability Shader\n" - "OpCapability VulkanMemoryModel\n" - "OpExtension \"SPV_KHR_vulkan_memory_model\"\n" - "OpMemoryModel Logical Vulkan\n" - "OpEntryPoint Vertex %1 \"shader\"\n" - "%uint = OpTypeInt 32 0\n" - "%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint\n" - "%4 = OpVariable %_ptr_Workgroup_uint Workgroup\n" - "%uint_0 = OpConstant %uint 0\n" - "%uint_1 = OpConstant %uint 1\n" - "%uint_0_0 = OpConstant %uint 0\n" - "%void = OpTypeVoid\n" - "%9 = OpTypeFunction %void\n" - "%uint_264 = OpConstant %uint 264\n" - "%1 = OpFunction %void None %9\n" - "%11 = OpLabel\n" - "OpAtomicStore %4 %uint_0_0 %uint_264 %uint_1\n" - "%12 = OpAtomicIIncrement %uint %4 %uint_0_0 %uint_264\n" - "%13 = OpAtomicCompareExchange %uint %4 %uint_0_0 %uint_264 %uint_264 " - "%uint_0 %uint_0\n" - "OpReturn\n" - "OpFunctionEnd\n", - // pass - "strip-atomic-counter-memory"}, - // Generate WebGPU Initializers - {// input - "OpCapability Shader\n" - "OpCapability VulkanMemoryModel\n" - "OpExtension \"SPV_KHR_vulkan_memory_model\"\n" - "OpMemoryModel Logical Vulkan\n" - "OpEntryPoint Vertex %func \"shader\"\n" - "%u32 = OpTypeInt 32 0\n" - "%u32_ptr = OpTypePointer Private %u32\n" - "%u32_var = OpVariable %u32_ptr Private\n" - "%u32_0 = OpConstant %u32 0\n" - "%void = OpTypeVoid\n" - "%void_f = OpTypeFunction %void\n" - "%func = OpFunction %void None %void_f\n" - "%label = OpLabel\n" - "OpStore %u32_var %u32_0\n" - "OpReturn\n" - "OpFunctionEnd\n", - // expected - "OpCapability Shader\n" - "OpCapability VulkanMemoryModel\n" - "OpExtension \"SPV_KHR_vulkan_memory_model\"\n" - "OpMemoryModel Logical Vulkan\n" - "OpEntryPoint Vertex %1 \"shader\"\n" - "%uint = OpTypeInt 32 0\n" - "%_ptr_Private_uint = OpTypePointer Private %uint\n" - "%4 = OpConstantNull %uint\n" - "%5 = OpVariable %_ptr_Private_uint Private %4\n" - "%uint_0 = OpConstant %uint 0\n" - "%void = OpTypeVoid\n" - "%8 = OpTypeFunction %void\n" - "%1 = OpFunction %void None %8\n" - "%9 = OpLabel\n" - "OpStore %5 %uint_0\n" - "OpReturn\n" - "OpFunctionEnd\n", - // pass - "generate-webgpu-initializers"}, - // Legalize Vector Shuffle - {// input - "OpCapability Shader\n" - "OpCapability VulkanMemoryModel\n" - "OpExtension \"SPV_KHR_vulkan_memory_model\"\n" - "OpMemoryModel Logical Vulkan\n" - "OpEntryPoint Vertex %1 \"shader\"\n" - "%uint = OpTypeInt 32 0\n" - "%v3uint = OpTypeVector %uint 3\n" - "%_ptr_Function_v3uint = OpTypePointer Function %v3uint\n" - "%void = OpTypeVoid\n" - "%6 = OpTypeFunction %void\n" - "%1 = OpFunction %void None %6\n" - "%7 = OpLabel\n" - "%8 = OpVariable %_ptr_Function_v3uint Function\n" - "%9 = OpLoad %v3uint %8\n" - "%10 = OpLoad %v3uint %8\n" - "%11 = OpVectorShuffle %v3uint %9 %10 2 1 0xFFFFFFFF\n" - "OpReturn\n" - "OpFunctionEnd\n", - // expected - "OpCapability Shader\n" - "OpCapability VulkanMemoryModel\n" - "OpExtension \"SPV_KHR_vulkan_memory_model\"\n" - "OpMemoryModel Logical Vulkan\n" - "OpEntryPoint Vertex %1 \"shader\"\n" - "%uint = OpTypeInt 32 0\n" - "%v3uint = OpTypeVector %uint 3\n" - "%_ptr_Function_v3uint = OpTypePointer Function %v3uint\n" - "%void = OpTypeVoid\n" - "%6 = OpTypeFunction %void\n" - "%7 = OpConstantNull %v3uint\n" - "%1 = OpFunction %void None %6\n" - "%8 = OpLabel\n" - "%9 = OpVariable %_ptr_Function_v3uint Function %7\n" - "%10 = OpLoad %v3uint %9\n" - "%11 = OpLoad %v3uint %9\n" - "%12 = OpVectorShuffle %v3uint %10 %11 2 1 0\n" - "OpReturn\n" - "OpFunctionEnd\n", - // pass - "legalize-vector-shuffle"}, - // Split Invalid Unreachable - {// input - "OpCapability Shader\n" - "OpCapability VulkanMemoryModel\n" - "OpExtension \"SPV_KHR_vulkan_memory_model\"\n" - "OpMemoryModel Logical Vulkan\n" - "OpEntryPoint Vertex %1 \"shader\"\n" - "%uint = OpTypeInt 32 0\n" - "%uint_1 = OpConstant %uint 1\n" - "%uint_2 = OpConstant %uint 2\n" - "%void = OpTypeVoid\n" - "%bool = OpTypeBool\n" - "%7 = OpTypeFunction %void\n" - "%1 = OpFunction %void None %7\n" - "%8 = OpLabel\n" - "OpBranch %9\n" - "%9 = OpLabel\n" - "OpLoopMerge %10 %11 None\n" - "OpBranch %12\n" - "%12 = OpLabel\n" - "%13 = OpSLessThan %bool %uint_1 %uint_2\n" - "OpSelectionMerge %11 None\n" - "OpBranchConditional %13 %14 %15\n" - "%14 = OpLabel\n" - "OpReturn\n" - "%15 = OpLabel\n" - "OpReturn\n" - "%10 = OpLabel\n" - "OpUnreachable\n" - "%11 = OpLabel\n" - "OpBranch %9\n" - "OpFunctionEnd\n", - // expected - "OpCapability Shader\n" - "OpCapability VulkanMemoryModel\n" - "OpExtension \"SPV_KHR_vulkan_memory_model\"\n" - "OpMemoryModel Logical Vulkan\n" - "OpEntryPoint Vertex %1 \"shader\"\n" - "%uint = OpTypeInt 32 0\n" - "%uint_1 = OpConstant %uint 1\n" - "%uint_2 = OpConstant %uint 2\n" - "%void = OpTypeVoid\n" - "%bool = OpTypeBool\n" - "%7 = OpTypeFunction %void\n" - "%1 = OpFunction %void None %7\n" - "%8 = OpLabel\n" - "OpBranch %9\n" - "%9 = OpLabel\n" - "OpLoopMerge %10 %11 None\n" - "OpBranch %12\n" - "%12 = OpLabel\n" - "%13 = OpSLessThan %bool %uint_1 %uint_2\n" - "OpSelectionMerge %14 None\n" - "OpBranchConditional %13 %15 %16\n" - "%15 = OpLabel\n" - "OpReturn\n" - "%16 = OpLabel\n" - "OpReturn\n" - "%10 = OpLabel\n" - "OpUnreachable\n" - "%14 = OpLabel\n" - "OpUnreachable\n" - "%11 = OpLabel\n" - "OpBranch %9\n" - "OpFunctionEnd\n", - // pass - "split-invalid-unreachable"}, - // Compact IDs - {// input - "OpCapability Shader\n" - "OpCapability VulkanMemoryModel\n" - "OpExtension \"SPV_KHR_vulkan_memory_model\"\n" - "OpMemoryModel Logical Vulkan\n" - "OpEntryPoint Vertex %1000 \"shader\"\n" - "%10 = OpTypeVoid\n" - "%100 = OpTypeFunction %10\n" - "%1000 = OpFunction %10 None %100\n" - "%10000 = OpLabel\n" - "OpReturn\n" - "OpFunctionEnd\n", - // expected - "OpCapability Shader\n" - "OpCapability VulkanMemoryModel\n" - "OpExtension \"SPV_KHR_vulkan_memory_model\"\n" - "OpMemoryModel Logical Vulkan\n" - "OpEntryPoint Vertex %1 \"shader\"\n" - "%void = OpTypeVoid\n" - "%3 = OpTypeFunction %void\n" - "%1 = OpFunction %void None %3\n" - "%4 = OpLabel\n" - "OpReturn\n" - "OpFunctionEnd\n", - // pass - "compact-ids"}})); - -TEST(Optimizer, WebGPUToVulkanSetsCorrectPasses) { - Optimizer opt(SPV_ENV_WEBGPU_0); - opt.RegisterWebGPUToVulkanPasses(); - std::vector pass_names = opt.GetPassNames(); - - std::vector registered_passes; - for (auto name = pass_names.begin(); name != pass_names.end(); ++name) - registered_passes.push_back(*name); - - std::vector expected_passes = {"decompose-initialized-variables", - "compact-ids"}; - std::sort(registered_passes.begin(), registered_passes.end()); - std::sort(expected_passes.begin(), expected_passes.end()); - - ASSERT_EQ(registered_passes.size(), expected_passes.size()); - for (size_t i = 0; i < registered_passes.size(); i++) - EXPECT_EQ(registered_passes[i], expected_passes[i]); -} - -struct WebGPUToVulkanPassCase { - // Input SPIR-V - std::string input; - // Expected result SPIR-V - std::string expected; - // Specific pass under test, used for logging messages. - std::string pass; -}; - -using WebGPUToVulkanPassTest = - PassTest<::testing::TestWithParam>; - -TEST_P(WebGPUToVulkanPassTest, Ran) { - std::vector binary; - { - SpirvTools tools(SPV_ENV_WEBGPU_0); - tools.Assemble(GetParam().input, &binary); - } - - Optimizer opt(SPV_ENV_WEBGPU_0); - opt.RegisterWebGPUToVulkanPasses(); - - std::vector optimized; - class ValidatorOptions validator_options; - ASSERT_TRUE(opt.Run(binary.data(), binary.size(), &optimized, - validator_options, true)); - std::string disassembly; - { - SpirvTools tools(SPV_ENV_VULKAN_1_1); - tools.Disassemble(optimized.data(), optimized.size(), &disassembly); - } - - EXPECT_EQ(GetParam().expected, disassembly) - << "Was expecting pass '" << GetParam().pass << "' to have been run.\n"; -} - -INSTANTIATE_TEST_SUITE_P( - Optimizer, WebGPUToVulkanPassTest, - ::testing::ValuesIn(std::vector{ - // Decompose Initialized Variables - {// input - "OpCapability Shader\n" - "OpCapability VulkanMemoryModel\n" - "OpExtension \"SPV_KHR_vulkan_memory_model\"\n" - "OpMemoryModel Logical Vulkan\n" - "OpEntryPoint Vertex %1 \"shader\"\n" - "%uint = OpTypeInt 32 0\n" - "%_ptr_Function_uint = OpTypePointer Function %uint\n" - "%4 = OpConstantNull %uint\n" - "%void = OpTypeVoid\n" - "%6 = OpTypeFunction %void\n" - "%1 = OpFunction %void None %6\n" - "%7 = OpLabel\n" - "%8 = OpVariable %_ptr_Function_uint Function %4\n" - "OpReturn\n" - "OpFunctionEnd\n", - // expected - "OpCapability Shader\n" - "OpCapability VulkanMemoryModel\n" - "OpExtension \"SPV_KHR_vulkan_memory_model\"\n" - "OpMemoryModel Logical Vulkan\n" - "OpEntryPoint Vertex %1 \"shader\"\n" - "%uint = OpTypeInt 32 0\n" - "%_ptr_Function_uint = OpTypePointer Function %uint\n" - "%4 = OpConstantNull %uint\n" - "%void = OpTypeVoid\n" - "%6 = OpTypeFunction %void\n" - "%1 = OpFunction %void None %6\n" - "%7 = OpLabel\n" - "%8 = OpVariable %_ptr_Function_uint Function\n" - "OpStore %8 %4\n" - "OpReturn\n" - "OpFunctionEnd\n", - // pass - "decompose-initialized-variables"}, - // Compact IDs - {// input - "OpCapability Shader\n" - "OpCapability VulkanMemoryModel\n" - "OpExtension \"SPV_KHR_vulkan_memory_model\"\n" - "OpMemoryModel Logical Vulkan\n" - "OpEntryPoint Vertex %1000 \"shader\"\n" - "%10 = OpTypeVoid\n" - "%100 = OpTypeFunction %10\n" - "%1000 = OpFunction %10 None %100\n" - "%10000 = OpLabel\n" - "OpReturn\n" - "OpFunctionEnd\n", - // expected - "OpCapability Shader\n" - "OpCapability VulkanMemoryModel\n" - "OpExtension \"SPV_KHR_vulkan_memory_model\"\n" - "OpMemoryModel Logical Vulkan\n" - "OpEntryPoint Vertex %1 \"shader\"\n" - "%void = OpTypeVoid\n" - "%3 = OpTypeFunction %void\n" - "%1 = OpFunction %void None %3\n" - "%4 = OpLabel\n" - "OpReturn\n" - "OpFunctionEnd\n", - // pass - "compact-ids"}})); TEST(Optimizer, RemoveNop) { // Test that OpNops are removed even if no optimizations are run. @@ -754,7 +262,7 @@ OpFunctionEnd << before << "\n"; std::string disassembly; { - SpirvTools tools(SPV_ENV_WEBGPU_0); + SpirvTools tools(SPV_ENV_VULKAN_1_1); tools.Disassemble(optimized.data(), optimized.size(), &disassembly); } diff --git a/test/opt/split_invalid_unreachable_test.cpp b/test/opt/split_invalid_unreachable_test.cpp deleted file mode 100644 index 520af0154b..0000000000 --- a/test/opt/split_invalid_unreachable_test.cpp +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright (c) 2019 Google LLC. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include - -#include "test/opt/pass_fixture.h" -#include "test/opt/pass_utils.h" - -namespace spvtools { -namespace opt { -namespace { - -using SplitInvalidUnreachableTest = PassTest<::testing::Test>; - -std::string spirv_header = R"(OpCapability Shader -OpCapability VulkanMemoryModel -OpExtension "SPV_KHR_vulkan_memory_model" -OpMemoryModel Logical Vulkan -OpEntryPoint Vertex %1 "shader" -%uint = OpTypeInt 32 0 -%uint_1 = OpConstant %uint 1 -%uint_2 = OpConstant %uint 2 -%void = OpTypeVoid -%bool = OpTypeBool -%7 = OpTypeFunction %void -)"; - -std::string function_head = R"(%1 = OpFunction %void None %7 -%8 = OpLabel -OpBranch %9 -)"; - -std::string function_tail = "OpFunctionEnd\n"; - -std::string GetLoopMergeBlock(std::string block_id, std::string merge_id, - std::string continue_id, std::string body_id) { - std::string result; - result += block_id + " = OpLabel\n"; - result += "OpLoopMerge " + merge_id + " " + continue_id + " None\n"; - result += "OpBranch " + body_id + "\n"; - return result; -} - -std::string GetSelectionMergeBlock(std::string block_id, - std::string condition_id, - std::string merge_id, std::string true_id, - std::string false_id) { - std::string result; - result += block_id + " = OpLabel\n"; - result += condition_id + " = OpSLessThan %bool %uint_1 %uint_2\n"; - result += "OpSelectionMerge " + merge_id + " None\n"; - result += "OpBranchConditional " + condition_id + " " + true_id + " " + - false_id + "\n"; - - return result; -} - -std::string GetReturnBlock(std::string block_id) { - std::string result; - result += block_id + " = OpLabel\n"; - result += "OpReturn\n"; - return result; -} - -std::string GetUnreachableBlock(std::string block_id) { - std::string result; - result += block_id + " = OpLabel\n"; - result += "OpUnreachable\n"; - return result; -} - -std::string GetBranchBlock(std::string block_id, std::string target_id) { - std::string result; - result += block_id + " = OpLabel\n"; - result += "OpBranch " + target_id + "\n"; - return result; -} - -TEST_F(SplitInvalidUnreachableTest, NoInvalidBlocks) { - std::string input = spirv_header + function_head; - input += GetLoopMergeBlock("%9", "%10", "%11", "%12"); - input += GetSelectionMergeBlock("%12", "%13", "%14", "%15", "%16"); - input += GetReturnBlock("%15"); - input += GetReturnBlock("%16"); - input += GetUnreachableBlock("%10"); - input += GetBranchBlock("%11", "%9"); - input += GetUnreachableBlock("%14"); - input += function_tail; - - SinglePassRunAndCheck(input, input, - /* skip_nop = */ false); -} - -TEST_F(SplitInvalidUnreachableTest, SelectionInLoop) { - std::string input = spirv_header + function_head; - input += GetLoopMergeBlock("%9", "%10", "%11", "%12"); - input += GetSelectionMergeBlock("%12", "%13", "%11", "%15", "%16"); - input += GetReturnBlock("%15"); - input += GetReturnBlock("%16"); - input += GetUnreachableBlock("%10"); - input += GetBranchBlock("%11", "%9"); - input += function_tail; - - std::string expected = spirv_header + function_head; - expected += GetLoopMergeBlock("%9", "%10", "%11", "%12"); - expected += GetSelectionMergeBlock("%12", "%13", "%16", "%14", "%15"); - expected += GetReturnBlock("%14"); - expected += GetReturnBlock("%15"); - expected += GetUnreachableBlock("%10"); - expected += GetUnreachableBlock("%16"); - expected += GetBranchBlock("%11", "%9"); - expected += function_tail; - - SinglePassRunAndCheck(input, expected, - /* skip_nop = */ false); -} - -TEST_F(SplitInvalidUnreachableTest, LoopInSelection) { - std::string input = spirv_header + function_head; - input += GetSelectionMergeBlock("%9", "%10", "%11", "%12", "%13"); - input += GetLoopMergeBlock("%12", "%14", "%11", "%15"); - input += GetReturnBlock("%13"); - input += GetUnreachableBlock("%14"); - input += GetBranchBlock("%11", "%12"); - input += GetReturnBlock("%15"); - input += function_tail; - - std::string expected = spirv_header + function_head; - expected += GetSelectionMergeBlock("%9", "%10", "%16", "%12", "%13"); - expected += GetLoopMergeBlock("%12", "%14", "%11", "%15"); - expected += GetReturnBlock("%13"); - expected += GetUnreachableBlock("%14"); - expected += GetUnreachableBlock("%16"); - expected += GetBranchBlock("%11", "%12"); - expected += GetReturnBlock("%15"); - expected += function_tail; - - SinglePassRunAndCheck(input, expected, - /* skip_nop = */ false); -} - -} // namespace -} // namespace opt -} // namespace spvtools diff --git a/test/opt/strip_atomic_counter_memory_test.cpp b/test/opt/strip_atomic_counter_memory_test.cpp deleted file mode 100644 index 90daa59c1d..0000000000 --- a/test/opt/strip_atomic_counter_memory_test.cpp +++ /dev/null @@ -1,406 +0,0 @@ -// Copyright (c) 2019 Google LLC. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include - -#include "test/opt/pass_fixture.h" -#include "test/opt/pass_utils.h" - -namespace spvtools { -namespace opt { -namespace { - -typedef std::tuple StripAtomicCounterMemoryParam; - -using MemorySemanticsModified = - PassTest<::testing::TestWithParam>; -using NonMemorySemanticsUnmodifiedTest = PassTest<::testing::Test>; - -void operator+=(std::vector& lhs, const char* rhs) { - lhs.push_back(rhs); -} - -std::string GetConstDecl(std::string val) { - std::string decl; - decl += "%uint_" + val + " = OpConstant %uint " + val; - return decl; -} - -std::string GetUnchangedString(std::string(generate_inst)(std::string), - std::string val) { - std::string decl = GetConstDecl(val); - std::string inst = generate_inst(val); - - std::vector result = { - // clang-format off - "OpCapability Shader", - "OpCapability VulkanMemoryModel", - "OpExtension \"SPV_KHR_vulkan_memory_model\"", - "OpMemoryModel Logical Vulkan", - "OpEntryPoint Vertex %1 \"shader\"", - "%uint = OpTypeInt 32 0", -"%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint", - "%4 = OpVariable %_ptr_Workgroup_uint Workgroup", - "%uint_0 = OpConstant %uint 0", - "%uint_1 = OpConstant %uint 1", - "%void = OpTypeVoid", - "%8 = OpTypeFunction %void", - decl.c_str(), - "%1 = OpFunction %void None %8", - "%10 = OpLabel", - inst.c_str(), - "OpReturn", - "OpFunctionEnd" - // clang-format on - }; - return JoinAllInsts(result); -} - -std::string GetChangedString(std::string(generate_inst)(std::string), - std::string orig, std::string changed) { - std::string orig_decl = GetConstDecl(orig); - std::string changed_decl = GetConstDecl(changed); - std::string inst = generate_inst(changed); - - std::vector result = { - // clang-format off - "OpCapability Shader", - "OpCapability VulkanMemoryModel", - "OpExtension \"SPV_KHR_vulkan_memory_model\"", - "OpMemoryModel Logical Vulkan", - "OpEntryPoint Vertex %1 \"shader\"", - "%uint = OpTypeInt 32 0", -"%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint", - "%4 = OpVariable %_ptr_Workgroup_uint Workgroup", - "%uint_0 = OpConstant %uint 0", - "%uint_1 = OpConstant %uint 1", - "%void = OpTypeVoid", - "%8 = OpTypeFunction %void", - orig_decl.c_str() }; - // clang-format on - if (changed != "0") result += changed_decl.c_str(); - result += "%1 = OpFunction %void None %8"; - result += "%10 = OpLabel"; - result += inst.c_str(); - result += "OpReturn"; - result += "OpFunctionEnd"; - return JoinAllInsts(result); -} - -std::tuple GetInputAndExpected( - std::string(generate_inst)(std::string), - StripAtomicCounterMemoryParam param) { - std::string orig = std::get<0>(param); - std::string changed = std::get<1>(param); - std::string input = GetUnchangedString(generate_inst, orig); - std::string expected = orig == changed - ? GetUnchangedString(generate_inst, changed) - : GetChangedString(generate_inst, orig, changed); - return std::make_tuple(input, expected); -} - -std::string GetOpControlBarrierInst(std::string val) { - return "OpControlBarrier %uint_1 %uint_1 %uint_" + val; -} - -TEST_P(MemorySemanticsModified, OpControlBarrier) { - std::string input, expected; - std::tie(input, expected) = - GetInputAndExpected(GetOpControlBarrierInst, GetParam()); - SinglePassRunAndCheck(input, expected, - /* skip_nop = */ false); -} - -std::string GetOpMemoryBarrierInst(std::string val) { - return "OpMemoryBarrier %uint_1 %uint_" + val; -} - -TEST_P(MemorySemanticsModified, OpMemoryBarrier) { - std::string input, expected; - std::tie(input, expected) = - GetInputAndExpected(GetOpMemoryBarrierInst, GetParam()); - SinglePassRunAndCheck(input, expected, - /* skip_nop = */ false); -} - -std::string GetOpAtomicLoadInst(std::string val) { - return "%11 = OpAtomicLoad %uint %4 %uint_1 %uint_" + val; -} - -TEST_P(MemorySemanticsModified, OpAtomicLoad) { - std::string input, expected; - std::tie(input, expected) = - GetInputAndExpected(GetOpAtomicLoadInst, GetParam()); - SinglePassRunAndCheck(input, expected, - /* skip_nop = */ false); -} - -std::string GetOpAtomicStoreInst(std::string val) { - return "OpAtomicStore %4 %uint_1 %uint_" + val + " %uint_1"; -} - -TEST_P(MemorySemanticsModified, OpAtomicStore) { - std::string input, expected; - std::tie(input, expected) = - GetInputAndExpected(GetOpAtomicStoreInst, GetParam()); - SinglePassRunAndCheck(input, expected, - /* skip_nop = */ false); -} - -std::string GetOpAtomicExchangeInst(std::string val) { - return "%11 = OpAtomicExchange %uint %4 %uint_1 %uint_" + val + " %uint_0"; -} - -TEST_P(MemorySemanticsModified, OpAtomicExchange) { - std::string input, expected; - std::tie(input, expected) = - GetInputAndExpected(GetOpAtomicExchangeInst, GetParam()); - SinglePassRunAndCheck(input, expected, - /* skip_nop = */ false); -} - -std::string GetOpAtomicCompareExchangeInst(std::string val) { - return "%11 = OpAtomicCompareExchange %uint %4 %uint_1 %uint_" + val + - " %uint_" + val + " %uint_0 %uint_0"; -} - -TEST_P(MemorySemanticsModified, OpAtomicCompareExchange) { - std::string input, expected; - std::tie(input, expected) = - GetInputAndExpected(GetOpAtomicCompareExchangeInst, GetParam()); - SinglePassRunAndCheck(input, expected, - /* skip_nop = */ false); -} - -std::string GetOpAtomicCompareExchangeWeakInst(std::string val) { - return "%11 = OpAtomicCompareExchangeWeak %uint %4 %uint_1 %uint_" + val + - " %uint_" + val + " %uint_0 %uint_0"; -} - -TEST_P(MemorySemanticsModified, OpAtomicCompareExchangeWeak) { - std::string input, expected; - std::tie(input, expected) = - GetInputAndExpected(GetOpAtomicCompareExchangeWeakInst, GetParam()); - SinglePassRunAndCheck(input, expected, - /* skip_nop = */ false); -} - -std::string GetOpAtomicIIncrementInst(std::string val) { - return "%11 = OpAtomicIIncrement %uint %4 %uint_1 %uint_" + val; -} - -TEST_P(MemorySemanticsModified, OpAtomicIIncrement) { - std::string input, expected; - std::tie(input, expected) = - GetInputAndExpected(GetOpAtomicIIncrementInst, GetParam()); - SinglePassRunAndCheck(input, expected, - /* skip_nop = */ false); -} - -std::string GetOpAtomicIDecrementInst(std::string val) { - return "%11 = OpAtomicIDecrement %uint %4 %uint_1 %uint_" + val; -} - -TEST_P(MemorySemanticsModified, OpAtomicIDecrement) { - std::string input, expected; - std::tie(input, expected) = - GetInputAndExpected(GetOpAtomicIDecrementInst, GetParam()); - SinglePassRunAndCheck(input, expected, - /* skip_nop = */ false); -} - -std::string GetOpAtomicIAddInst(std::string val) { - return "%11 = OpAtomicIAdd %uint %4 %uint_1 %uint_" + val + " %uint_1"; -} - -TEST_P(MemorySemanticsModified, OpAtomicIAdd) { - std::string input, expected; - std::tie(input, expected) = - GetInputAndExpected(GetOpAtomicIAddInst, GetParam()); - SinglePassRunAndCheck(input, expected, - /* skip_nop = */ false); -} - -std::string GetOpAtomicISubInst(std::string val) { - return "%11 = OpAtomicISub %uint %4 %uint_1 %uint_" + val + " %uint_1"; -} - -TEST_P(MemorySemanticsModified, OpAtomicISub) { - std::string input, expected; - std::tie(input, expected) = - GetInputAndExpected(GetOpAtomicISubInst, GetParam()); - SinglePassRunAndCheck(input, expected, - /* skip_nop = */ false); -} - -std::string GetOpAtomicSMinInst(std::string val) { - return "%11 = OpAtomicSMin %uint %4 %uint_1 %uint_" + val + " %uint_1"; -} - -TEST_P(MemorySemanticsModified, OpAtomicSMin) { - std::string input, expected; - std::tie(input, expected) = - GetInputAndExpected(GetOpAtomicSMinInst, GetParam()); - SinglePassRunAndCheck(input, expected, - /* skip_nop = */ false); -} - -std::string GetOpAtomicUMinInst(std::string val) { - return "%11 = OpAtomicUMin %uint %4 %uint_1 %uint_" + val + " %uint_1"; -} - -TEST_P(MemorySemanticsModified, OpAtomicUMin) { - std::string input, expected; - std::tie(input, expected) = - GetInputAndExpected(GetOpAtomicUMinInst, GetParam()); - SinglePassRunAndCheck(input, expected, - /* skip_nop = */ false); -} - -std::string GetOpAtomicSMaxInst(std::string val) { - return "%11 = OpAtomicSMax %uint %4 %uint_1 %uint_" + val + " %uint_1"; -} - -TEST_P(MemorySemanticsModified, OpAtomicSMax) { - std::string input, expected; - std::tie(input, expected) = - GetInputAndExpected(GetOpAtomicSMaxInst, GetParam()); - SinglePassRunAndCheck(input, expected, - /* skip_nop = */ false); -} - -std::string GetOpAtomicUMaxInst(std::string val) { - return "%11 = OpAtomicUMax %uint %4 %uint_1 %uint_" + val + " %uint_1"; -} - -TEST_P(MemorySemanticsModified, OpAtomicUMax) { - std::string input, expected; - std::tie(input, expected) = - GetInputAndExpected(GetOpAtomicUMaxInst, GetParam()); - SinglePassRunAndCheck(input, expected, - /* skip_nop = */ false); -} - -std::string GetOpAtomicAndInst(std::string val) { - return "%11 = OpAtomicAnd %uint %4 %uint_1 %uint_" + val + " %uint_1"; -} - -TEST_P(MemorySemanticsModified, OpAtomicAnd) { - std::string input, expected; - std::tie(input, expected) = - GetInputAndExpected(GetOpAtomicAndInst, GetParam()); - SinglePassRunAndCheck(input, expected, - /* skip_nop = */ false); -} - -std::string GetOpAtomicOrInst(std::string val) { - return "%11 = OpAtomicOr %uint %4 %uint_1 %uint_" + val + " %uint_1"; -} - -TEST_P(MemorySemanticsModified, OpAtomicOr) { - std::string input, expected; - std::tie(input, expected) = - GetInputAndExpected(GetOpAtomicOrInst, GetParam()); - SinglePassRunAndCheck(input, expected, - /* skip_nop = */ false); -} - -std::string GetOpAtomicXorInst(std::string val) { - return "%11 = OpAtomicXor %uint %4 %uint_1 %uint_" + val + " %uint_1"; -} - -TEST_P(MemorySemanticsModified, OpAtomicXor) { - std::string input, expected; - std::tie(input, expected) = - GetInputAndExpected(GetOpAtomicXorInst, GetParam()); - SinglePassRunAndCheck(input, expected, - /* skip_nop = */ false); -} - -std::string GetOpAtomicFlagTestAndSetInst(std::string val) { - return "%11 = OpAtomicFlagTestAndSet %uint %4 %uint_1 %uint_" + val; -} - -TEST_P(MemorySemanticsModified, OpAtomicFlagTestAndSet) { - std::string input, expected; - std::tie(input, expected) = - GetInputAndExpected(GetOpAtomicFlagTestAndSetInst, GetParam()); - SinglePassRunAndCheck(input, expected, - /* skip_nop = */ false); -} - -std::string GetOpAtomicFlagClearInst(std::string val) { - return "OpAtomicFlagClear %4 %uint_1 %uint_" + val; -} - -TEST_P(MemorySemanticsModified, OpAtomicFlagClear) { - std::string input, expected; - std::tie(input, expected) = - GetInputAndExpected(GetOpAtomicFlagClearInst, GetParam()); - SinglePassRunAndCheck(input, expected, - /* skip_nop = */ false); -} - -std::string GetOpMemoryNamedBarrierInst(std::string val) { - return "OpMemoryNamedBarrier %4 %uint_1 %uint_" + val; -} - -TEST_P(MemorySemanticsModified, OpMemoryNamedBarrier) { - std::string input, expected; - std::tie(input, expected) = - GetInputAndExpected(GetOpMemoryNamedBarrierInst, GetParam()); - SinglePassRunAndCheck(input, expected, - /* skip_nop = */ false); -} - -// clang-format off -INSTANTIATE_TEST_SUITE_P( - StripAtomicCounterMemoryTest, MemorySemanticsModified, - ::testing::ValuesIn(std::vector({ - std::make_tuple("1024", "0"), - std::make_tuple("5", "5"), - std::make_tuple("1288", "264"), - std::make_tuple("264", "264") - }))); -// clang-format on - -std::string GetNoMemorySemanticsPresentInst(std::string val) { - return "%11 = OpVariable %_ptr_Workgroup_uint Workgroup %uint_" + val; -} - -TEST_F(NonMemorySemanticsUnmodifiedTest, NoMemorySemanticsPresent) { - std::string input, expected; - StripAtomicCounterMemoryParam param = std::make_tuple("1288", "1288"); - std::tie(input, expected) = - GetInputAndExpected(GetNoMemorySemanticsPresentInst, param); - SinglePassRunAndCheck(input, expected, - /* skip_nop = */ false); -} - -std::string GetMemorySemanticsPresentInst(std::string val) { - return "%11 = OpAtomicIAdd %uint %4 %uint_1 %uint_" + val + " %uint_1288"; -} - -TEST_F(NonMemorySemanticsUnmodifiedTest, MemorySemanticsPresent) { - std::string input, expected; - StripAtomicCounterMemoryParam param = std::make_tuple("1288", "264"); - std::tie(input, expected) = - GetInputAndExpected(GetMemorySemanticsPresentInst, param); - SinglePassRunAndCheck(input, expected, - /* skip_nop = */ false); -} - -} // namespace -} // namespace opt -} // namespace spvtools diff --git a/test/target_env_test.cpp b/test/target_env_test.cpp index 9c86e2da6c..4acb8ff295 100644 --- a/test/target_env_test.cpp +++ b/test/target_env_test.cpp @@ -95,7 +95,6 @@ INSTANTIATE_TEST_SUITE_P( {"opencl2.0embedded", true, SPV_ENV_OPENCL_EMBEDDED_2_0}, {"opencl2.1embedded", true, SPV_ENV_OPENCL_EMBEDDED_2_1}, {"opencl2.2embedded", true, SPV_ENV_OPENCL_EMBEDDED_2_2}, - {"webgpu0", true, SPV_ENV_WEBGPU_0}, {"opencl2.3", false, SPV_ENV_UNIVERSAL_1_0}, {"opencl3.0", false, SPV_ENV_UNIVERSAL_1_0}, {"vulkan1.9", false, SPV_ENV_UNIVERSAL_1_0}, diff --git a/test/tools/opt/flags.py b/test/tools/opt/flags.py index f8117d9dcc..c79f68073f 100644 --- a/test/tools/opt/flags.py +++ b/test/tools/opt/flags.py @@ -73,10 +73,7 @@ class TestValidPassFlags(expect.ValidObjectFile1_5, '--remove-duplicates', '--replace-invalid-opcode', '--ssa-rewrite', '--scalar-replacement', '--scalar-replacement=42', '--strength-reduction', '--strip-debug', '--strip-reflect', '--vector-dce', '--workaround-1209', - '--unify-const', '--legalize-vector-shuffle', - '--split-invalid-unreachable', '--generate-webgpu-initializers', - '--decompose-initialized-variables', '--graphics-robust-access', - '--wrap-opkill', '--amd-ext-to-khr' + '--unify-const', '--graphics-robust-access', '--wrap-opkill', '--amd-ext-to-khr' ] expected_passes = [ 'wrap-opkill', @@ -124,10 +121,6 @@ class TestValidPassFlags(expect.ValidObjectFile1_5, 'vector-dce', 'workaround-1209', 'unify-const', - 'legalize-vector-shuffle', - 'split-invalid-unreachable', - 'generate-webgpu-initializers', - 'decompose-initialized-variables', 'graphics-robust-access', 'wrap-opkill', 'amd-ext-to-khr' @@ -362,45 +355,3 @@ class TestLoopPeelingThresholdArgsInvalidNumber(expect.ErrorMessageSubstr): spirv_args = ['--loop-peeling-threshold=a10f'] expected_error_substr = 'must have a positive integer argument' - -@inside_spirv_testsuite('SpirvOptFlags') -class TestWebGPUToVulkanThenVulkanToWebGPUIsInvalid(expect.ReturnCodeIsNonZero, expect.ErrorMessageSubstr): - """Tests Vulkan->WebGPU flag cannot be used after WebGPU->Vulkan flag.""" - - spirv_args = ['--webgpu-to-vulkan', '--vulkan-to-webgpu'] - expected_error_substr = 'Cannot use both' - -@inside_spirv_testsuite('SpirvOptFlags') -class TestVulkanToWebGPUThenWebGPUToVulkanIsInvalid(expect.ReturnCodeIsNonZero, expect.ErrorMessageSubstr): - """Tests WebGPU->Vulkan flag cannot be used after Vulkan->WebGPU flag.""" - - spirv_args = ['--vulkan-to-webgpu', '--webgpu-to-vulkan'] - expected_error_substr = 'Cannot use both' - -@inside_spirv_testsuite('SpirvOptFlags') -class TestTargetEnvThenVulkanToWebGPUIsInvalid(expect.ReturnCodeIsNonZero, expect.ErrorMessageSubstr): - """Tests Vulkan->WebGPU flag cannot be used after target env flag.""" - - spirv_args = ['--target-env=opengl4.0', '--vulkan-to-webgpu'] - expected_error_substr = 'defines the target environment' - -@inside_spirv_testsuite('SpirvOptFlags') -class TestVulkanToWebGPUThenTargetEnvIsInvalid(expect.ReturnCodeIsNonZero, expect.ErrorMessageSubstr): - """Tests target env flag cannot be used after Vulkan->WebGPU flag.""" - - spirv_args = ['--vulkan-to-webgpu', '--target-env=opengl4.0'] - expected_error_substr = 'defines the target environment' - -@inside_spirv_testsuite('SpirvOptFlags') -class TestTargetEnvThenWebGPUToVulkanIsInvalid(expect.ReturnCodeIsNonZero, expect.ErrorMessageSubstr): - """Tests WebGPU->Vulkan flag cannot be used after target env flag.""" - - spirv_args = ['--target-env=opengl4.0', '--webgpu-to-vulkan'] - expected_error_substr = 'defines the target environment' - -@inside_spirv_testsuite('SpirvOptFlags') -class TestWebGPUToVulkanThenTargetEnvIsInvalid(expect.ReturnCodeIsNonZero, expect.ErrorMessageSubstr): - """Tests target env flag cannot be used after WebGPU->Vulkan flag.""" - - spirv_args = ['--webgpu-to-vulkan', '--target-env=opengl4.0'] - expected_error_substr = 'defines the target environment' diff --git a/test/unit_spirv.h b/test/unit_spirv.h index 32646620de..f0a2958db6 100644 --- a/test/unit_spirv.h +++ b/test/unit_spirv.h @@ -195,7 +195,7 @@ inline std::vector AllTargetEnvironments() { SPV_ENV_OPENGL_4_1, SPV_ENV_OPENGL_4_2, SPV_ENV_OPENGL_4_3, SPV_ENV_OPENGL_4_5, SPV_ENV_UNIVERSAL_1_2, SPV_ENV_UNIVERSAL_1_3, - SPV_ENV_VULKAN_1_1, SPV_ENV_WEBGPU_0, + SPV_ENV_VULKAN_1_1, }; } diff --git a/test/val/CMakeLists.txt b/test/val/CMakeLists.txt index 153a91670c..b17d1cb160 100644 --- a/test/val/CMakeLists.txt +++ b/test/val/CMakeLists.txt @@ -89,7 +89,6 @@ add_spvtools_unittest(TARGET val_stuvw val_type_unique_test.cpp val_validation_state_test.cpp val_version_test.cpp - val_webgpu_test.cpp ${VAL_TEST_COMMON_SRCS} LIBS ${SPIRV_TOOLS_FULL_VISIBILITY} PCH_FILE pch_test_val diff --git a/test/val/val_atomics_test.cpp b/test/val/val_atomics_test.cpp index aca0f3c90c..6eec91620e 100644 --- a/test/val/val_atomics_test.cpp +++ b/test/val/val_atomics_test.cpp @@ -113,23 +113,6 @@ std::string GenerateShaderCode( memory_model); } -std::string GenerateWebGPUShaderCode( - const std::string& body, - const std::string& capabilities_and_extensions = "") { - const std::string vulkan_memory_capability = R"( -OpCapability VulkanMemoryModelDeviceScopeKHR -OpCapability VulkanMemoryModelKHR -)"; - const std::string vulkan_memory_extension = R"( -OpExtension "SPV_KHR_vulkan_memory_model" -)"; - return GenerateShaderCodeImpl(body, - vulkan_memory_capability + - capabilities_and_extensions + - vulkan_memory_extension, - "", "VulkanKHR"); -} - std::string GenerateKernelCode( const std::string& body, const std::string& capabilities_and_extensions = "") { @@ -501,39 +484,6 @@ TEST_F(ValidateAtomics, AtomicLoadVulkanInt64) { "AtomicLoad: 64-bit atomics require the Int64Atomics capability")); } -TEST_F(ValidateAtomics, AtomicLoadWebGPUSuccess) { - const std::string body = R"( -%val1 = OpAtomicLoad %u32 %u32_var %queuefamily %relaxed -)"; - - CompileSuccessfully(GenerateWebGPUShaderCode(body), SPV_ENV_WEBGPU_0); - ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); -} - -TEST_F(ValidateAtomics, AtomicLoadWebGPUNonQueueFamilyFailure) { - const std::string body = R"( -%val3 = OpAtomicLoad %u32 %u32_var %invocation %relaxed -)"; - - CompileSuccessfully(GenerateWebGPUShaderCode(body), SPV_ENV_WEBGPU_0); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("Memory Scope is limited to QueueFamilyKHR for " - "OpAtomic* operations")); -} - -TEST_F(ValidateAtomics, AtomicLoadWebGPUNonRelaxedFailure) { - const std::string body = R"( -%val1 = OpAtomicLoad %u32 %u32_var %queuefamily %acquire -)"; - - CompileSuccessfully(GenerateWebGPUShaderCode(body), SPV_ENV_WEBGPU_0); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("no bits may be set for Memory Semantics of OpAtomic* " - "instructions")); -} - TEST_F(ValidateAtomics, VK_KHR_shader_atomic_int64Success) { const std::string body = R"( %val1 = OpAtomicUMin %u64 %u64_var %device %relaxed %u64_1 @@ -710,38 +660,6 @@ OpAtomicStore %u32_var %device %sequentially_consistent %u32_1 "Acquire, AcquireRelease and SequentiallyConsistent")); } -TEST_F(ValidateAtomics, AtomicStoreWebGPUSuccess) { - const std::string body = R"( -OpAtomicStore %u32_var %queuefamily %relaxed %u32_1 -)"; - - CompileSuccessfully(GenerateWebGPUShaderCode(body), SPV_ENV_WEBGPU_0); - ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); -} -TEST_F(ValidateAtomics, AtomicStoreWebGPUNonQueueFamilyFailure) { - const std::string body = R"( -OpAtomicStore %u32_var %workgroup %relaxed %u32_1 -)"; - - CompileSuccessfully(GenerateWebGPUShaderCode(body), SPV_ENV_WEBGPU_0); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("Memory Scope is limited to QueueFamilyKHR for " - "OpAtomic* operations")); -} - -TEST_F(ValidateAtomics, AtomicStoreWebGPUNonRelaxedFailure) { - const std::string body = R"( -OpAtomicStore %u32_var %queuefamily %release %u32_1 -)"; - - CompileSuccessfully(GenerateWebGPUShaderCode(body), SPV_ENV_WEBGPU_0); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("no bits may be set for Memory Semantics of OpAtomic* " - "instructions")); -} - TEST_F(ValidateAtomics, AtomicStoreWrongPointerType) { const std::string body = R"( OpAtomicStore %f32_1 %device %relaxed %f32_1 @@ -2032,75 +1950,6 @@ OpExtension "SPV_KHR_vulkan_memory_model" EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); } -TEST_F(ValidateAtomics, WebGPUCrossDeviceMemoryScopeBad) { - const std::string body = R"( -%val1 = OpAtomicLoad %u32 %u32_var %cross_device %relaxed -)"; - - CompileSuccessfully(GenerateWebGPUShaderCode(body), SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("in WebGPU environment Memory Scope is limited to " - "QueueFamilyKHR for OpAtomic* operations")); -} - -TEST_F(ValidateAtomics, WebGPUDeviceMemoryScopeBad) { - const std::string body = R"( -%val1 = OpAtomicLoad %u32 %u32_var %device %relaxed -)"; - - CompileSuccessfully(GenerateWebGPUShaderCode(body), SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("in WebGPU environment Memory Scope is limited to " - "QueueFamilyKHR for OpAtomic* operations")); -} - -TEST_F(ValidateAtomics, WebGPUWorkgroupMemoryScopeBad) { - const std::string body = R"( -%val1 = OpAtomicLoad %u32 %u32_var %workgroup %relaxed -)"; - - CompileSuccessfully(GenerateWebGPUShaderCode(body), SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("in WebGPU environment Memory Scope is limited to " - "QueueFamilyKHR for OpAtomic* operations")); -} - -TEST_F(ValidateAtomics, WebGPUSubgroupMemoryScopeBad) { - const std::string body = R"( -%val1 = OpAtomicLoad %u32 %u32_var %subgroup %relaxed -)"; - - CompileSuccessfully(GenerateWebGPUShaderCode(body), SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("in WebGPU environment Memory Scope is limited to " - "QueueFamilyKHR for OpAtomic* operations")); -} - -TEST_F(ValidateAtomics, WebGPUInvocationMemoryScopeBad) { - const std::string body = R"( -%val1 = OpAtomicLoad %u32 %u32_var %invocation %relaxed -)"; - - CompileSuccessfully(GenerateWebGPUShaderCode(body), SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("in WebGPU environment Memory Scope is limited to " - "QueueFamilyKHR for OpAtomic* operations")); -} - -TEST_F(ValidateAtomics, WebGPUQueueFamilyMemoryScopeGood) { - const std::string body = R"( -%val1 = OpAtomicLoad %u32 %u32_var %queuefamily %relaxed -)"; - - CompileSuccessfully(GenerateWebGPUShaderCode(body), SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); -} - TEST_F(ValidateAtomics, CompareExchangeWeakV13ValV14Good) { const std::string body = R"( %val1 = OpAtomicCompareExchangeWeak %u32 %u32_var %device %relaxed %relaxed %u32_0 %u32_0 diff --git a/test/val/val_barriers_test.cpp b/test/val/val_barriers_test.cpp index d7ddb46b9e..579ec69d0c 100644 --- a/test/val/val_barriers_test.cpp +++ b/test/val/val_barriers_test.cpp @@ -121,42 +121,6 @@ OpCapability Int64 execution_model, memory_model); } -std::string GenerateWebGPUComputeShaderCode( - const std::string& body, - const std::string& capabilities_and_extensions = "", - const std::string& execution_model = "GLCompute") { - const std::string vulkan_memory_capability = R"( -OpCapability VulkanMemoryModelKHR -)"; - const std::string vulkan_memory_extension = R"( -OpExtension "SPV_KHR_vulkan_memory_model" -)"; - const std::string memory_model = "OpMemoryModel Logical VulkanKHR"; - return GenerateShaderCodeImpl(body, - vulkan_memory_capability + - capabilities_and_extensions + - vulkan_memory_extension, - "", execution_model, memory_model); -} - -std::string GenerateWebGPUVertexShaderCode( - const std::string& body, - const std::string& capabilities_and_extensions = "", - const std::string& execution_model = "Vertex") { - const std::string vulkan_memory_capability = R"( -OpCapability VulkanMemoryModelKHR -)"; - const std::string vulkan_memory_extension = R"( -OpExtension "SPV_KHR_vulkan_memory_model" -)"; - const std::string memory_model = "OpMemoryModel Logical VulkanKHR"; - return GenerateShaderCodeImpl(body, - vulkan_memory_capability + - capabilities_and_extensions + - vulkan_memory_extension, - "", execution_model, memory_model); -} - std::string GenerateKernelCode( const std::string& body, const std::string& capabilities_and_extensions = "") { @@ -271,64 +235,6 @@ OpControlBarrier %workgroup %workgroup %acquire_release_uniform_workgroup ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); } -TEST_F(ValidateBarriers, OpControlBarrierWebGPUAcquireReleaseSuccess) { - const std::string body = R"( -OpControlBarrier %workgroup %workgroup %acquire_release_workgroup -)"; - - CompileSuccessfully(GenerateWebGPUComputeShaderCode(body), SPV_ENV_WEBGPU_0); - ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); -} - -TEST_F(ValidateBarriers, OpControlBarrierWebGPURelaxedFailure) { - const std::string body = R"( -OpControlBarrier %workgroup %workgroup %workgroup -)"; - - CompileSuccessfully(GenerateWebGPUComputeShaderCode(body), SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("For WebGPU, AcquireRelease must be set for Memory " - "Semantics of OpControlBarrier")); -} - -TEST_F(ValidateBarriers, OpControlBarrierWebGPUMissingWorkgroupFailure) { - const std::string body = R"( -OpControlBarrier %workgroup %workgroup %acquire_release -)"; - - CompileSuccessfully(GenerateWebGPUComputeShaderCode(body), SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("For WebGPU, WorkgroupMemory must be set for Memory " - "Semantics")); -} - -TEST_F(ValidateBarriers, OpControlBarrierWebGPUUniformFailure) { - const std::string body = R"( -OpControlBarrier %workgroup %workgroup %acquire_release_uniform_workgroup -)"; - - CompileSuccessfully(GenerateWebGPUComputeShaderCode(body), SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("For WebGPU only WorkgroupMemory and AcquireRelease may be set " - "for Memory Semantics of OpControlBarrier.")); -} - -TEST_F(ValidateBarriers, OpControlBarrierWebGPUReleaseFailure) { - const std::string body = R"( -OpControlBarrier %workgroup %workgroup %release_uniform_workgroup -)"; - - CompileSuccessfully(GenerateWebGPUComputeShaderCode(body), SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("For WebGPU, AcquireRelease must be set for Memory " - "Semantics of OpControlBarrier")); -} - TEST_F(ValidateBarriers, OpControlBarrierExecutionModelFragmentSpirv12) { const std::string body = R"( OpControlBarrier %device %device %none @@ -435,44 +341,6 @@ OpControlBarrier %device %workgroup %none "is limited to Workgroup and Subgroup")); } -TEST_F(ValidateBarriers, OpControlBarrierWebGPUExecutionScopeDeviceBad) { - const std::string body = R"( -OpControlBarrier %device %workgroup %none -)"; - - CompileSuccessfully(GenerateWebGPUComputeShaderCode(body), SPV_ENV_WEBGPU_0); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("ControlBarrier: in WebGPU environment Execution Scope " - "is limited to Workgroup")); -} - -TEST_F(ValidateBarriers, OpControlBarrierWebGPUExecutionScopeSubgroupBad) { - const std::string body = R"( -OpControlBarrier %subgroup %workgroup %none -)"; - - CompileSuccessfully(GenerateWebGPUComputeShaderCode(body), SPV_ENV_WEBGPU_0); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("ControlBarrier: in WebGPU environment Execution Scope " - "is limited to Workgroup")); -} - -TEST_F(ValidateBarriers, - OpControlBarrierWebGPUExecutionScopeWorkgroupNonComputeBad) { - const std::string body = R"( -OpControlBarrier %workgroup %workgroup %acquire_release_workgroup -)"; - - CompileSuccessfully(GenerateWebGPUVertexShaderCode(body), SPV_ENV_WEBGPU_0); - ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr( - "Workgroup Execution Scope is limited to GLCompute execution model")); -} - TEST_F(ValidateBarriers, OpControlBarrierVulkanMemoryScopeSubgroup) { const std::string body = R"( OpControlBarrier %subgroup %subgroup %none @@ -507,18 +375,6 @@ OpControlBarrier %subgroup %cross_device %none "cannot be CrossDevice")); } -TEST_F(ValidateBarriers, OpControlBarrierWebGPUMemoryScopeNonWorkgroup) { - const std::string body = R"( -OpControlBarrier %workgroup %subgroup %acquire_release_workgroup -)"; - - CompileSuccessfully(GenerateWebGPUComputeShaderCode(body), SPV_ENV_WEBGPU_0); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("ControlBarrier: in WebGPU environment Memory Scope is " - "limited to Workgroup for OpControlBarrier")); -} - TEST_F(ValidateBarriers, OpControlBarrierAcquireAndRelease) { const std::string body = R"( OpControlBarrier %device %device %acquire_and_release_uniform @@ -738,100 +594,6 @@ OpMemoryBarrier %workgroup %acquire_release_uniform_workgroup ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); } -TEST_F(ValidateBarriers, OpMemoryBarrierWebGPUImageMemorySuccess) { - const std::string body = R"( -OpMemoryBarrier %workgroup %image_memory -)"; - - CompileSuccessfully(GenerateWebGPUComputeShaderCode(body), SPV_ENV_WEBGPU_0); - ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); -} - -TEST_F(ValidateBarriers, OpMemoryBarrierWebGPUDeviceFailure) { - const std::string body = R"( -OpMemoryBarrier %subgroup %image_memory -)"; - - CompileSuccessfully(GenerateWebGPUComputeShaderCode(body), SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("in WebGPU environment Memory Scope is limited to " - "Workgroup for OpMemoryBarrier")); -} - -TEST_F(ValidateBarriers, OpMemoryBarrierWebGPUAcquireReleaseFailure) { - const std::string body = R"( -OpMemoryBarrier %workgroup %acquire_release_uniform_workgroup -)"; - - CompileSuccessfully(GenerateWebGPUComputeShaderCode(body), SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("ImageMemory must be set for Memory Semantics of " - "OpMemoryBarrier")); -} - -TEST_F(ValidateBarriers, OpMemoryBarrierWebGPURelaxedFailure) { - const std::string body = R"( -OpMemoryBarrier %workgroup %uniform_workgroup -)"; - - CompileSuccessfully(GenerateWebGPUComputeShaderCode(body), SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("ImageMemory must be set for Memory Semantics of " - "OpMemoryBarrier")); -} - -TEST_F(ValidateBarriers, OpMemoryBarrierWebGPUAcquireFailure) { - const std::string body = R"( -OpMemoryBarrier %workgroup %acquire_uniform_workgroup -)"; - - CompileSuccessfully(GenerateWebGPUComputeShaderCode(body), SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("ImageMemory must be set for Memory Semantics of " - "OpMemoryBarrier")); -} - -TEST_F(ValidateBarriers, OpMemoryBarrierWebGPUReleaseFailure) { - const std::string body = R"( -OpMemoryBarrier %workgroup %release_uniform_workgroup -)"; - - CompileSuccessfully(GenerateWebGPUComputeShaderCode(body), SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("ImageMemory must be set for Memory Semantics of " - "OpMemoryBarrier")); -} - -TEST_F(ValidateBarriers, OpMemoryBarrierWebGPUUniformFailure) { - const std::string body = R"( -OpMemoryBarrier %workgroup %uniform_image_memory -)"; - - CompileSuccessfully(GenerateWebGPUComputeShaderCode(body), SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("only ImageMemory may be set for Memory Semantics of " - "OpMemoryBarrier")); -} - -TEST_F(ValidateBarriers, OpMemoryBarrierWebGPUWorkgroupNonComputeFailure) { - const std::string body = R"( -OpMemoryBarrier %workgroup %image_memory -)"; - - CompileSuccessfully(GenerateWebGPUVertexShaderCode(body), SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr( - "Workgroup Memory Scope is limited to GLCompute execution model")); -} - TEST_F(ValidateBarriers, OpMemoryBarrierFloatMemoryScope) { const std::string body = R"( OpMemoryBarrier %f32_1 %acquire_release_uniform_workgroup diff --git a/test/val/val_builtins_test.cpp b/test/val/val_builtins_test.cpp index 7d12aaca38..66e73be6fd 100644 --- a/test/val/val_builtins_test.cpp +++ b/test/val/val_builtins_test.cpp @@ -60,13 +60,8 @@ using ValidateVulkanSubgroupBuiltIns = using ValidateVulkanCombineBuiltInExecutionModelDataTypeResult = spvtest::ValidateBase>; -using ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult = - spvtest::ValidateBase>; using ValidateVulkanCombineBuiltInArrayedVariable = spvtest::ValidateBase< std::tuple>; -using ValidateWebGPUCombineBuiltInArrayedVariable = spvtest::ValidateBase< - std::tuple>; using ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult = spvtest::ValidateBase< std::tuple>; -bool InitializerRequired(spv_target_env env, const char* const storage_class) { - return spvIsWebGPUEnv(env) && (strncmp(storage_class, "Output", 6) == 0 || - strncmp(storage_class, "Private", 7) == 0 || - strncmp(storage_class, "Function", 8) == 0); +bool InitializerRequired(const char* const storage_class) { + return (strncmp(storage_class, "Output", 6) == 0 || + strncmp(storage_class, "Private", 7) == 0 || + strncmp(storage_class, "Function", 8) == 0); } -CodeGenerator GetInMainCodeGenerator(spv_target_env env, - const char* const built_in, +CodeGenerator GetInMainCodeGenerator(const char* const built_in, const char* const execution_model, const char* const storage_class, const char* const capabilities, const char* const extensions, const char* const data_type) { - CodeGenerator generator = - spvIsWebGPUEnv(env) ? CodeGenerator::GetWebGPUShaderCodeGenerator() - : CodeGenerator::GetDefaultShaderCodeGenerator(); + CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator(); if (capabilities) { generator.capabilities_ += capabilities; @@ -108,13 +100,13 @@ CodeGenerator GetInMainCodeGenerator(spv_target_env env, std::ostringstream after_types; after_types << "%built_in_type = OpTypeStruct " << data_type << "\n"; - if (InitializerRequired(env, storage_class)) { + if (InitializerRequired(storage_class)) { after_types << "%built_in_null = OpConstantNull %built_in_type\n"; } after_types << "%built_in_ptr = OpTypePointer " << storage_class << " %built_in_type\n"; after_types << "%built_in_var = OpVariable %built_in_ptr " << storage_class; - if (InitializerRequired(env, storage_class)) { + if (InitializerRequired(storage_class)) { after_types << " %built_in_null"; } after_types << "\n"; @@ -167,9 +159,8 @@ TEST_P(ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, InMain) { const char* const vuid = std::get<4>(GetParam()); const TestResult& test_result = std::get<5>(GetParam()); - CodeGenerator generator = - GetInMainCodeGenerator(SPV_ENV_VULKAN_1_0, built_in, execution_model, - storage_class, NULL, NULL, data_type); + CodeGenerator generator = GetInMainCodeGenerator( + built_in, execution_model, storage_class, NULL, NULL, data_type); CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0); ASSERT_EQ(test_result.validation_result, @@ -185,28 +176,6 @@ TEST_P(ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, InMain) { } } -TEST_P(ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, InMain) { - const char* const built_in = std::get<0>(GetParam()); - const char* const execution_model = std::get<1>(GetParam()); - const char* const storage_class = std::get<2>(GetParam()); - const char* const data_type = std::get<3>(GetParam()); - const TestResult& test_result = std::get<4>(GetParam()); - - CodeGenerator generator = - GetInMainCodeGenerator(SPV_ENV_WEBGPU_0, built_in, execution_model, - storage_class, NULL, NULL, data_type); - - CompileSuccessfully(generator.Build(), SPV_ENV_WEBGPU_0); - ASSERT_EQ(test_result.validation_result, - ValidateInstructions(SPV_ENV_WEBGPU_0)); - if (test_result.error_str) { - EXPECT_THAT(getDiagnosticString(), HasSubstr(test_result.error_str)); - } - if (test_result.error_str2) { - EXPECT_THAT(getDiagnosticString(), HasSubstr(test_result.error_str2)); - } -} - TEST_P( ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult, InMain) { @@ -219,9 +188,9 @@ TEST_P( const char* const vuid = std::get<6>(GetParam()); const TestResult& test_result = std::get<7>(GetParam()); - CodeGenerator generator = GetInMainCodeGenerator( - SPV_ENV_VULKAN_1_0, built_in, execution_model, storage_class, - capabilities, extensions, data_type); + CodeGenerator generator = + GetInMainCodeGenerator(built_in, execution_model, storage_class, + capabilities, extensions, data_type); CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0); ASSERT_EQ(test_result.validation_result, @@ -251,7 +220,7 @@ TEST_P( const TestResult& test_result = std::get<8>(GetParam()); CodeGenerator generator = - GetInMainCodeGenerator(env, built_in, execution_model, storage_class, + GetInMainCodeGenerator(built_in, execution_model, storage_class, capabilities, extensions, data_type); CompileSuccessfully(generator.Build(), env); @@ -267,16 +236,13 @@ TEST_P( } } -CodeGenerator GetInFunctionCodeGenerator(spv_target_env env, - const char* const built_in, +CodeGenerator GetInFunctionCodeGenerator(const char* const built_in, const char* const execution_model, const char* const storage_class, const char* const capabilities, const char* const extensions, const char* const data_type) { - CodeGenerator generator = - spvIsWebGPUEnv(env) ? CodeGenerator::GetWebGPUShaderCodeGenerator() - : CodeGenerator::GetDefaultShaderCodeGenerator(); + CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator(); if (capabilities) { generator.capabilities_ += capabilities; @@ -291,13 +257,13 @@ CodeGenerator GetInFunctionCodeGenerator(spv_target_env env, std::ostringstream after_types; after_types << "%built_in_type = OpTypeStruct " << data_type << "\n"; - if (InitializerRequired(env, storage_class)) { + if (InitializerRequired(storage_class)) { after_types << "%built_in_null = OpConstantNull %built_in_type\n"; } after_types << "%built_in_ptr = OpTypePointer " << storage_class << " %built_in_type\n"; after_types << "%built_in_var = OpVariable %built_in_ptr " << storage_class; - if (InitializerRequired(env, storage_class)) { + if (InitializerRequired(storage_class)) { after_types << " %built_in_null"; } after_types << "\n"; @@ -346,11 +312,7 @@ OpReturn OpFunctionEnd )"; - if (spvIsWebGPUEnv(env)) { - generator.after_types_ += function_body; - } else { - generator.add_at_the_end_ = function_body; - } + generator.add_at_the_end_ = function_body; generator.entry_points_.push_back(std::move(entry_point)); @@ -365,9 +327,8 @@ TEST_P(ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, InFunction) { const char* const vuid = std::get<4>(GetParam()); const TestResult& test_result = std::get<5>(GetParam()); - CodeGenerator generator = - GetInFunctionCodeGenerator(SPV_ENV_VULKAN_1_0, built_in, execution_model, - storage_class, NULL, NULL, data_type); + CodeGenerator generator = GetInFunctionCodeGenerator( + built_in, execution_model, storage_class, NULL, NULL, data_type); CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0); ASSERT_EQ(test_result.validation_result, @@ -383,28 +344,6 @@ TEST_P(ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, InFunction) { } } -TEST_P(ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, InFunction) { - const char* const built_in = std::get<0>(GetParam()); - const char* const execution_model = std::get<1>(GetParam()); - const char* const storage_class = std::get<2>(GetParam()); - const char* const data_type = std::get<3>(GetParam()); - const TestResult& test_result = std::get<4>(GetParam()); - - CodeGenerator generator = - GetInFunctionCodeGenerator(SPV_ENV_WEBGPU_0, built_in, execution_model, - storage_class, NULL, NULL, data_type); - - CompileSuccessfully(generator.Build(), SPV_ENV_WEBGPU_0); - ASSERT_EQ(test_result.validation_result, - ValidateInstructions(SPV_ENV_WEBGPU_0)); - if (test_result.error_str) { - EXPECT_THAT(getDiagnosticString(), HasSubstr(test_result.error_str)); - } - if (test_result.error_str2) { - EXPECT_THAT(getDiagnosticString(), HasSubstr(test_result.error_str2)); - } -} - TEST_P( ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult, InFunction) { @@ -417,9 +356,9 @@ TEST_P( const char* const vuid = std::get<6>(GetParam()); const TestResult& test_result = std::get<7>(GetParam()); - CodeGenerator generator = GetInFunctionCodeGenerator( - SPV_ENV_VULKAN_1_0, built_in, execution_model, storage_class, - capabilities, extensions, data_type); + CodeGenerator generator = + GetInFunctionCodeGenerator(built_in, execution_model, storage_class, + capabilities, extensions, data_type); CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0); ASSERT_EQ(test_result.validation_result, @@ -435,16 +374,13 @@ TEST_P( } } -CodeGenerator GetVariableCodeGenerator(spv_target_env env, - const char* const built_in, +CodeGenerator GetVariableCodeGenerator(const char* const built_in, const char* const execution_model, const char* const storage_class, const char* const capabilities, const char* const extensions, const char* const data_type) { - CodeGenerator generator = - spvIsWebGPUEnv(env) ? CodeGenerator::GetWebGPUShaderCodeGenerator() - : CodeGenerator::GetDefaultShaderCodeGenerator(); + CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator(); if (capabilities) { generator.capabilities_ += capabilities; @@ -458,13 +394,13 @@ CodeGenerator GetVariableCodeGenerator(spv_target_env env, generator.before_types_ += "\n"; std::ostringstream after_types; - if (InitializerRequired(env, storage_class)) { + if (InitializerRequired(storage_class)) { after_types << "%built_in_null = OpConstantNull " << data_type << "\n"; } after_types << "%built_in_ptr = OpTypePointer " << storage_class << " " << data_type << "\n"; after_types << "%built_in_var = OpVariable %built_in_ptr " << storage_class; - if (InitializerRequired(env, storage_class)) { + if (InitializerRequired(storage_class)) { after_types << " %built_in_null"; } after_types << "\n"; @@ -516,9 +452,8 @@ TEST_P(ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, Variable) { const char* const vuid = std::get<4>(GetParam()); const TestResult& test_result = std::get<5>(GetParam()); - CodeGenerator generator = - GetVariableCodeGenerator(SPV_ENV_VULKAN_1_0, built_in, execution_model, - storage_class, NULL, NULL, data_type); + CodeGenerator generator = GetVariableCodeGenerator( + built_in, execution_model, storage_class, NULL, NULL, data_type); CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0); ASSERT_EQ(test_result.validation_result, @@ -534,28 +469,6 @@ TEST_P(ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, Variable) { } } -TEST_P(ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, Variable) { - const char* const built_in = std::get<0>(GetParam()); - const char* const execution_model = std::get<1>(GetParam()); - const char* const storage_class = std::get<2>(GetParam()); - const char* const data_type = std::get<3>(GetParam()); - const TestResult& test_result = std::get<4>(GetParam()); - - CodeGenerator generator = - GetVariableCodeGenerator(SPV_ENV_WEBGPU_0, built_in, execution_model, - storage_class, NULL, NULL, data_type); - - CompileSuccessfully(generator.Build(), SPV_ENV_WEBGPU_0); - ASSERT_EQ(test_result.validation_result, - ValidateInstructions(SPV_ENV_WEBGPU_0)); - if (test_result.error_str) { - EXPECT_THAT(getDiagnosticString(), HasSubstr(test_result.error_str)); - } - if (test_result.error_str2) { - EXPECT_THAT(getDiagnosticString(), HasSubstr(test_result.error_str2)); - } -} - TEST_P( ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult, Variable) { @@ -568,9 +481,9 @@ TEST_P( const char* const vuid = std::get<6>(GetParam()); const TestResult& test_result = std::get<7>(GetParam()); - CodeGenerator generator = GetVariableCodeGenerator( - SPV_ENV_VULKAN_1_0, built_in, execution_model, storage_class, - capabilities, extensions, data_type); + CodeGenerator generator = + GetVariableCodeGenerator(built_in, execution_model, storage_class, + capabilities, extensions, data_type); CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0); ASSERT_EQ(test_result.validation_result, @@ -706,11 +619,6 @@ INSTANTIATE_TEST_SUITE_P( Combine(Values("FragCoord"), Values("Fragment"), Values("Input"), Values("%f32vec4"), Values(nullptr), Values(TestResult()))); -INSTANTIATE_TEST_SUITE_P( - FragCoordSuccess, ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, - Combine(Values("FragCoord"), Values("Fragment"), Values("Input"), - Values("%f32vec4"), Values(TestResult()))); - INSTANTIATE_TEST_SUITE_P( FragCoordNotFragment, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, @@ -723,15 +631,6 @@ INSTANTIATE_TEST_SUITE_P( Values(TestResult(SPV_ERROR_INVALID_DATA, "to be used only with Fragment execution model")))); -INSTANTIATE_TEST_SUITE_P( - FragCoordNotFragment, - ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, - Combine( - Values("FragCoord"), Values("Vertex", "GLCompute"), Values("Input"), - Values("%f32vec4"), - Values(TestResult(SPV_ERROR_INVALID_DATA, - "to be used only with Fragment execution model")))); - INSTANTIATE_TEST_SUITE_P( FragCoordNotInput, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, Combine(Values("FragCoord"), Values("Fragment"), Values("Output"), @@ -741,15 +640,6 @@ INSTANTIATE_TEST_SUITE_P( "to be only used for variables with Input storage class", "uses storage class Output")))); -INSTANTIATE_TEST_SUITE_P( - FragCoordNotInput, ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, - Combine(Values("FragCoord"), Values("Fragment"), Values("Output"), - Values("%f32vec4"), - Values(TestResult( - SPV_ERROR_INVALID_DATA, - "to be only used for variables with Input storage class", - "uses storage class Output")))); - INSTANTIATE_TEST_SUITE_P( FragCoordNotFloatVector, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, @@ -760,15 +650,6 @@ INSTANTIATE_TEST_SUITE_P( "needs to be a 4-component 32-bit float vector", "is not a float vector")))); -INSTANTIATE_TEST_SUITE_P( - FragCoordNotFloatVector, - ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, - Combine(Values("FragCoord"), Values("Fragment"), Values("Input"), - Values("%f32arr4", "%u32vec4"), - Values(TestResult(SPV_ERROR_INVALID_DATA, - "needs to be a 4-component 32-bit float vector", - "is not a float vector")))); - INSTANTIATE_TEST_SUITE_P( FragCoordNotFloatVec4, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, @@ -778,15 +659,6 @@ INSTANTIATE_TEST_SUITE_P( "needs to be a 4-component 32-bit float vector", "has 3 components")))); -INSTANTIATE_TEST_SUITE_P( - FragCoordNotFloatVec4, - ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, - Combine(Values("FragCoord"), Values("Fragment"), Values("Input"), - Values("%f32vec3"), - Values(TestResult(SPV_ERROR_INVALID_DATA, - "needs to be a 4-component 32-bit float vector", - "has 3 components")))); - INSTANTIATE_TEST_SUITE_P( FragCoordNotF32Vec4, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, @@ -801,11 +673,6 @@ INSTANTIATE_TEST_SUITE_P( Combine(Values("FragDepth"), Values("Fragment"), Values("Output"), Values("%f32"), Values(nullptr), Values(TestResult()))); -INSTANTIATE_TEST_SUITE_P( - FragDepthSuccess, ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, - Combine(Values("FragDepth"), Values("Fragment"), Values("Output"), - Values("%f32"), Values(TestResult()))); - INSTANTIATE_TEST_SUITE_P( FragDepthNotFragment, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, @@ -818,15 +685,6 @@ INSTANTIATE_TEST_SUITE_P( Values(TestResult(SPV_ERROR_INVALID_DATA, "to be used only with Fragment execution model")))); -INSTANTIATE_TEST_SUITE_P( - FragDepthNotFragment, - ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, - Combine( - Values("FragDepth"), Values("Vertex", "GLCompute"), Values("Output"), - Values("%f32"), - Values(TestResult(SPV_ERROR_INVALID_DATA, - "to be used only with Fragment execution model")))); - INSTANTIATE_TEST_SUITE_P( FragDepthNotOutput, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, @@ -837,16 +695,6 @@ INSTANTIATE_TEST_SUITE_P( "to be only used for variables with Output storage class", "uses storage class Input")))); -INSTANTIATE_TEST_SUITE_P( - FragDepthNotOutput, - ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, - Combine(Values("FragDepth"), Values("Fragment"), Values("Input"), - Values("%f32"), - Values(TestResult( - SPV_ERROR_INVALID_DATA, - "to be only used for variables with Output storage class", - "uses storage class Input")))); - INSTANTIATE_TEST_SUITE_P( FragDepthNotFloatScalar, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, @@ -857,15 +705,6 @@ INSTANTIATE_TEST_SUITE_P( "needs to be a 32-bit float scalar", "is not a float scalar")))); -INSTANTIATE_TEST_SUITE_P( - FragDepthNotFloatScalar, - ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, - Combine(Values("FragDepth"), Values("Fragment"), Values("Output"), - Values("%f32vec4", "%u32"), - Values(TestResult(SPV_ERROR_INVALID_DATA, - "needs to be a 32-bit float scalar", - "is not a float scalar")))); - INSTANTIATE_TEST_SUITE_P( FragDepthNotF32, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, Combine(Values("FragDepth"), Values("Fragment"), Values("Output"), @@ -881,12 +720,6 @@ INSTANTIATE_TEST_SUITE_P( Values("Input"), Values("%bool"), Values(nullptr), 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, @@ -900,15 +733,6 @@ INSTANTIATE_TEST_SUITE_P( Values(TestResult(SPV_ERROR_INVALID_DATA, "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, @@ -921,16 +745,6 @@ INSTANTIATE_TEST_SUITE_P( "to be only used for variables with Input storage class", "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, @@ -942,15 +756,6 @@ INSTANTIATE_TEST_SUITE_P( "needs to be a bool scalar", "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, @@ -959,13 +764,6 @@ INSTANTIATE_TEST_SUITE_P( Values("GLCompute"), Values("Input"), Values("%u32vec3"), Values(nullptr), Values(TestResult()))); -INSTANTIATE_TEST_SUITE_P( - ComputeShaderInputInt32Vec3Success, - ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, - Combine(Values("GlobalInvocationId", "LocalInvocationId", "NumWorkgroups"), - Values("GLCompute"), Values("Input"), Values("%u32vec3"), - Values(TestResult()))); - INSTANTIATE_TEST_SUITE_P( ComputeShaderInputInt32Vec3NotGLCompute, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, @@ -982,15 +780,6 @@ INSTANTIATE_TEST_SUITE_P( Values(TestResult(SPV_ERROR_INVALID_DATA, "to be used only with GLCompute execution model")))); -INSTANTIATE_TEST_SUITE_P( - ComputeShaderInputInt32Vec3NotGLCompute, - ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, - Combine( - Values("GlobalInvocationId", "LocalInvocationId", "NumWorkgroups"), - Values("Vertex", "Fragment"), Values("Input"), Values("%u32vec3"), - Values(TestResult(SPV_ERROR_INVALID_DATA, - "to be used only with GLCompute execution model")))); - INSTANTIATE_TEST_SUITE_P( ComputeShaderInputInt32Vec3NotInput, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, @@ -1006,16 +795,6 @@ INSTANTIATE_TEST_SUITE_P( "to be only used for variables with Input storage class", "uses storage class Output")))); -INSTANTIATE_TEST_SUITE_P( - ComputeShaderInputInt32Vec3NotInput, - ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, - Combine(Values("GlobalInvocationId", "LocalInvocationId", "NumWorkgroups"), - Values("GLCompute"), Values("Output"), Values("%u32vec3"), - Values(TestResult( - SPV_ERROR_INVALID_DATA, - "to be only used for variables with Input storage class", - "uses storage class Output")))); - INSTANTIATE_TEST_SUITE_P( ComputeShaderInputInt32Vec3NotIntVector, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, @@ -1031,16 +810,6 @@ INSTANTIATE_TEST_SUITE_P( "needs to be a 3-component 32-bit int vector", "is not an int vector")))); -INSTANTIATE_TEST_SUITE_P( - ComputeShaderInputInt32Vec3NotIntVector, - ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, - Combine(Values("GlobalInvocationId", "LocalInvocationId", "NumWorkgroups"), - Values("GLCompute"), Values("Input"), - Values("%u32arr3", "%f32vec3"), - Values(TestResult(SPV_ERROR_INVALID_DATA, - "needs to be a 3-component 32-bit int vector", - "is not an int vector")))); - INSTANTIATE_TEST_SUITE_P( ComputeShaderInputInt32Vec3NotIntVec3, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, @@ -1055,15 +824,6 @@ INSTANTIATE_TEST_SUITE_P( "needs to be a 3-component 32-bit int vector", "has 4 components")))); -INSTANTIATE_TEST_SUITE_P( - ComputeShaderInputInt32Vec3NotIntVec3, - ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, - Combine(Values("GlobalInvocationId", "LocalInvocationId", "NumWorkgroups"), - Values("GLCompute"), Values("Input"), Values("%u32vec4"), - Values(TestResult(SPV_ERROR_INVALID_DATA, - "needs to be a 3-component 32-bit int vector", - "has 4 components")))); - INSTANTIATE_TEST_SUITE_P( ComputeShaderInputInt32Vec3NotInt32Vec, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, @@ -1133,12 +893,6 @@ INSTANTIATE_TEST_SUITE_P( Combine(Values("InstanceIndex"), Values("Vertex"), Values("Input"), Values("%u32"), Values(nullptr), Values(TestResult()))); -INSTANTIATE_TEST_SUITE_P( - InstanceIndexSuccess, - ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, - Combine(Values("InstanceIndex"), Values("Vertex"), Values("Input"), - Values("%u32"), Values(TestResult()))); - INSTANTIATE_TEST_SUITE_P( InstanceIndexInvalidExecutionModel, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, @@ -1150,14 +904,6 @@ INSTANTIATE_TEST_SUITE_P( Values(TestResult(SPV_ERROR_INVALID_DATA, "to be used only with Vertex execution model")))); -INSTANTIATE_TEST_SUITE_P( - InstanceIndexInvalidExecutionModel, - ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, - Combine(Values("InstanceIndex"), Values("Fragment", "GLCompute"), - Values("Input"), Values("%u32"), - Values(TestResult(SPV_ERROR_INVALID_DATA, - "to be used only with Vertex execution model")))); - INSTANTIATE_TEST_SUITE_P( InstanceIndexNotInput, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, @@ -1168,16 +914,6 @@ INSTANTIATE_TEST_SUITE_P( "to be only used for variables with Input storage class", "uses storage class Output")))); -INSTANTIATE_TEST_SUITE_P( - InstanceIndexNotInput, - ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, - Combine(Values("InstanceIndex"), Values("Vertex"), Values("Output"), - Values("%u32"), - Values(TestResult( - SPV_ERROR_INVALID_DATA, - "to be only used for variables with Input storage class", - "uses storage class Output")))); - INSTANTIATE_TEST_SUITE_P( InstanceIndexNotIntScalar, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, @@ -1188,15 +924,6 @@ INSTANTIATE_TEST_SUITE_P( "needs to be a 32-bit int scalar", "is not an int scalar")))); -INSTANTIATE_TEST_SUITE_P( - InstanceIndexNotIntScalar, - ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, - Combine(Values("InstanceIndex"), Values("Vertex"), Values("Input"), - Values("%f32", "%u32vec3"), - Values(TestResult(SPV_ERROR_INVALID_DATA, - "needs to be a 32-bit int scalar", - "is not an int scalar")))); - INSTANTIATE_TEST_SUITE_P( InstanceIndexNotInt32, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, @@ -1488,21 +1215,6 @@ INSTANTIATE_TEST_SUITE_P( Values("Output"), Values("%f32vec4"), Values(nullptr), Values(TestResult()))); -INSTANTIATE_TEST_SUITE_P( - PositionOutputSuccess, - ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, - Combine(Values("Position"), Values("Vertex"), Values("Output"), - Values("%f32vec4"), Values(TestResult()))); - -INSTANTIATE_TEST_SUITE_P( - PositionOutputFailure, - ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, - Combine(Values("Position"), Values("Fragment", "GLCompute"), - Values("Output"), Values("%f32vec4"), - Values(TestResult(SPV_ERROR_INVALID_DATA, - "WebGPU spec allows BuiltIn Position to be used " - "only with the Vertex execution model.")))); - INSTANTIATE_TEST_SUITE_P( PositionInputSuccess, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, @@ -1511,16 +1223,6 @@ INSTANTIATE_TEST_SUITE_P( Values("Input"), Values("%f32vec4"), Values(nullptr), Values(TestResult()))); -INSTANTIATE_TEST_SUITE_P( - PositionInputFailure, - ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, - Combine( - Values("Position"), Values("Vertex", "Fragment", "GLCompute"), - Values("Input"), Values("%f32vec4"), - Values(TestResult(SPV_ERROR_INVALID_DATA, - "WebGPU spec allows BuiltIn Position to be only used " - "for variables with Output storage class")))); - INSTANTIATE_TEST_SUITE_P( PositionInvalidStorageClass, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, @@ -1566,15 +1268,6 @@ INSTANTIATE_TEST_SUITE_P( "needs to be a 4-component 32-bit float vector", "is not a float vector")))); -INSTANTIATE_TEST_SUITE_P( - PositionNotFloatVector, - ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, - Combine( - Values("Position"), Values("Vertex"), Values("Output"), - Values("%f32arr4", "%u32vec4"), - Values(TestResult(SPV_ERROR_INVALID_DATA, - "needs to be a 4-component 32-bit float vector")))); - INSTANTIATE_TEST_SUITE_P( PositionNotFloatVec4, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, @@ -1584,15 +1277,6 @@ INSTANTIATE_TEST_SUITE_P( "needs to be a 4-component 32-bit float vector", "has 3 components")))); -INSTANTIATE_TEST_SUITE_P( - PositionNotFloatVec4, - ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, - Combine( - Values("Position"), Values("Vertex"), Values("Output"), - Values("%f32vec3"), - Values(TestResult(SPV_ERROR_INVALID_DATA, - "needs to be a 4-component 32-bit float vector")))); - INSTANTIATE_TEST_SUITE_P( PositionNotF32Vec4, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, @@ -2067,12 +1751,6 @@ INSTANTIATE_TEST_SUITE_P( Combine(Values("VertexIndex"), Values("Vertex"), Values("Input"), Values("%u32"), Values(nullptr), Values(TestResult()))); -INSTANTIATE_TEST_SUITE_P( - VertexIndexSuccess, - ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, - Combine(Values("VertexIndex"), Values("Vertex"), Values("Input"), - Values("%u32"), Values(TestResult()))); - INSTANTIATE_TEST_SUITE_P( VertexIndexInvalidExecutionModel, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, @@ -2084,14 +1762,6 @@ INSTANTIATE_TEST_SUITE_P( Values(TestResult(SPV_ERROR_INVALID_DATA, "to be used only with Vertex execution model")))); -INSTANTIATE_TEST_SUITE_P( - VertexIndexInvalidExecutionModel, - ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, - Combine(Values("VertexIndex"), Values("Fragment", "GLCompute"), - Values("Input"), Values("%u32"), - Values(TestResult(SPV_ERROR_INVALID_DATA, - "to be used only with Vertex execution model")))); - INSTANTIATE_TEST_SUITE_P( VertexIndexNotInput, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, @@ -2102,16 +1772,6 @@ INSTANTIATE_TEST_SUITE_P( "Vulkan spec allows BuiltIn VertexIndex to be only " "used for variables with Input storage class")))); -INSTANTIATE_TEST_SUITE_P( - VertexIndexNotInput, - ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, - Combine( - Values("VertexIndex"), Values("Vertex"), Values("Output"), - Values("%u32"), - Values(TestResult(SPV_ERROR_INVALID_DATA, - "WebGPU spec allows BuiltIn VertexIndex to be only " - "used for variables with Input storage class")))); - INSTANTIATE_TEST_SUITE_P( VertexIndexNotIntScalar, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, @@ -2122,15 +1782,6 @@ INSTANTIATE_TEST_SUITE_P( "needs to be a 32-bit int scalar", "is not an int scalar")))); -INSTANTIATE_TEST_SUITE_P( - VertexIndexNotIntScalar, - ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, - Combine(Values("VertexIndex"), Values("Vertex"), Values("Input"), - Values("%f32", "%u32vec3"), - Values(TestResult(SPV_ERROR_INVALID_DATA, - "needs to be a 32-bit int scalar", - "is not an int scalar")))); - INSTANTIATE_TEST_SUITE_P( VertexIndexNotInt32, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, @@ -2140,50 +1791,6 @@ INSTANTIATE_TEST_SUITE_P( "needs to be a 32-bit int scalar", "has bit width 64")))); -INSTANTIATE_TEST_SUITE_P( - LocalInvocationIndexSuccess, - ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, - Combine(Values("LocalInvocationIndex"), Values("GLCompute"), - Values("Input"), Values("%u32"), Values(TestResult()))); - -INSTANTIATE_TEST_SUITE_P( - LocalInvocationIndexInvalidExecutionModel, - ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, - Combine( - Values("LocalInvocationIndex"), Values("Fragment", "Vertex"), - Values("Input"), Values("%u32"), - Values(TestResult(SPV_ERROR_INVALID_DATA, - "to be used only with GLCompute execution model")))); - -INSTANTIATE_TEST_SUITE_P( - LocalInvocationIndexNotInput, - ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, - Combine( - Values("LocalInvocationIndex"), Values("GLCompute"), Values("Output"), - Values("%u32"), - Values(TestResult(SPV_ERROR_INVALID_DATA, - "WebGPU spec allows BuiltIn LocalInvocationIndex to " - "be only used for variables with Input storage " - "class")))); - -INSTANTIATE_TEST_SUITE_P( - LocalInvocationIndexNotIntScalar, - ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, - Combine(Values("LocalInvocationIndex"), Values("GLCompute"), - Values("Input"), Values("%f32", "%u32vec3"), - Values(TestResult(SPV_ERROR_INVALID_DATA, - "needs to be a 32-bit int", "is not an int")))); - -INSTANTIATE_TEST_SUITE_P( - AllowListRejection, - ValidateWebGPUCombineBuiltInExecutionModelDataTypeResult, - Combine(Values("PointSize", "ClipDistance", "CullDistance", "VertexId", - "InstanceId", "PointCoord", "SampleMask", "HelperInvocation", - "WorkgroupId"), - Values("Vertex"), Values("Input"), Values("%u32"), - Values(TestResult(SPV_ERROR_INVALID_DATA, - "WebGPU does not allow BuiltIn")))); - INSTANTIATE_TEST_SUITE_P( BaseInstanceOrVertexSuccess, ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult, @@ -2936,14 +2543,11 @@ INSTANTIATE_TEST_SUITE_P( Values(TestResult(SPV_ERROR_INVALID_DATA, "needs to be a 3-component 32-bit int vector")))); -CodeGenerator GetArrayedVariableCodeGenerator(spv_target_env env, - const char* const built_in, +CodeGenerator GetArrayedVariableCodeGenerator(const char* const built_in, const char* const execution_model, const char* const storage_class, const char* const data_type) { - CodeGenerator generator = - spvIsWebGPUEnv(env) ? CodeGenerator::GetWebGPUShaderCodeGenerator() - : CodeGenerator::GetDefaultShaderCodeGenerator(); + CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator(); generator.before_types_ = "OpDecorate %built_in_var BuiltIn "; generator.before_types_ += built_in; @@ -2951,14 +2555,14 @@ CodeGenerator GetArrayedVariableCodeGenerator(spv_target_env env, std::ostringstream after_types; after_types << "%built_in_array = OpTypeArray " << data_type << " %u32_3\n"; - if (InitializerRequired(env, storage_class)) { + if (InitializerRequired(storage_class)) { after_types << "%built_in_array_null = OpConstantNull %built_in_array\n"; } after_types << "%built_in_ptr = OpTypePointer " << storage_class << " %built_in_array\n"; after_types << "%built_in_var = OpVariable %built_in_ptr " << storage_class; - if (InitializerRequired(env, storage_class)) { + if (InitializerRequired(storage_class)) { after_types << " %built_in_array_null"; } after_types << "\n"; @@ -3007,7 +2611,7 @@ TEST_P(ValidateVulkanCombineBuiltInArrayedVariable, Variable) { const TestResult& test_result = std::get<4>(GetParam()); CodeGenerator generator = GetArrayedVariableCodeGenerator( - SPV_ENV_VULKAN_1_0, built_in, execution_model, storage_class, data_type); + built_in, execution_model, storage_class, data_type); CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0); ASSERT_EQ(test_result.validation_result, @@ -3020,27 +2624,6 @@ TEST_P(ValidateVulkanCombineBuiltInArrayedVariable, Variable) { } } -TEST_P(ValidateWebGPUCombineBuiltInArrayedVariable, Variable) { - const char* const built_in = std::get<0>(GetParam()); - const char* const execution_model = std::get<1>(GetParam()); - const char* const storage_class = std::get<2>(GetParam()); - const char* const data_type = std::get<3>(GetParam()); - const TestResult& test_result = std::get<4>(GetParam()); - - CodeGenerator generator = GetArrayedVariableCodeGenerator( - SPV_ENV_WEBGPU_0, built_in, execution_model, storage_class, data_type); - - CompileSuccessfully(generator.Build(), SPV_ENV_WEBGPU_0); - ASSERT_EQ(test_result.validation_result, - ValidateInstructions(SPV_ENV_WEBGPU_0)); - if (test_result.error_str) { - EXPECT_THAT(getDiagnosticString(), HasSubstr(test_result.error_str)); - } - if (test_result.error_str2) { - EXPECT_THAT(getDiagnosticString(), HasSubstr(test_result.error_str2)); - } -} - INSTANTIATE_TEST_SUITE_P(PointSizeArrayedF32TessControl, ValidateVulkanCombineBuiltInArrayedVariable, Combine(Values("PointSize"), @@ -3086,14 +2669,6 @@ INSTANTIATE_TEST_SUITE_P( "needs to be a 4-component 32-bit float vector", "is not a float vector")))); -INSTANTIATE_TEST_SUITE_P( - PositionArrayedF32Vec4Vertex, ValidateWebGPUCombineBuiltInArrayedVariable, - Combine(Values("Position"), Values("Vertex"), Values("Output"), - Values("%f32vec4"), - Values(TestResult(SPV_ERROR_INVALID_DATA, - "needs to be a 4-component 32-bit float vector", - "is not a float vector")))); - INSTANTIATE_TEST_SUITE_P( ClipAndCullDistanceOutputSuccess, ValidateVulkanCombineBuiltInArrayedVariable, @@ -3197,10 +2772,8 @@ INSTANTIATE_TEST_SUITE_P( "needs to be a 32-bit int scalar", "has bit width 64")))); -CodeGenerator GetWorkgroupSizeSuccessGenerator(spv_target_env env) { - CodeGenerator generator = - env == SPV_ENV_WEBGPU_0 ? CodeGenerator::GetWebGPUShaderCodeGenerator() - : CodeGenerator::GetDefaultShaderCodeGenerator(); +CodeGenerator GetWorkgroupSizeSuccessGenerator() { + CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator(); generator.before_types_ = R"( OpDecorate %workgroup_size BuiltIn WorkgroupSize @@ -3222,22 +2795,13 @@ OpDecorate %workgroup_size BuiltIn WorkgroupSize } TEST_F(ValidateBuiltIns, VulkanWorkgroupSizeSuccess) { - CodeGenerator generator = - GetWorkgroupSizeSuccessGenerator(SPV_ENV_VULKAN_1_0); + CodeGenerator generator = GetWorkgroupSizeSuccessGenerator(); CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); } -TEST_F(ValidateBuiltIns, WebGPUWorkgroupSizeSuccess) { - CodeGenerator generator = GetWorkgroupSizeSuccessGenerator(SPV_ENV_WEBGPU_0); - CompileSuccessfully(generator.Build(), SPV_ENV_WEBGPU_0); - ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); -} - -CodeGenerator GetWorkgroupSizeFragmentGenerator(spv_target_env env) { - CodeGenerator generator = - env == SPV_ENV_WEBGPU_0 ? CodeGenerator::GetWebGPUShaderCodeGenerator() - : CodeGenerator::GetDefaultShaderCodeGenerator(); +CodeGenerator GetWorkgroupSizeFragmentGenerator() { + CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator(); generator.before_types_ = R"( OpDecorate %workgroup_size BuiltIn WorkgroupSize @@ -3260,8 +2824,7 @@ OpDecorate %workgroup_size BuiltIn WorkgroupSize } TEST_F(ValidateBuiltIns, VulkanWorkgroupSizeFragment) { - CodeGenerator generator = - GetWorkgroupSizeFragmentGenerator(SPV_ENV_VULKAN_1_0); + CodeGenerator generator = GetWorkgroupSizeFragmentGenerator(); CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); @@ -3277,20 +2840,6 @@ TEST_F(ValidateBuiltIns, VulkanWorkgroupSizeFragment) { "VUID-WorkgroupSize-WorkgroupSize-04427")); } -TEST_F(ValidateBuiltIns, WebGPUWorkgroupSizeFragment) { - CodeGenerator generator = GetWorkgroupSizeFragmentGenerator(SPV_ENV_WEBGPU_0); - - CompileSuccessfully(generator.Build(), SPV_ENV_WEBGPU_0); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("WebGPU spec allows BuiltIn WorkgroupSize to be used " - "only with GLCompute execution model")); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("is referencing ID <2> (OpConstantComposite) which is " - "decorated with BuiltIn WorkgroupSize in function <1> " - "called with execution model Fragment")); -} - TEST_F(ValidateBuiltIns, WorkgroupSizeNotConstant) { CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator(); generator.before_types_ = R"( @@ -3316,10 +2865,8 @@ OpDecorate %copy BuiltIn WorkgroupSize HasSubstr("BuiltIns can only target variables, structs or constants")); } -CodeGenerator GetWorkgroupSizeNotVectorGenerator(spv_target_env env) { - CodeGenerator generator = - env == SPV_ENV_WEBGPU_0 ? CodeGenerator::GetWebGPUShaderCodeGenerator() - : CodeGenerator::GetDefaultShaderCodeGenerator(); +CodeGenerator GetWorkgroupSizeNotVectorGenerator() { + CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator(); generator.before_types_ = R"( OpDecorate %workgroup_size BuiltIn WorkgroupSize @@ -3341,8 +2888,7 @@ OpDecorate %workgroup_size BuiltIn WorkgroupSize } TEST_F(ValidateBuiltIns, VulkanWorkgroupSizeNotVector) { - CodeGenerator generator = - GetWorkgroupSizeNotVectorGenerator(SPV_ENV_VULKAN_1_0); + CodeGenerator generator = GetWorkgroupSizeNotVectorGenerator(); CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); @@ -3354,22 +2900,8 @@ TEST_F(ValidateBuiltIns, VulkanWorkgroupSizeNotVector) { AnyVUID("VUID-WorkgroupSize-WorkgroupSize-04427")); } -TEST_F(ValidateBuiltIns, WebGPUWorkgroupSizeNotVector) { - CodeGenerator generator = - GetWorkgroupSizeNotVectorGenerator(SPV_ENV_WEBGPU_0); - - CompileSuccessfully(generator.Build(), SPV_ENV_WEBGPU_0); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("According to the WebGPU spec BuiltIn WorkgroupSize " - "variable needs to be a 3-component 32-bit int vector. " - "ID <2> (OpConstant) is not an int vector.")); -} - -CodeGenerator GetWorkgroupSizeNotIntVectorGenerator(spv_target_env env) { - CodeGenerator generator = - env == SPV_ENV_WEBGPU_0 ? CodeGenerator::GetWebGPUShaderCodeGenerator() - : CodeGenerator::GetDefaultShaderCodeGenerator(); +CodeGenerator GetWorkgroupSizeNotIntVectorGenerator() { + CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator(); generator.before_types_ = R"( OpDecorate %workgroup_size BuiltIn WorkgroupSize @@ -3391,8 +2923,7 @@ OpDecorate %workgroup_size BuiltIn WorkgroupSize } TEST_F(ValidateBuiltIns, VulkanWorkgroupSizeNotIntVector) { - CodeGenerator generator = - GetWorkgroupSizeNotIntVectorGenerator(SPV_ENV_VULKAN_1_0); + CodeGenerator generator = GetWorkgroupSizeNotIntVectorGenerator(); CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); @@ -3404,22 +2935,8 @@ TEST_F(ValidateBuiltIns, VulkanWorkgroupSizeNotIntVector) { AnyVUID("VUID-WorkgroupSize-WorkgroupSize-04427")); } -TEST_F(ValidateBuiltIns, WebGPUWorkgroupSizeNotIntVector) { - CodeGenerator generator = - GetWorkgroupSizeNotIntVectorGenerator(SPV_ENV_WEBGPU_0); - - CompileSuccessfully(generator.Build(), SPV_ENV_WEBGPU_0); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("According to the WebGPU spec BuiltIn WorkgroupSize " - "variable needs to be a 3-component 32-bit int vector. " - "ID <2> (OpConstantComposite) is not an int vector.")); -} - -CodeGenerator GetWorkgroupSizeNotVec3Generator(spv_target_env env) { - CodeGenerator generator = - env == SPV_ENV_WEBGPU_0 ? CodeGenerator::GetWebGPUShaderCodeGenerator() - : CodeGenerator::GetDefaultShaderCodeGenerator(); +CodeGenerator GetWorkgroupSizeNotVec3Generator() { + CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator(); generator.before_types_ = R"( OpDecorate %workgroup_size BuiltIn WorkgroupSize @@ -3441,8 +2958,7 @@ OpDecorate %workgroup_size BuiltIn WorkgroupSize } TEST_F(ValidateBuiltIns, VulkanWorkgroupSizeNotVec3) { - CodeGenerator generator = - GetWorkgroupSizeNotVec3Generator(SPV_ENV_VULKAN_1_0); + CodeGenerator generator = GetWorkgroupSizeNotVec3Generator(); CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); @@ -3454,17 +2970,6 @@ TEST_F(ValidateBuiltIns, VulkanWorkgroupSizeNotVec3) { AnyVUID("VUID-WorkgroupSize-WorkgroupSize-04427")); } -TEST_F(ValidateBuiltIns, WebGPUWorkgroupSizeNotVec3) { - CodeGenerator generator = GetWorkgroupSizeNotVec3Generator(SPV_ENV_WEBGPU_0); - - CompileSuccessfully(generator.Build(), SPV_ENV_WEBGPU_0); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("According to the WebGPU spec BuiltIn WorkgroupSize " - "variable needs to be a 3-component 32-bit int vector. " - "ID <2> (OpConstantComposite) has 2 components.")); -} - TEST_F(ValidateBuiltIns, WorkgroupSizeNotInt32Vec) { CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator(); generator.before_types_ = R"( @@ -3742,10 +3247,8 @@ OpFunctionEnd HasSubstr("called with execution model Fragment")); } -CodeGenerator GetNoDepthReplacingGenerator(spv_target_env env) { - CodeGenerator generator = - spvIsWebGPUEnv(env) ? CodeGenerator::GetWebGPUShaderCodeGenerator() - : CodeGenerator::GetDefaultShaderCodeGenerator(); +CodeGenerator GetNoDepthReplacingGenerator() { + CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator(); generator.before_types_ = R"( OpMemberDecorate %output_type 0 BuiltIn FragDepth @@ -3778,17 +3281,13 @@ OpReturn OpFunctionEnd )"; - if (spvIsWebGPUEnv(env)) { - generator.after_types_ += function_body; - } else { generator.add_at_the_end_ = function_body; - } return generator; } TEST_F(ValidateBuiltIns, VulkanFragmentFragDepthNoDepthReplacing) { - CodeGenerator generator = GetNoDepthReplacingGenerator(SPV_ENV_VULKAN_1_0); + CodeGenerator generator = GetNoDepthReplacingGenerator(); CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); @@ -3799,21 +3298,8 @@ TEST_F(ValidateBuiltIns, VulkanFragmentFragDepthNoDepthReplacing) { HasSubstr("VUID-FragDepth-FragDepth-04216")); } -TEST_F(ValidateBuiltIns, WebGPUFragmentFragDepthNoDepthReplacing) { - CodeGenerator generator = GetNoDepthReplacingGenerator(SPV_ENV_WEBGPU_0); - - CompileSuccessfully(generator.Build(), SPV_ENV_WEBGPU_0); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("WebGPU spec requires DepthReplacing execution mode to " - "be declared when using BuiltIn FragDepth")); -} - -CodeGenerator GetOneMainHasDepthReplacingOtherHasntGenerator( - spv_target_env env) { - CodeGenerator generator = - spvIsWebGPUEnv(env) ? CodeGenerator::GetWebGPUShaderCodeGenerator() - : CodeGenerator::GetDefaultShaderCodeGenerator(); +CodeGenerator GetOneMainHasDepthReplacingOtherHasntGenerator() { + CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator(); generator.before_types_ = R"( OpMemberDecorate %output_type 0 BuiltIn FragDepth @@ -3857,19 +3343,14 @@ OpReturn OpFunctionEnd )"; - if (spvIsWebGPUEnv(env)) { - generator.after_types_ += function_body; - } else { generator.add_at_the_end_ = function_body; - } return generator; } TEST_F(ValidateBuiltIns, VulkanFragmentFragDepthOneMainHasDepthReplacingOtherHasnt) { - CodeGenerator generator = - GetOneMainHasDepthReplacingOtherHasntGenerator(SPV_ENV_VULKAN_1_0); + CodeGenerator generator = GetOneMainHasDepthReplacingOtherHasntGenerator(); CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0)); @@ -3880,17 +3361,6 @@ TEST_F(ValidateBuiltIns, HasSubstr("VUID-FragDepth-FragDepth-04216")); } -TEST_F(ValidateBuiltIns, - WebGPUFragmentFragDepthOneMainHasDepthReplacingOtherHasnt) { - CodeGenerator generator = - GetOneMainHasDepthReplacingOtherHasntGenerator(SPV_ENV_WEBGPU_0); - - CompileSuccessfully(generator.Build(), SPV_ENV_WEBGPU_0); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("WebGPU spec requires DepthReplacing execution mode to " - "be declared when using BuiltIn FragDepth")); -} TEST_F(ValidateBuiltIns, AllowInstanceIdWithIntersectionShader) { CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator(); diff --git a/test/val/val_capability_test.cpp b/test/val/val_capability_test.cpp index 9705cb8f89..82f8d38196 100644 --- a/test/val/val_capability_test.cpp +++ b/test/val/val_capability_test.cpp @@ -116,8 +116,6 @@ using ValidateCapabilityOpenGL40 = spvtest::ValidateBase; using ValidateCapabilityVulkan11 = spvtest::ValidateBase; // Always assembles using Vulkan 1.2. using ValidateCapabilityVulkan12 = spvtest::ValidateBase; -// Always assembles using WebGPU. -using ValidateCapabilityWebGPU = spvtest::ValidateBase; TEST_F(ValidateCapability, Default) { const char str[] = R"( @@ -588,18 +586,6 @@ const std::vector& AllVulkan12Capabilities() { return *r; } -const std::vector& AllWebGPUCapabilities() { - static const auto r = new std::vector{ - "", - "Shader", - "Matrix", - "Sampled1D", - "Image1D", - "ImageQuery", - "DerivativeControl"}; - return *r; -} - const std::vector& MatrixDependencies() { static const auto r = new std::vector{ "Matrix", @@ -790,12 +776,6 @@ const char kGLSL450MemoryModel[] = \ " OpCapability Shader" " OpMemoryModel Logical GLSL450 "; -const char kVulkanMemoryModel[] = \ - " OpCapability Shader" - " OpCapability VulkanMemoryModelKHR" - " OpExtension \"SPV_KHR_vulkan_memory_model\"" - " OpMemoryModel Logical VulkanKHR "; - const char kVoidFVoid[] = \ " %void = OpTypeVoid" " %void_f = OpTypeFunction %void" @@ -1814,16 +1794,6 @@ std::make_pair(std::string(kGLSL450MemoryModel) + AllSpirV10Capabilities()) ))); -INSTANTIATE_TEST_SUITE_P(Capabilities, ValidateCapabilityWebGPU, - Combine( - // All capabilities to try. - ValuesIn(AllCapabilities()), - Values( -std::make_pair(std::string(kVulkanMemoryModel) + - "OpEntryPoint Vertex %func \"shader\" \n" + std::string(kVoidFVoid), - AllWebGPUCapabilities()) -))); - INSTANTIATE_TEST_SUITE_P(Capabilities, ValidateCapabilityVulkan11, Combine( // All capabilities to try. @@ -2047,17 +2017,6 @@ TEST_P(ValidateCapabilityOpenGL40, Capability) { } } -TEST_P(ValidateCapabilityWebGPU, Capability) { - const std::string capability = Capability(GetParam()); - if (Exists(capability, SPV_ENV_WEBGPU_0)) { - const std::string test_code = MakeAssembly(GetParam()); - CompileSuccessfully(test_code, SPV_ENV_WEBGPU_0); - ASSERT_EQ(ExpectedResult(GetParam()), - ValidateInstructions(SPV_ENV_WEBGPU_0)) - << test_code; - } -} - TEST_F(ValidateCapability, SemanticsIdIsAnIdNotALiteral) { // From https://github.com/KhronosGroup/SPIRV-Tools/issues/248 // The validator was interpreting the memory semantics ID number diff --git a/test/val/val_cfg_test.cpp b/test/val/val_cfg_test.cpp index 7a268ebb32..9698fb1cbd 100644 --- a/test/val/val_cfg_test.cpp +++ b/test/val/val_cfg_test.cpp @@ -168,15 +168,6 @@ const std::string& GetDefaultHeader(SpvCapability cap) { return (cap == SpvCapabilityShader) ? shader_header : kernel_header; } -const std::string& GetWebGPUHeader() { - static const std::string header = - "OpCapability Shader\n" - "OpCapability VulkanMemoryModelKHR\n" - "OpExtension \"SPV_KHR_vulkan_memory_model\"\n" - "OpMemoryModel Logical VulkanKHR\n"; - return header; -} - const std::string& types_consts() { static const std::string types = "%voidt = OpTypeVoid\n" @@ -714,10 +705,8 @@ TEST_P(ValidateCFG, HeaderDoesntStrictlyDominateMergeBad) { } } -std::string GetUnreachableMergeNoMergeInst(SpvCapability cap, - spv_target_env env) { - std::string header = - spvIsWebGPUEnv(env) ? GetWebGPUHeader() : GetDefaultHeader(cap); +std::string GetUnreachableMergeNoMergeInst(SpvCapability cap) { + std::string header = GetDefaultHeader(cap); Block entry("entry"); Block branch("branch", SpvOpBranchConditional); Block t("t", SpvOpReturn); @@ -725,17 +714,11 @@ std::string GetUnreachableMergeNoMergeInst(SpvCapability cap, Block merge("merge", SpvOpReturn); entry.SetBody("%cond = OpSLessThan %boolt %one %two\n"); - if (!spvIsWebGPUEnv(env) && cap == SpvCapabilityShader) + if (cap == SpvCapabilityShader) branch.AppendBody("OpSelectionMerge %merge None\n"); std::string str = header; - if (spvIsWebGPUEnv(env)) { - str += - "OpEntryPoint Fragment %func \"func\"\n" - "OpExecutionMode %func OriginUpperLeft\n"; - } - if (!spvIsWebGPUEnv(env)) - str += nameOps("branch", "merge", std::make_pair("func", "Main")); + str += nameOps("branch", "merge", std::make_pair("func", "Main")); str += types_consts() + "%func = OpFunction %voidt None %funct\n"; str += entry >> branch; str += branch >> std::vector({t, f}); @@ -748,23 +731,12 @@ std::string GetUnreachableMergeNoMergeInst(SpvCapability cap, } TEST_P(ValidateCFG, UnreachableMergeNoMergeInst) { - CompileSuccessfully( - GetUnreachableMergeNoMergeInst(GetParam(), SPV_ENV_UNIVERSAL_1_0)); + CompileSuccessfully(GetUnreachableMergeNoMergeInst(GetParam())); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } -TEST_F(ValidateCFG, WebGPUUnreachableMergeNoMergeInst) { - CompileSuccessfully( - GetUnreachableMergeNoMergeInst(SpvCapabilityShader, SPV_ENV_WEBGPU_0)); - ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("For WebGPU, all blocks must be reachable")); -} - -std::string GetUnreachableMergeTerminatedBy(SpvCapability cap, - spv_target_env env, SpvOp op) { - std::string header = - spvIsWebGPUEnv(env) ? GetWebGPUHeader() : GetDefaultHeader(cap); +std::string GetUnreachableMergeTerminatedBy(SpvCapability cap, SpvOp op) { + std::string header = GetDefaultHeader(cap); Block entry("entry"); Block branch("branch", SpvOpBranchConditional); @@ -774,16 +746,10 @@ std::string GetUnreachableMergeTerminatedBy(SpvCapability cap, entry.SetBody("%cond = OpSLessThan %boolt %one %two\n"); std::string str = header; - if (spvIsWebGPUEnv(env)) { - str += - "OpEntryPoint Fragment %func \"func\"\n" - "OpExecutionMode %func OriginUpperLeft\n"; - } if (cap == SpvCapabilityShader) branch.AppendBody("OpSelectionMerge %merge None\n"); - if (!spvIsWebGPUEnv(env)) - str += nameOps("branch", "merge", std::make_pair("func", "Main")); + str += nameOps("branch", "merge", std::make_pair("func", "Main")); str += types_consts(); str += "%func = OpFunction %voidt None %funct\n"; str += entry >> branch; @@ -797,49 +763,24 @@ std::string GetUnreachableMergeTerminatedBy(SpvCapability cap, } TEST_P(ValidateCFG, UnreachableMergeTerminatedByOpUnreachable) { - CompileSuccessfully(GetUnreachableMergeTerminatedBy( - GetParam(), SPV_ENV_UNIVERSAL_1_0, SpvOpUnreachable)); + CompileSuccessfully( + GetUnreachableMergeTerminatedBy(GetParam(), SpvOpUnreachable)); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } TEST_F(ValidateCFG, UnreachableMergeTerminatedByOpKill) { - CompileSuccessfully(GetUnreachableMergeTerminatedBy( - SpvCapabilityShader, SPV_ENV_UNIVERSAL_1_0, SpvOpKill)); + CompileSuccessfully( + GetUnreachableMergeTerminatedBy(SpvCapabilityShader, SpvOpKill)); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } TEST_P(ValidateCFG, UnreachableMergeTerminatedByOpReturn) { - CompileSuccessfully(GetUnreachableMergeTerminatedBy( - GetParam(), SPV_ENV_UNIVERSAL_1_0, SpvOpReturn)); + CompileSuccessfully(GetUnreachableMergeTerminatedBy(GetParam(), SpvOpReturn)); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } -TEST_F(ValidateCFG, WebGPUUnreachableMergeTerminatedByOpUnreachable) { - CompileSuccessfully(GetUnreachableMergeTerminatedBy( - SpvCapabilityShader, SPV_ENV_WEBGPU_0, SpvOpUnreachable)); - ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); -} - -TEST_F(ValidateCFG, WebGPUUnreachableMergeTerminatedByOpKill) { - CompileSuccessfully(GetUnreachableMergeTerminatedBy( - SpvCapabilityShader, SPV_ENV_WEBGPU_0, SpvOpKill)); - ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("must terminate with OpUnreachable")); -} - -TEST_P(ValidateCFG, WebGPUUnreachableMergeTerminatedByOpReturn) { - CompileSuccessfully(GetUnreachableMergeTerminatedBy( - SpvCapabilityShader, SPV_ENV_WEBGPU_0, SpvOpReturn)); - ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("must terminate with OpUnreachable")); -} - -std::string GetUnreachableContinueTerminatedBy(SpvCapability cap, - spv_target_env env, SpvOp op) { - std::string header = - spvIsWebGPUEnv(env) ? GetWebGPUHeader() : GetDefaultHeader(cap); +std::string GetUnreachableContinueTerminatedBy(SpvCapability cap, SpvOp op) { + std::string header = GetDefaultHeader(cap); Block entry("entry"); Block branch("branch", SpvOpBranch); @@ -849,16 +790,10 @@ std::string GetUnreachableContinueTerminatedBy(SpvCapability cap, if (op == SpvOpBranch) target >> branch; std::string str = header; - if (spvIsWebGPUEnv(env)) { - str += - "OpEntryPoint Fragment %func \"func\"\n" - "OpExecutionMode %func OriginUpperLeft\n"; - } if (cap == SpvCapabilityShader) branch.AppendBody("OpLoopMerge %merge %target None\n"); - if (!spvIsWebGPUEnv(env)) - str += nameOps("branch", "merge", "target", std::make_pair("func", "Main")); + str += nameOps("branch", "merge", "target", std::make_pair("func", "Main")); str += types_consts(); str += "%func = OpFunction %voidt None %funct\n"; str += entry >> branch; @@ -871,8 +806,8 @@ std::string GetUnreachableContinueTerminatedBy(SpvCapability cap, } TEST_P(ValidateCFG, UnreachableContinueTerminatedBySpvOpUnreachable) { - CompileSuccessfully(GetUnreachableContinueTerminatedBy( - GetParam(), SPV_ENV_UNIVERSAL_1_0, SpvOpUnreachable)); + CompileSuccessfully( + GetUnreachableContinueTerminatedBy(GetParam(), SpvOpUnreachable)); if (GetParam() == SpvCapabilityShader) { ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), @@ -883,16 +818,16 @@ TEST_P(ValidateCFG, UnreachableContinueTerminatedBySpvOpUnreachable) { } TEST_F(ValidateCFG, UnreachableContinueTerminatedBySpvOpKill) { - CompileSuccessfully(GetUnreachableContinueTerminatedBy( - SpvCapabilityShader, SPV_ENV_UNIVERSAL_1_0, SpvOpKill)); + CompileSuccessfully( + GetUnreachableContinueTerminatedBy(SpvCapabilityShader, SpvOpKill)); ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), HasSubstr("targeted by 0 back-edge blocks")); } TEST_P(ValidateCFG, UnreachableContinueTerminatedBySpvOpReturn) { - CompileSuccessfully(GetUnreachableContinueTerminatedBy( - GetParam(), SPV_ENV_UNIVERSAL_1_0, SpvOpReturn)); + CompileSuccessfully( + GetUnreachableContinueTerminatedBy(GetParam(), SpvOpReturn)); if (GetParam() == SpvCapabilityShader) { ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), @@ -903,48 +838,13 @@ TEST_P(ValidateCFG, UnreachableContinueTerminatedBySpvOpReturn) { } TEST_P(ValidateCFG, UnreachableContinueTerminatedBySpvOpBranch) { - CompileSuccessfully(GetUnreachableContinueTerminatedBy( - GetParam(), SPV_ENV_UNIVERSAL_1_0, SpvOpBranch)); + CompileSuccessfully( + GetUnreachableContinueTerminatedBy(GetParam(), SpvOpBranch)); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } -TEST_F(ValidateCFG, WebGPUUnreachableContinueTerminatedBySpvOpUnreachable) { - CompileSuccessfully(GetUnreachableContinueTerminatedBy( - SpvCapabilityShader, SPV_ENV_WEBGPU_0, SpvOpUnreachable)); - ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("For WebGPU, unreachable continue-target must " - "terminate with OpBranch.\n %12 = OpLabel\n")); -} - -TEST_F(ValidateCFG, WebGPUUnreachableContinueTerminatedBySpvOpKill) { - CompileSuccessfully(GetUnreachableContinueTerminatedBy( - SpvCapabilityShader, SPV_ENV_WEBGPU_0, SpvOpKill)); - ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("For WebGPU, unreachable continue-target must " - "terminate with OpBranch.\n %12 = OpLabel\n")); -} - -TEST_F(ValidateCFG, WebGPUUnreachableContinueTerminatedBySpvOpReturn) { - CompileSuccessfully(GetUnreachableContinueTerminatedBy( - SpvCapabilityShader, SPV_ENV_WEBGPU_0, SpvOpReturn)); - ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("For WebGPU, unreachable continue-target must " - "terminate with OpBranch.\n %12 = OpLabel\n")); -} - -TEST_F(ValidateCFG, WebGPUUnreachableContinueTerminatedBySpvOpBranch) { - CompileSuccessfully(GetUnreachableContinueTerminatedBy( - SpvCapabilityShader, SPV_ENV_WEBGPU_0, SpvOpBranch)); - ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); -} - -std::string GetUnreachableMergeUnreachableMergeInst(SpvCapability cap, - spv_target_env env) { - std::string header = - spvIsWebGPUEnv(env) ? GetWebGPUHeader() : GetDefaultHeader(cap); +std::string GetUnreachableMergeUnreachableMergeInst(SpvCapability cap) { + std::string header = GetDefaultHeader(cap); Block body("body", SpvOpReturn); Block entry("entry"); @@ -955,16 +855,10 @@ std::string GetUnreachableMergeUnreachableMergeInst(SpvCapability cap, entry.SetBody("%cond = OpSLessThan %boolt %one %two\n"); std::string str = header; - if (spvIsWebGPUEnv(env)) { - str += - "OpEntryPoint Fragment %func \"func\"\n" - "OpExecutionMode %func OriginUpperLeft\n"; - } if (cap == SpvCapabilityShader) branch.AppendBody("OpSelectionMerge %merge None\n"); - if (!spvIsWebGPUEnv(env)) - str += nameOps("branch", "merge", std::make_pair("func", "Main")); + str += nameOps("branch", "merge", std::make_pair("func", "Main")); str += types_consts(); str += "%func = OpFunction %voidt None %funct\n"; str += body; @@ -979,23 +873,12 @@ std::string GetUnreachableMergeUnreachableMergeInst(SpvCapability cap, } TEST_P(ValidateCFG, UnreachableMergeUnreachableMergeInst) { - CompileSuccessfully(GetUnreachableMergeUnreachableMergeInst( - GetParam(), SPV_ENV_UNIVERSAL_1_0)); + CompileSuccessfully(GetUnreachableMergeUnreachableMergeInst(GetParam())); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } -TEST_F(ValidateCFG, WebGPUUnreachableMergeUnreachableMergeInst) { - CompileSuccessfully(GetUnreachableMergeUnreachableMergeInst( - SpvCapabilityShader, SPV_ENV_WEBGPU_0)); - ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("must be referenced by a reachable merge instruction")); -} - -std::string GetUnreachableContinueUnreachableLoopInst(SpvCapability cap, - spv_target_env env) { - std::string header = - spvIsWebGPUEnv(env) ? GetWebGPUHeader() : GetDefaultHeader(cap); +std::string GetUnreachableContinueUnreachableLoopInst(SpvCapability cap) { + std::string header = GetDefaultHeader(cap); Block body("body", SpvOpReturn); Block entry("entry"); @@ -1006,16 +889,10 @@ std::string GetUnreachableContinueUnreachableLoopInst(SpvCapability cap, target >> branch; std::string str = header; - if (spvIsWebGPUEnv(env)) { - str += - "OpEntryPoint Fragment %func \"func\"\n" - "OpExecutionMode %func OriginUpperLeft\n"; - } if (cap == SpvCapabilityShader) branch.AppendBody("OpLoopMerge %merge %target None\n"); - if (!spvIsWebGPUEnv(env)) - str += nameOps("branch", "merge", "target", std::make_pair("func", "Main")); + str += nameOps("branch", "merge", "target", std::make_pair("func", "Main")); str += types_consts(); str += "%func = OpFunction %voidt None %funct\n"; str += body; @@ -1029,8 +906,7 @@ std::string GetUnreachableContinueUnreachableLoopInst(SpvCapability cap, } TEST_P(ValidateCFG, UnreachableContinueUnreachableLoopInst) { - CompileSuccessfully(GetUnreachableContinueUnreachableLoopInst( - GetParam(), SPV_ENV_UNIVERSAL_1_0)); + CompileSuccessfully(GetUnreachableContinueUnreachableLoopInst(GetParam())); if (GetParam() == SpvCapabilityShader) { // Shader causes additional structured CFG checks that cause a failure. ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions()); @@ -1043,18 +919,8 @@ TEST_P(ValidateCFG, UnreachableContinueUnreachableLoopInst) { } } -TEST_F(ValidateCFG, WebGPUUnreachableContinueUnreachableLoopInst) { - CompileSuccessfully(GetUnreachableContinueUnreachableLoopInst( - SpvCapabilityShader, SPV_ENV_WEBGPU_0)); - ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("must be referenced by a reachable loop instruction")); -} - -std::string GetUnreachableMergeWithComplexBody(SpvCapability cap, - spv_target_env env) { - std::string header = - spvIsWebGPUEnv(env) ? GetWebGPUHeader() : GetDefaultHeader(cap); +std::string GetUnreachableMergeWithComplexBody(SpvCapability cap) { + std::string header = GetDefaultHeader(cap); Block entry("entry"); Block branch("branch", SpvOpBranchConditional); @@ -1062,23 +928,15 @@ std::string GetUnreachableMergeWithComplexBody(SpvCapability cap, Block f("f", SpvOpReturn); Block merge("merge", SpvOpUnreachable); - entry.AppendBody(spvIsWebGPUEnv(env) - ? "%placeholder = OpVariable %intptrt Function %two\n" - : "%placeholder = OpVariable %intptrt Function\n"); + entry.AppendBody("%placeholder = OpVariable %intptrt Function\n"); entry.AppendBody("%cond = OpSLessThan %boolt %one %two\n"); merge.AppendBody("OpStore %placeholder %one\n"); std::string str = header; - if (spvIsWebGPUEnv(env)) { - str += - "OpEntryPoint Fragment %func \"func\"\n" - "OpExecutionMode %func OriginUpperLeft\n"; - } if (cap == SpvCapabilityShader) branch.AppendBody("OpSelectionMerge %merge None\n"); - if (!spvIsWebGPUEnv(env)) - str += nameOps("branch", "merge", std::make_pair("func", "Main")); + str += nameOps("branch", "merge", std::make_pair("func", "Main")); str += types_consts(); str += "%intptrt = OpTypePointer Function %intt\n"; str += "%func = OpFunction %voidt None %funct\n"; @@ -1093,24 +951,12 @@ std::string GetUnreachableMergeWithComplexBody(SpvCapability cap, } TEST_P(ValidateCFG, UnreachableMergeWithComplexBody) { - CompileSuccessfully( - GetUnreachableMergeWithComplexBody(GetParam(), SPV_ENV_UNIVERSAL_1_0)); + CompileSuccessfully(GetUnreachableMergeWithComplexBody(GetParam())); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } -TEST_F(ValidateCFG, WebGPUUnreachableMergeWithComplexBody) { - CompileSuccessfully(GetUnreachableMergeWithComplexBody(SpvCapabilityShader, - SPV_ENV_WEBGPU_0)); - ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("must only contain an OpLabel and OpUnreachable instruction")); -} - -std::string GetUnreachableContinueWithComplexBody(SpvCapability cap, - spv_target_env env) { - std::string header = - spvIsWebGPUEnv(env) ? GetWebGPUHeader() : GetDefaultHeader(cap); +std::string GetUnreachableContinueWithComplexBody(SpvCapability cap) { + std::string header = GetDefaultHeader(cap); Block entry("entry"); Block branch("branch", SpvOpBranch); @@ -1119,22 +965,14 @@ std::string GetUnreachableContinueWithComplexBody(SpvCapability cap, target >> branch; - entry.AppendBody(spvIsWebGPUEnv(env) - ? "%placeholder = OpVariable %intptrt Function %two\n" - : "%placeholder = OpVariable %intptrt Function\n"); + entry.AppendBody("%placeholder = OpVariable %intptrt Function\n"); target.AppendBody("OpStore %placeholder %one\n"); std::string str = header; - if (spvIsWebGPUEnv(env)) { - str += - "OpEntryPoint Fragment %func \"func\"\n" - "OpExecutionMode %func OriginUpperLeft\n"; - } if (cap == SpvCapabilityShader) branch.AppendBody("OpLoopMerge %merge %target None\n"); - if (!spvIsWebGPUEnv(env)) - str += nameOps("branch", "merge", "target", std::make_pair("func", "Main")); + str += nameOps("branch", "merge", "target", std::make_pair("func", "Main")); str += types_consts(); str += "%intptrt = OpTypePointer Function %intt\n"; str += "%func = OpFunction %voidt None %funct\n"; @@ -1148,24 +986,12 @@ std::string GetUnreachableContinueWithComplexBody(SpvCapability cap, } TEST_P(ValidateCFG, UnreachableContinueWithComplexBody) { - CompileSuccessfully( - GetUnreachableContinueWithComplexBody(GetParam(), SPV_ENV_UNIVERSAL_1_0)); + CompileSuccessfully(GetUnreachableContinueWithComplexBody(GetParam())); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } -TEST_F(ValidateCFG, WebGPUUnreachableContinueWithComplexBody) { - CompileSuccessfully(GetUnreachableContinueWithComplexBody(SpvCapabilityShader, - SPV_ENV_WEBGPU_0)); - ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("must only contain an OpLabel and an OpBranch instruction")); -} - -std::string GetUnreachableMergeWithBranchUse(SpvCapability cap, - spv_target_env env) { - std::string header = - spvIsWebGPUEnv(env) ? GetWebGPUHeader() : GetDefaultHeader(cap); +std::string GetUnreachableMergeWithBranchUse(SpvCapability cap) { + std::string header = GetDefaultHeader(cap); Block entry("entry"); Block branch("branch", SpvOpBranchConditional); @@ -1176,16 +1002,10 @@ std::string GetUnreachableMergeWithBranchUse(SpvCapability cap, entry.AppendBody("%cond = OpSLessThan %boolt %one %two\n"); std::string str = header; - if (spvIsWebGPUEnv(env)) { - str += - "OpEntryPoint Fragment %func \"func\"\n" - "OpExecutionMode %func OriginUpperLeft\n"; - } if (cap == SpvCapabilityShader) branch.AppendBody("OpSelectionMerge %merge None\n"); - if (!spvIsWebGPUEnv(env)) - str += nameOps("branch", "merge", std::make_pair("func", "Main")); + str += nameOps("branch", "merge", std::make_pair("func", "Main")); str += types_consts(); str += "%func = OpFunction %voidt None %funct\n"; str += entry >> branch; @@ -1199,15 +1019,12 @@ std::string GetUnreachableMergeWithBranchUse(SpvCapability cap, } TEST_P(ValidateCFG, UnreachableMergeWithBranchUse) { - CompileSuccessfully( - GetUnreachableMergeWithBranchUse(GetParam(), SPV_ENV_UNIVERSAL_1_0)); + CompileSuccessfully(GetUnreachableMergeWithBranchUse(GetParam())); EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); } -std::string GetUnreachableMergeWithMultipleUses(SpvCapability cap, - spv_target_env env) { - std::string header = - spvIsWebGPUEnv(env) ? GetWebGPUHeader() : GetDefaultHeader(cap); +std::string GetUnreachableMergeWithMultipleUses(SpvCapability cap) { + std::string header = GetDefaultHeader(cap); Block entry("entry"); Block branch("branch", SpvOpBranchConditional); @@ -1219,18 +1036,12 @@ std::string GetUnreachableMergeWithMultipleUses(SpvCapability cap, entry.AppendBody("%cond = OpSLessThan %boolt %one %two\n"); std::string str = header; - if (spvIsWebGPUEnv(env)) { - str += - "OpEntryPoint Fragment %func \"func\"\n" - "OpExecutionMode %func OriginUpperLeft\n"; - } if (cap == SpvCapabilityShader) { branch.AppendBody("OpSelectionMerge %merge None\n"); duplicate.AppendBody("OpSelectionMerge %merge None\n"); } - if (!spvIsWebGPUEnv(env)) - str += nameOps("branch", "merge", std::make_pair("func", "Main")); + str += nameOps("branch", "merge", std::make_pair("func", "Main")); str += types_consts(); str += "%func = OpFunction %voidt None %funct\n"; str += entry >> branch; @@ -1245,8 +1056,7 @@ std::string GetUnreachableMergeWithMultipleUses(SpvCapability cap, } TEST_P(ValidateCFG, UnreachableMergeWithMultipleUses) { - CompileSuccessfully( - GetUnreachableMergeWithMultipleUses(GetParam(), SPV_ENV_UNIVERSAL_1_0)); + CompileSuccessfully(GetUnreachableMergeWithMultipleUses(GetParam())); if (GetParam() == SpvCapabilityShader) { ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions()); EXPECT_THAT(getDiagnosticString(), @@ -1256,18 +1066,8 @@ TEST_P(ValidateCFG, UnreachableMergeWithMultipleUses) { } } -TEST_F(ValidateCFG, WebGPUUnreachableMergeWithMultipleUses) { - CompileSuccessfully(GetUnreachableMergeWithMultipleUses(SpvCapabilityShader, - SPV_ENV_WEBGPU_0)); - ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("is already a merge block for another header")); -} - -std::string GetUnreachableContinueWithBranchUse(SpvCapability cap, - spv_target_env env) { - std::string header = - spvIsWebGPUEnv(env) ? GetWebGPUHeader() : GetDefaultHeader(cap); +std::string GetUnreachableContinueWithBranchUse(SpvCapability cap) { + std::string header = GetDefaultHeader(cap); Block entry("entry"); Block foo("foo", SpvOpBranch); @@ -1278,21 +1078,13 @@ std::string GetUnreachableContinueWithBranchUse(SpvCapability cap, foo >> target; target >> branch; - entry.AppendBody(spvIsWebGPUEnv(env) - ? "%placeholder = OpVariable %intptrt Function %two\n" - : "%placeholder = OpVariable %intptrt Function\n"); + entry.AppendBody("%placeholder = OpVariable %intptrt Function\n"); std::string str = header; - if (spvIsWebGPUEnv(env)) { - str += - "OpEntryPoint Fragment %func \"func\"\n" - "OpExecutionMode %func OriginUpperLeft\n"; - } if (cap == SpvCapabilityShader) branch.AppendBody("OpLoopMerge %merge %target None\n"); - if (!spvIsWebGPUEnv(env)) - str += nameOps("branch", "merge", "target", std::make_pair("func", "Main")); + str += nameOps("branch", "merge", "target", std::make_pair("func", "Main")); str += types_consts(); str += "%intptrt = OpTypePointer Function %intt\n"; str += "%func = OpFunction %voidt None %funct\n"; @@ -1307,23 +1099,12 @@ std::string GetUnreachableContinueWithBranchUse(SpvCapability cap, } TEST_P(ValidateCFG, UnreachableContinueWithBranchUse) { - CompileSuccessfully( - GetUnreachableContinueWithBranchUse(GetParam(), SPV_ENV_UNIVERSAL_1_0)); + CompileSuccessfully(GetUnreachableContinueWithBranchUse(GetParam())); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } -TEST_F(ValidateCFG, WebGPUUnreachableContinueWithBranchUse) { - CompileSuccessfully(GetUnreachableContinueWithBranchUse(SpvCapabilityShader, - SPV_ENV_WEBGPU_0)); - ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("cannot be the target of a branch.")); -} - -std::string GetReachableMergeAndContinue(SpvCapability cap, - spv_target_env env) { - std::string header = - spvIsWebGPUEnv(env) ? GetWebGPUHeader() : GetDefaultHeader(cap); +std::string GetReachableMergeAndContinue(SpvCapability cap) { + std::string header = GetDefaultHeader(cap); Block entry("entry"); Block branch("branch", SpvOpBranch); @@ -1339,20 +1120,13 @@ std::string GetReachableMergeAndContinue(SpvCapability cap, f >> target; std::string str = header; - if (spvIsWebGPUEnv(env)) { - str += - "OpEntryPoint Fragment %func \"func\"\n" - "OpExecutionMode %func OriginUpperLeft\n"; - } if (cap == SpvCapabilityShader) { branch.AppendBody("OpLoopMerge %merge %target None\n"); body.AppendBody("OpSelectionMerge %f None\n"); } - if (!spvIsWebGPUEnv(env)) - str += nameOps("branch", "merge", "target", "body", "t", "f", - std::make_pair("func", "Main")); - + str += nameOps("branch", "merge", "target", "body", "t", "f", + std::make_pair("func", "Main")); str += types_consts(); str += "%func = OpFunction %voidt None %funct\n"; str += entry >> branch; @@ -1368,21 +1142,12 @@ std::string GetReachableMergeAndContinue(SpvCapability cap, } TEST_P(ValidateCFG, ReachableMergeAndContinue) { - CompileSuccessfully( - GetReachableMergeAndContinue(GetParam(), SPV_ENV_UNIVERSAL_1_0)); + CompileSuccessfully(GetReachableMergeAndContinue(GetParam())); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } -TEST_F(ValidateCFG, WebGPUReachableMergeAndContinue) { - CompileSuccessfully( - GetReachableMergeAndContinue(SpvCapabilityShader, SPV_ENV_WEBGPU_0)); - ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); -} - -std::string GetUnreachableMergeAndContinue(SpvCapability cap, - spv_target_env env) { - std::string header = - spvIsWebGPUEnv(env) ? GetWebGPUHeader() : GetDefaultHeader(cap); +std::string GetUnreachableMergeAndContinue(SpvCapability cap) { + std::string header = GetDefaultHeader(cap); Block entry("entry"); Block branch("branch", SpvOpBranch); @@ -1396,20 +1161,13 @@ std::string GetUnreachableMergeAndContinue(SpvCapability cap, body.SetBody("%cond = OpSLessThan %boolt %one %two\n"); std::string str = header; - if (spvIsWebGPUEnv(env)) { - str += - "OpEntryPoint Fragment %func \"func\"\n" - "OpExecutionMode %func OriginUpperLeft\n"; - } if (cap == SpvCapabilityShader) { branch.AppendBody("OpLoopMerge %merge %target None\n"); body.AppendBody("OpSelectionMerge %target None\n"); } - if (!spvIsWebGPUEnv(env)) - str += nameOps("branch", "merge", "target", "body", "t", "f", - std::make_pair("func", "Main")); - + str += nameOps("branch", "merge", "target", "body", "t", "f", + std::make_pair("func", "Main")); str += types_consts(); str += "%func = OpFunction %voidt None %funct\n"; str += entry >> branch; @@ -1425,36 +1183,19 @@ std::string GetUnreachableMergeAndContinue(SpvCapability cap, } TEST_P(ValidateCFG, UnreachableMergeAndContinue) { - CompileSuccessfully( - GetUnreachableMergeAndContinue(GetParam(), SPV_ENV_UNIVERSAL_1_0)); + CompileSuccessfully(GetUnreachableMergeAndContinue(GetParam())); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } -TEST_F(ValidateCFG, WebGPUUnreachableMergeAndContinue) { - CompileSuccessfully( - GetUnreachableMergeAndContinue(SpvCapabilityShader, SPV_ENV_WEBGPU_0)); - ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("unreachable merge-blocks must terminate with OpUnreachable")); -} - -std::string GetUnreachableBlock(SpvCapability cap, spv_target_env env) { - std::string header = - spvIsWebGPUEnv(env) ? GetWebGPUHeader() : GetDefaultHeader(cap); +std::string GetUnreachableBlock(SpvCapability cap) { + std::string header = GetDefaultHeader(cap); Block entry("entry"); Block unreachable("unreachable"); Block exit("exit", SpvOpReturn); std::string str = header; - if (spvIsWebGPUEnv(env)) { - str += - "OpEntryPoint Fragment %func \"func\"\n" - "OpExecutionMode %func OriginUpperLeft\n"; - } - if (!spvIsWebGPUEnv(env)) - str += nameOps("unreachable", "exit", std::make_pair("func", "Main")); + str += nameOps("unreachable", "exit", std::make_pair("func", "Main")); str += types_consts(); str += "%func = OpFunction %voidt None %funct\n"; str += entry >> exit; @@ -1466,20 +1207,12 @@ std::string GetUnreachableBlock(SpvCapability cap, spv_target_env env) { } TEST_P(ValidateCFG, UnreachableBlock) { - CompileSuccessfully(GetUnreachableBlock(GetParam(), SPV_ENV_UNIVERSAL_1_0)); + CompileSuccessfully(GetUnreachableBlock(GetParam())); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } -TEST_F(ValidateCFG, WebGPUUnreachableBlock) { - CompileSuccessfully( - GetUnreachableBlock(SpvCapabilityShader, SPV_ENV_WEBGPU_0)); - ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), HasSubstr("all blocks must be reachable")); -} - -std::string GetUnreachableBranch(SpvCapability cap, spv_target_env env) { - std::string header = - spvIsWebGPUEnv(env) ? GetWebGPUHeader() : GetDefaultHeader(cap); +std::string GetUnreachableBranch(SpvCapability cap) { + std::string header = GetDefaultHeader(cap); Block entry("entry"); Block unreachable("unreachable", SpvOpBranchConditional); @@ -1493,13 +1226,7 @@ std::string GetUnreachableBranch(SpvCapability cap, spv_target_env env) { unreachable.AppendBody("OpSelectionMerge %merge None\n"); std::string str = header; - if (spvIsWebGPUEnv(env)) { - str += - "OpEntryPoint Fragment %func \"func\"\n" - "OpExecutionMode %func OriginUpperLeft\n"; - } - if (!spvIsWebGPUEnv(env)) - str += nameOps("unreachable", "exit", std::make_pair("func", "Main")); + str += nameOps("unreachable", "exit", std::make_pair("func", "Main")); str += types_consts(); str += "%func = OpFunction %voidt None %funct\n"; @@ -1516,17 +1243,10 @@ std::string GetUnreachableBranch(SpvCapability cap, spv_target_env env) { } TEST_P(ValidateCFG, UnreachableBranch) { - CompileSuccessfully(GetUnreachableBranch(GetParam(), SPV_ENV_UNIVERSAL_1_0)); + CompileSuccessfully(GetUnreachableBranch(GetParam())); ASSERT_EQ(SPV_SUCCESS, ValidateInstructions()); } -TEST_F(ValidateCFG, WebGPUUnreachableBranch) { - CompileSuccessfully( - GetUnreachableBranch(SpvCapabilityShader, SPV_ENV_WEBGPU_0)); - ASSERT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), HasSubstr("all blocks must be reachable")); -} - TEST_P(ValidateCFG, EmptyFunction) { std::string str = GetDefaultHeader(GetParam()) + std::string(types_consts()) + R"(%func = OpFunction %voidt None %funct diff --git a/test/val/val_code_generator.cpp b/test/val/val_code_generator.cpp index 96971f9be6..f151f51acb 100644 --- a/test/val/val_code_generator.cpp +++ b/test/val/val_code_generator.cpp @@ -32,13 +32,6 @@ OpCapability SampleRateShading )"; } -std::string GetWebGPUShaderCapabilities() { - return R"( -OpCapability Shader -OpCapability VulkanMemoryModelKHR -)"; -} - std::string GetDefaultShaderTypes() { return R"( %void = OpTypeVoid @@ -127,55 +120,6 @@ std::string GetDefaultShaderTypes() { )"; } -std::string GetWebGPUShaderTypes() { - return R"( -%void = OpTypeVoid -%func = OpTypeFunction %void -%bool = OpTypeBool -%f32 = OpTypeFloat 32 -%u32 = OpTypeInt 32 0 -%f32vec2 = OpTypeVector %f32 2 -%f32vec3 = OpTypeVector %f32 3 -%f32vec4 = OpTypeVector %f32 4 -%u32vec2 = OpTypeVector %u32 2 -%u32vec3 = OpTypeVector %u32 3 -%u32vec4 = OpTypeVector %u32 4 - -%f32_0 = OpConstant %f32 0 -%f32_1 = OpConstant %f32 1 -%f32_2 = OpConstant %f32 2 -%f32_3 = OpConstant %f32 3 -%f32_4 = OpConstant %f32 4 -%f32_h = OpConstant %f32 0.5 -%f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1 -%f32vec2_12 = OpConstantComposite %f32vec2 %f32_1 %f32_2 -%f32vec3_012 = OpConstantComposite %f32vec3 %f32_0 %f32_1 %f32_2 -%f32vec3_123 = OpConstantComposite %f32vec3 %f32_1 %f32_2 %f32_3 -%f32vec4_0123 = OpConstantComposite %f32vec4 %f32_0 %f32_1 %f32_2 %f32_3 -%f32vec4_1234 = OpConstantComposite %f32vec4 %f32_1 %f32_2 %f32_3 %f32_4 - -%u32_0 = OpConstant %u32 0 -%u32_1 = OpConstant %u32 1 -%u32_2 = OpConstant %u32 2 -%u32_3 = OpConstant %u32 3 -%u32_4 = OpConstant %u32 4 - -%u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1 -%u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2 -%u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3 - -%u32arr2 = OpTypeArray %u32 %u32_2 -%u32arr3 = OpTypeArray %u32 %u32_3 -%u32arr4 = OpTypeArray %u32 %u32_4 -%f32arr2 = OpTypeArray %f32 %u32_2 -%f32arr3 = OpTypeArray %f32 %u32_3 -%f32arr4 = OpTypeArray %f32 %u32_4 - -%f32vec3arr3 = OpTypeArray %f32vec3 %u32_3 -%f32vec4arr3 = OpTypeArray %f32vec4 %u32_3 -)"; -} - } // namespace CodeGenerator CodeGenerator::GetDefaultShaderCodeGenerator() { @@ -186,15 +130,6 @@ CodeGenerator CodeGenerator::GetDefaultShaderCodeGenerator() { return generator; } -CodeGenerator CodeGenerator::GetWebGPUShaderCodeGenerator() { - CodeGenerator generator; - generator.capabilities_ = GetWebGPUShaderCapabilities(); - generator.memory_model_ = "OpMemoryModel Logical VulkanKHR\n"; - generator.extensions_ = "OpExtension \"SPV_KHR_vulkan_memory_model\"\n"; - generator.types_ = GetWebGPUShaderTypes(); - return generator; -} - std::string CodeGenerator::Build() const { std::ostringstream ss; diff --git a/test/val/val_code_generator.h b/test/val/val_code_generator.h index e580ddff70..c69deeecea 100644 --- a/test/val/val_code_generator.h +++ b/test/val/val_code_generator.h @@ -31,7 +31,6 @@ struct EntryPoint { class CodeGenerator { public: static CodeGenerator GetDefaultShaderCodeGenerator(); - static CodeGenerator GetWebGPUShaderCodeGenerator(); std::string Build() const; diff --git a/test/val/val_data_test.cpp b/test/val/val_data_test.cpp index 99a9aa0931..1d4c0e044b 100644 --- a/test/val/val_data_test.cpp +++ b/test/val/val_data_test.cpp @@ -36,24 +36,6 @@ std::string HeaderWith(std::string cap) { cap + " OpMemoryModel Logical GLSL450 "; } -std::string WebGPUHeaderWith(std::string cap) { - return R"( -OpCapability Shader -OpCapability )" + - cap + R"( -OpCapability VulkanMemoryModelKHR -OpExtension "SPV_KHR_vulkan_memory_model" -OpMemoryModel Logical VulkanKHR -)"; -} - -std::string webgpu_header = R"( -OpCapability Shader -OpCapability VulkanMemoryModelKHR -OpExtension "SPV_KHR_vulkan_memory_model" -OpMemoryModel Logical VulkanKHR -)"; - std::string header = R"( OpCapability Shader OpCapability Linkage @@ -267,18 +249,6 @@ TEST_F(ValidateData, int8_with_storage_push_constant_8_good) { EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()) << getDiagnosticString(); } -TEST_F(ValidateData, webgpu_int8_bad) { - std::string str = WebGPUHeaderWith("Int8") + "%2 = OpTypeInt 8 0"; - CompileSuccessfully(str.c_str(), SPV_ENV_WEBGPU_0); - ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, - ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("Capability Int8 is not allowed by WebGPU specification (or " - "requires extension)\n" - " OpCapability Int8\n")); -} - TEST_F(ValidateData, int16_good) { std::string str = header_with_int16 + "%2 = OpTypeInt 16 1"; CompileSuccessfully(str.c_str()); @@ -338,34 +308,6 @@ TEST_F(ValidateData, int16_bad) { EXPECT_THAT(getDiagnosticString(), HasSubstr(missing_int16_cap_error)); } -TEST_F(ValidateData, webgpu_int16_bad) { - std::string str = WebGPUHeaderWith("Int16") + "%2 = OpTypeInt 16 1"; - CompileSuccessfully(str.c_str(), SPV_ENV_WEBGPU_0); - ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, - ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("Capability Int16 is not allowed by WebGPU specification (or " - "requires extension)\n" - " OpCapability Int16\n")); -} - -TEST_F(ValidateData, webgpu_int32_good) { - std::string str = webgpu_header + R"( - OpEntryPoint Fragment %func "func" - OpExecutionMode %func OriginUpperLeft -%uint_t = OpTypeInt 32 0 - %void = OpTypeVoid -%func_t = OpTypeFunction %void - %func = OpFunction %void None %func_t - %1 = OpLabel - OpReturn - OpFunctionEnd -)"; - CompileSuccessfully(str.c_str(), SPV_ENV_WEBGPU_0); - ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); -} - TEST_F(ValidateData, int64_good) { std::string str = header_with_int64 + "%2 = OpTypeInt 64 1"; CompileSuccessfully(str.c_str()); @@ -379,18 +321,6 @@ TEST_F(ValidateData, int64_bad) { EXPECT_THAT(getDiagnosticString(), HasSubstr(missing_int64_cap_error)); } -TEST_F(ValidateData, webgpu_int64_bad) { - std::string str = WebGPUHeaderWith("Int64") + "%2 = OpTypeInt 64 1"; - CompileSuccessfully(str.c_str(), SPV_ENV_WEBGPU_0); - ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, - ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("Capability Int64 is not allowed by WebGPU specification (or " - "requires extension)\n" - " OpCapability Int64\n")); -} - // Number of bits in an integer may be only one of: {8,16,32,64} TEST_F(ValidateData, int_invalid_num_bits) { std::string str = header + "%2 = OpTypeInt 48 1"; @@ -418,34 +348,6 @@ TEST_F(ValidateData, float16_bad) { EXPECT_THAT(getDiagnosticString(), HasSubstr(missing_float16_cap_error)); } -TEST_F(ValidateData, webgpu_float16_bad) { - std::string str = WebGPUHeaderWith("Float16") + "%2 = OpTypeFloat 16"; - CompileSuccessfully(str.c_str(), SPV_ENV_WEBGPU_0); - ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, - ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("Capability Float16 is not allowed by WebGPU specification (or " - "requires extension)\n" - " OpCapability Float16\n")); -} - -TEST_F(ValidateData, webgpu_float32_good) { - std::string str = webgpu_header + R"( - OpEntryPoint Fragment %func "func" - OpExecutionMode %func OriginUpperLeft -%float_t = OpTypeFloat 32 - %void = OpTypeVoid - %func_t = OpTypeFunction %void - %func = OpFunction %void None %func_t - %1 = OpLabel - OpReturn - OpFunctionEnd -)"; - CompileSuccessfully(str.c_str(), SPV_ENV_WEBGPU_0); - ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); -} - TEST_F(ValidateData, float64_good) { std::string str = header_with_float64 + "%2 = OpTypeFloat 64"; CompileSuccessfully(str.c_str()); @@ -459,18 +361,6 @@ TEST_F(ValidateData, float64_bad) { EXPECT_THAT(getDiagnosticString(), HasSubstr(missing_float64_cap_error)); } -TEST_F(ValidateData, webgpu_float64_bad) { - std::string str = WebGPUHeaderWith("Float64") + "%2 = OpTypeFloat 64"; - CompileSuccessfully(str.c_str(), SPV_ENV_WEBGPU_0); - ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, - ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("Capability Float64 is not allowed by WebGPU specification (or " - "requires extension)\n" - " OpCapability Float64\n")); -} - // Number of bits in a float may be only one of: {16,32,64} TEST_F(ValidateData, float_invalid_num_bits) { std::string str = header + "%2 = OpTypeFloat 48"; @@ -882,68 +772,6 @@ TEST_F(ValidateData, vulkan_RTA_not_at_end_of_struct) { "OpTypeStruct %_runtimearr_uint %uint\n")); } -TEST_F(ValidateData, webgpu_RTA_array_at_end_of_struct) { - std::string str = R"( - OpCapability Shader - OpCapability VulkanMemoryModelKHR - OpExtension "SPV_KHR_vulkan_memory_model" - OpMemoryModel Logical VulkanKHR - OpEntryPoint Fragment %func "func" - OpExecutionMode %func OriginUpperLeft - OpDecorate %array_t ArrayStride 4 - OpMemberDecorate %struct_t 0 Offset 0 - OpMemberDecorate %struct_t 1 Offset 4 - OpDecorate %struct_t Block - %uint_t = OpTypeInt 32 0 - %array_t = OpTypeRuntimeArray %uint_t - %struct_t = OpTypeStruct %uint_t %array_t -%struct_ptr = OpTypePointer StorageBuffer %struct_t - %2 = OpVariable %struct_ptr StorageBuffer - %void = OpTypeVoid - %func_t = OpTypeFunction %void - %func = OpFunction %void None %func_t - %1 = OpLabel - OpReturn - OpFunctionEnd -)"; - - CompileSuccessfully(str.c_str(), SPV_ENV_WEBGPU_0); - ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); -} - -TEST_F(ValidateData, webgpu_RTA_not_at_end_of_struct) { - std::string str = R"( - OpCapability Shader - OpCapability VulkanMemoryModelKHR - OpExtension "SPV_KHR_vulkan_memory_model" - OpMemoryModel Logical VulkanKHR - OpEntryPoint Fragment %func "func" - OpExecutionMode %func OriginUpperLeft - OpDecorate %array_t ArrayStride 4 - OpMemberDecorate %struct_t 0 Offset 0 - OpMemberDecorate %struct_t 1 Offset 4 - OpDecorate %struct_t Block - %uint_t = OpTypeInt 32 0 - %array_t = OpTypeRuntimeArray %uint_t - %struct_t = OpTypeStruct %array_t %uint_t -%struct_ptr = OpTypePointer StorageBuffer %struct_t - %2 = OpVariable %struct_ptr StorageBuffer - %void = OpTypeVoid - %func_t = OpTypeFunction %void - %func = OpFunction %void None %func_t - %1 = OpLabel - OpReturn - OpFunctionEnd -)"; - - CompileSuccessfully(str.c_str(), SPV_ENV_WEBGPU_0); - ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("In WebGPU, OpTypeRuntimeArray must only be used for " - "the last member of an OpTypeStruct\n %_struct_3 = " - "OpTypeStruct %_runtimearr_uint %uint\n")); -} - TEST_F(ValidateData, TypeForwardReference) { std::string test = R"( OpCapability Shader diff --git a/test/val/val_decoration_test.cpp b/test/val/val_decoration_test.cpp index 1b68503d60..8fe1aa6c8a 100644 --- a/test/val/val_decoration_test.cpp +++ b/test/val/val_decoration_test.cpp @@ -42,8 +42,6 @@ struct TestResult { }; using ValidateDecorations = spvtest::ValidateBase; -using ValidateWebGPUCombineDecorationResult = - spvtest::ValidateBase>; using ValidateVulkanCombineDecorationResult = spvtest::ValidateBase>; @@ -165,44 +163,6 @@ TEST_F(ValidateDecorations, ValidateGroupDecorateRegistration) { EXPECT_THAT(vstate_->id_decorations(4), Eq(expected_decorations)); } -TEST_F(ValidateDecorations, WebGPUOpDecorationGroupBad) { - std::string spirv = R"( - OpCapability Shader - OpCapability VulkanMemoryModelKHR - OpExtension "SPV_KHR_vulkan_memory_model" - OpMemoryModel Logical VulkanKHR - OpDecorate %1 DescriptorSet 0 - OpDecorate %1 NonWritable - OpDecorate %1 Restrict - %1 = OpDecorationGroup - OpGroupDecorate %1 %2 %3 - OpGroupDecorate %1 %4 - %float = OpTypeFloat 32 -%_runtimearr_float = OpTypeRuntimeArray %float - %_struct_9 = OpTypeStruct %_runtimearr_float -%_ptr_Uniform__struct_9 = OpTypePointer Uniform %_struct_9 - %2 = OpVariable %_ptr_Uniform__struct_9 Uniform - %_struct_10 = OpTypeStruct %_runtimearr_float -%_ptr_Uniform__struct_10 = OpTypePointer Uniform %_struct_10 - %3 = OpVariable %_ptr_Uniform__struct_10 Uniform - %_struct_11 = OpTypeStruct %_runtimearr_float -%_ptr_Uniform__struct_11 = OpTypePointer Uniform %_struct_11 - %4 = OpVariable %_ptr_Uniform__struct_11 Uniform - )"; - CompileSuccessfully(spirv); - EXPECT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("OpDecorationGroup is not allowed in the WebGPU " - "execution environment.\n %1 = OpDecorationGroup\n")); -} - -// For WebGPU, OpGroupDecorate does not have a test case, because it requires -// being preceded by OpDecorationGroup, which will cause a validation error. - -// For WebGPU, OpGroupMemberDecorate does not have a test case, because it -// requires being preceded by OpDecorationGroup, which will cause a validation -// error. - TEST_F(ValidateDecorations, ValidateGroupMemberDecorateRegistration) { std::string spirv = R"( OpCapability Shader @@ -6390,67 +6350,6 @@ TEST_F(ValidateDecorations, NonWritableRuntimeArrayGood) { EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); } -TEST_P(ValidateWebGPUCombineDecorationResult, Decorate) { - const char* const decoration = std::get<0>(GetParam()); - const TestResult& test_result = std::get<1>(GetParam()); - - CodeGenerator generator = CodeGenerator::GetWebGPUShaderCodeGenerator(); - generator.before_types_ = "OpDecorate %u32 "; - generator.before_types_ += decoration; - generator.before_types_ += "\n"; - - EntryPoint entry_point; - entry_point.name = "main"; - entry_point.execution_model = "Vertex"; - generator.entry_points_.push_back(std::move(entry_point)); - - CompileSuccessfully(generator.Build(), SPV_ENV_WEBGPU_0); - ASSERT_EQ(test_result.validation_result, - ValidateInstructions(SPV_ENV_WEBGPU_0)); - if (test_result.error_str != "") { - EXPECT_THAT(getDiagnosticString(), HasSubstr(test_result.error_str)); - } -} - -TEST_P(ValidateWebGPUCombineDecorationResult, DecorateMember) { - const char* const decoration = std::get<0>(GetParam()); - const TestResult& test_result = std::get<1>(GetParam()); - - CodeGenerator generator = CodeGenerator::GetWebGPUShaderCodeGenerator(); - generator.before_types_ = "OpMemberDecorate %struct_type 0 "; - generator.before_types_ += decoration; - generator.before_types_ += "\n"; - - generator.after_types_ = "%struct_type = OpTypeStruct %u32\n"; - - EntryPoint entry_point; - entry_point.name = "main"; - entry_point.execution_model = "Vertex"; - generator.entry_points_.push_back(std::move(entry_point)); - - CompileSuccessfully(generator.Build(), SPV_ENV_WEBGPU_0); - ASSERT_EQ(test_result.validation_result, - ValidateInstructions(SPV_ENV_WEBGPU_0)); - if (!test_result.error_str.empty()) { - EXPECT_THAT(getDiagnosticString(), HasSubstr(test_result.error_str)); - } -} - -INSTANTIATE_TEST_SUITE_P( - DecorationCapabilityFailure, ValidateWebGPUCombineDecorationResult, - Combine(Values("CPacked", "Patch", "Sample", "Constant", - "SaturatedConversion", "NonUniformEXT"), - Values(TestResult(SPV_ERROR_INVALID_CAPABILITY, - "requires one of these capabilities")))); - -INSTANTIATE_TEST_SUITE_P( - DecorationAllowListFailure, ValidateWebGPUCombineDecorationResult, - Combine(Values("RelaxedPrecision", "BufferBlock", "GLSLShared", - "GLSLPacked", "Invariant", "Volatile", "Coherent"), - Values(TestResult( - SPV_ERROR_INVALID_ID, - "is not valid for the WebGPU execution environment.")))); - TEST_P(ValidateVulkanCombineDecorationResult, Decorate) { const char* const decoration = std::get<0>(GetParam()); const char* const vuid = std::get<1>(GetParam()); diff --git a/test/val/val_id_test.cpp b/test/val/val_id_test.cpp index ad8ebfc68f..c65d1715d5 100644 --- a/test/val/val_id_test.cpp +++ b/test/val/val_id_test.cpp @@ -954,31 +954,6 @@ TEST_P(OpTypeArrayLengthTest, LengthPositiveHugeEnding1InVulkan) { } } -TEST_P(OpTypeArrayLengthTest, LengthPositiveHugeEnding0InWebGPU) { - env_ = SPV_ENV_WEBGPU_0; - const int width = GetParam(); - // WebGPU only has 32 bit integers. - if (width != 32) return; - const int max_int_width = 32; - const auto module = CompileSuccessfully(MakeArrayLength( - big_num_ending_0(width), kUnsigned, width, max_int_width, true)); - EXPECT_EQ(SPV_SUCCESS, Val(module)); -} - -TEST_P(OpTypeArrayLengthTest, LengthPositiveHugeEnding1InWebGPU) { - env_ = SPV_ENV_WEBGPU_0; - const int width = GetParam(); - // WebGPU only has 32 bit integers. - if (width != 32) return; - const int max_int_width = 32; - const auto module = CompileSuccessfully(MakeArrayLength( - big_num_ending_1(width), kUnsigned, width, max_int_width, true)); - EXPECT_EQ(SPV_ERROR_INVALID_ID, - Val(module, - "OpTypeArray Length '3\\[%.*\\]' size exceeds max value " - "2147483648 permitted by WebGPU: got 2147483649")); -} - // The only valid widths for integers are 8, 16, 32, and 64. // Since the Int8 capability requires the Kernel capability, and the Kernel // capability prohibits usage of signed integers, we can skip 8-bit integers @@ -4731,39 +4706,6 @@ TEST_F(ValidateIdWithMessage, OpVectorShuffleLiterals) { "size of 5.")); } -TEST_F(ValidateIdWithMessage, WebGPUOpVectorShuffle0xFFFFFFFFLiteralBad) { - std::string spirv = R"( - OpCapability Shader - OpCapability VulkanMemoryModelKHR - OpExtension "SPV_KHR_vulkan_memory_model" - OpMemoryModel Logical VulkanKHR -%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 diff --git a/test/val/val_image_test.cpp b/test/val/val_image_test.cpp index dc09321391..bcee6231cb 100644 --- a/test/val/val_image_test.cpp +++ b/test/val/val_image_test.cpp @@ -454,26 +454,6 @@ std::string TrivialMain() { )"; } -std::string GetWebGPUShaderHeader() { - return R"( - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint GLCompute %main "main" - OpExecutionMode %main LocalSize 1 1 1 - %void = OpTypeVoid - %func = OpTypeFunction %void - %f32 = OpTypeFloat 32 - %u32 = OpTypeInt 32 0 - %f32vec2 = OpTypeVector %f32 2 - %f32vec3 = OpTypeVector %f32 3 - %f32vec4 = OpTypeVector %f32 4 - %u32vec2 = OpTypeVector %u32 2 - %u32vec3 = OpTypeVector %u32 3 - %u32vec4 = OpTypeVector %u32 4 - %u32vec2null = OpConstantNull %u32vec2 - )"; -} - std::string GetShaderHeader(const std::string& capabilities_and_extensions = "", bool include_entry_point = true) { std::ostringstream ss; @@ -833,37 +813,6 @@ TEST_F(ValidateImage, TypeImage_Vulkan_Sampled0_Invalid) { HasSubstr("Sampled must be 1 or 2 in the Vulkan environment.")); } -TEST_F(ValidateImage, TypeImage_WebGPU_Sampled1_OK) { - const std::string code = GetWebGPUShaderHeader() + R"( -%img_type = OpTypeImage %f32 2D 0 0 0 1 Unknown -)" + TrivialMain(); - - CompileSuccessfully(code.c_str()); - ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), Eq("")); -} - -TEST_F(ValidateImage, TypeImage_WebGPU_Sampled2_OK) { - const std::string code = GetWebGPUShaderHeader() + R"( -%img_type = OpTypeImage %f32 2D 0 0 0 2 Rgba32f -)" + TrivialMain(); - - CompileSuccessfully(code.c_str()); - ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), Eq("")); -} - -TEST_F(ValidateImage, TypeImage_WebGPU_Sampled0_Invalid) { - const std::string code = GetWebGPUShaderHeader() + R"( -%img_type = OpTypeImage %f32 2D 0 0 0 0 Unknown -)" + TrivialMain(); - - CompileSuccessfully(code.c_str()); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("Sampled must be 1 or 2 in the WebGPU environment.")); -} - TEST_F(ValidateImage, TypeImageWrongFormatForSubpassData) { const std::string code = GetShaderHeader("OpCapability InputAttachment\n", false) + @@ -3322,26 +3271,6 @@ TEST_F(ValidateImage, ReadWrongNumComponentsResultType_Vulkan) { HasSubstr("Expected Result Type to have 4 components")); } -TEST_F(ValidateImage, ReadWrongNumComponentsResultType_WebGPU) { - const std::string code = GetWebGPUShaderHeader() + R"( -%img_type = OpTypeImage %f32 2D 0 0 0 2 Unknown -%ptr_type = OpTypePointer UniformConstant %img_type -%var = OpVariable %ptr_type UniformConstant -%main = OpFunction %void None %func -%entry = OpLabel -%img = OpLoad %img_type %var -%res1 = OpImageRead %u32vec3 %img %u32vec2null -OpReturn -OpFunctionEnd -)"; - - CompileSuccessfully(code.c_str()); - ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0)) - << getDiagnosticString(); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("Expected Result Type to have 4 components")); -} - TEST_F(ValidateImage, ReadNotImage) { const std::string body = R"( %sampler = OpLoad %type_sampler %uniform_sampler diff --git a/test/val/val_layout_test.cpp b/test/val/val_layout_test.cpp index 43fa0469b5..d34c97f9cf 100644 --- a/test/val/val_layout_test.cpp +++ b/test/val/val_layout_test.cpp @@ -667,57 +667,6 @@ TEST_F(ValidateLayout, ModuleProcessedInvalidInBasicBlock) { HasSubstr("ModuleProcessed cannot appear in a function declaration")); } -TEST_F(ValidateLayout, WebGPUCallerBeforeCalleeBad) { - char str[] = R"( - OpCapability Shader - OpCapability VulkanMemoryModelKHR - OpExtension "SPV_KHR_vulkan_memory_model" - OpMemoryModel Logical VulkanKHR - OpEntryPoint GLCompute %main "main" -%void = OpTypeVoid -%voidfn = OpTypeFunction %void -%main = OpFunction %void None %voidfn -%1 = OpLabel -%2 = OpFunctionCall %void %callee - OpReturn - OpFunctionEnd -%callee = OpFunction %void None %voidfn -%3 = OpLabel - OpReturn - OpFunctionEnd -)"; - - CompileSuccessfully(str, SPV_ENV_WEBGPU_0); - ASSERT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("For WebGPU, functions need to be defined before being " - "called.\n %5 = OpFunctionCall %void %6\n")); -} - -TEST_F(ValidateLayout, WebGPUCalleeBeforeCallerGood) { - char str[] = R"( - OpCapability Shader - OpCapability VulkanMemoryModelKHR - OpExtension "SPV_KHR_vulkan_memory_model" - OpMemoryModel Logical VulkanKHR - OpEntryPoint GLCompute %main "main" -%void = OpTypeVoid -%voidfn = OpTypeFunction %void -%callee = OpFunction %void None %voidfn -%3 = OpLabel - OpReturn - OpFunctionEnd -%main = OpFunction %void None %voidfn -%1 = OpLabel -%2 = OpFunctionCall %void %callee - OpReturn - OpFunctionEnd -)"; - - CompileSuccessfully(str, SPV_ENV_WEBGPU_0); - ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); -} - // TODO(umar): Test optional instructions } // namespace diff --git a/test/val/val_memory_test.cpp b/test/val/val_memory_test.cpp index 6d6b8983f2..8142f859a3 100644 --- a/test/val/val_memory_test.cpp +++ b/test/val/val_memory_test.cpp @@ -362,192 +362,6 @@ OpFunctionEnd EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); } -TEST_F(ValidateMemory, WebGPUInitializerWithOutputStorageClassesGood) { - std::string spirv = R"( -OpCapability Shader -OpCapability VulkanMemoryModelKHR -OpExtension "SPV_KHR_vulkan_memory_model" -OpMemoryModel Logical VulkanKHR -OpEntryPoint Fragment %func "func" -OpExecutionMode %func OriginUpperLeft -%float = OpTypeFloat 32 -%float_ptr = OpTypePointer Output %float -%init_val = OpConstant %float 1.0 -%1 = OpVariable %float_ptr Output %init_val -%void = OpTypeVoid -%functy = OpTypeFunction %void -%func = OpFunction %void None %functy -%2 = OpLabel -OpReturn -OpFunctionEnd -)"; - CompileSuccessfully(spirv.c_str(), SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); -} - -TEST_F(ValidateMemory, WebGPUInitializerWithFunctionStorageClassesGood) { - std::string spirv = R"( -OpCapability Shader -OpCapability VulkanMemoryModelKHR -OpExtension "SPV_KHR_vulkan_memory_model" -OpMemoryModel Logical VulkanKHR -OpEntryPoint Fragment %func "func" -OpExecutionMode %func OriginUpperLeft -%float = OpTypeFloat 32 -%float_ptr = OpTypePointer Function %float -%init_val = OpConstant %float 1.0 -%void = OpTypeVoid -%functy = OpTypeFunction %void -%func = OpFunction %void None %functy -%1 = OpLabel -%2 = OpVariable %float_ptr Function %init_val -OpReturn -OpFunctionEnd -)"; - CompileSuccessfully(spirv.c_str(), SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); -} - -TEST_F(ValidateMemory, WebGPUInitializerWithPrivateStorageClassesGood) { - std::string spirv = R"( -OpCapability Shader -OpCapability VulkanMemoryModelKHR -OpExtension "SPV_KHR_vulkan_memory_model" -OpMemoryModel Logical VulkanKHR -OpEntryPoint Fragment %func "func" -OpExecutionMode %func OriginUpperLeft -%float = OpTypeFloat 32 -%float_ptr = OpTypePointer Private %float -%init_val = OpConstant %float 1.0 -%1 = OpVariable %float_ptr Private %init_val -%void = OpTypeVoid -%functy = OpTypeFunction %void -%func = OpFunction %void None %functy -%2 = OpLabel -OpReturn -OpFunctionEnd -)"; - CompileSuccessfully(spirv.c_str(), SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); -} - -TEST_F(ValidateMemory, WebGPUInitializerWithDisallowedStorageClassesBad) { - std::string spirv = R"( -OpCapability Shader -OpCapability VulkanMemoryModelKHR -OpExtension "SPV_KHR_vulkan_memory_model" -OpMemoryModel Logical VulkanKHR -OpEntryPoint Fragment %func "func" -OpExecutionMode %func OriginUpperLeft -%float = OpTypeFloat 32 -%float_ptr = OpTypePointer Uniform %float -%init_val = OpConstant %float 1.0 -%1 = OpVariable %float_ptr Uniform %init_val -%void = OpTypeVoid -%functy = OpTypeFunction %void -%func = OpFunction %void None %functy -%2 = OpLabel -OpReturn -OpFunctionEnd -)"; - CompileSuccessfully(spirv.c_str(), SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("OpVariable, '5[%5]', has a disallowed initializer & " - "storage class combination.\nFrom WebGPU spec:\nVariable " - "declarations that include initializers must have one of the " - "following storage classes: Output, Private, or Function\n %5 " - "= OpVariable %_ptr_Uniform_float Uniform %float_1\n")); -} - -TEST_F(ValidateMemory, WebGPUOutputStorageClassWithoutInitializerBad) { - std::string spirv = R"( -OpCapability Shader -OpCapability VulkanMemoryModelKHR -OpExtension "SPV_KHR_vulkan_memory_model" -OpMemoryModel Logical VulkanKHR -OpEntryPoint Fragment %func "func" -OpExecutionMode %func OriginUpperLeft -%float = OpTypeFloat 32 -%float_ptr = OpTypePointer Output %float -%1 = OpVariable %float_ptr Output -%void = OpTypeVoid -%functy = OpTypeFunction %void -%func = OpFunction %void None %functy -%2 = OpLabel -OpReturn -OpFunctionEnd -)"; - CompileSuccessfully(spirv.c_str(), SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("OpVariable, '4[%4]', must have an initializer.\n" - "From WebGPU execution environment spec:\n" - "All variables in the following storage classes must have an " - "initializer: Output, Private, or Function\n" - " %4 = OpVariable %_ptr_Output_float Output\n")); -} - -TEST_F(ValidateMemory, WebGPUFunctionStorageClassWithoutInitializerBad) { - std::string spirv = R"( -OpCapability Shader -OpCapability VulkanMemoryModelKHR -OpExtension "SPV_KHR_vulkan_memory_model" -OpMemoryModel Logical VulkanKHR -OpEntryPoint Fragment %func "func" -OpExecutionMode %func OriginUpperLeft -%float = OpTypeFloat 32 -%float_ptr = OpTypePointer Function %float -%void = OpTypeVoid -%functy = OpTypeFunction %void -%func = OpFunction %void None %functy -%1 = OpLabel -%2 = OpVariable %float_ptr Function -OpReturn -OpFunctionEnd -)"; - CompileSuccessfully(spirv.c_str(), SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("OpVariable, '7[%7]', must have an initializer.\n" - "From WebGPU execution environment spec:\n" - "All variables in the following storage classes must have an " - "initializer: Output, Private, or Function\n" - " %7 = OpVariable %_ptr_Function_float Function\n")); -} - -TEST_F(ValidateMemory, WebGPUPrivateStorageClassWithoutInitializerBad) { - std::string spirv = R"( -OpCapability Shader -OpCapability VulkanMemoryModelKHR -OpExtension "SPV_KHR_vulkan_memory_model" -OpMemoryModel Logical VulkanKHR -OpEntryPoint Fragment %func "func" -OpExecutionMode %func OriginUpperLeft -%float = OpTypeFloat 32 -%float_ptr = OpTypePointer Private %float -%1 = OpVariable %float_ptr Private -%void = OpTypeVoid -%functy = OpTypeFunction %void -%func = OpFunction %void None %functy -%2 = OpLabel -OpReturn -OpFunctionEnd -)"; - CompileSuccessfully(spirv.c_str(), SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("OpVariable, '4[%4]', must have an initializer.\n" - "From WebGPU execution environment spec:\n" - "All variables in the following storage classes must have an " - "initializer: Output, Private, or Function\n" - " %4 = OpVariable %_ptr_Private_float Private\n")); -} - TEST_F(ValidateMemory, VulkanInitializerWithOutputStorageClassesGood) { std::string spirv = R"( OpCapability Shader @@ -2282,38 +2096,6 @@ OpFunctionEnd "%_ptr_UniformConstant__runtimearr_2 UniformConstant\n")); } -TEST_F(ValidateMemory, WebGPURTAOutsideOfStructBad) { - std::string spirv = R"( -OpCapability Shader -OpCapability VulkanMemoryModelKHR -OpExtension "SPV_KHR_vulkan_memory_model" -OpMemoryModel Logical VulkanKHR -OpEntryPoint Fragment %func "func" -OpExecutionMode %func OriginUpperLeft -%sampler_t = OpTypeSampler -%array_t = OpTypeRuntimeArray %sampler_t -%array_ptr = OpTypePointer UniformConstant %array_t -%2 = OpVariable %array_ptr UniformConstant -%void = OpTypeVoid -%func_t = OpTypeFunction %void -%func = OpFunction %void None %func_t -%1 = OpLabel -OpReturn -OpFunctionEnd -)"; - - CompileSuccessfully(spirv.c_str(), SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr( - "OpVariable, '5[%5]', is attempting to create memory for an " - "illegal type, OpTypeRuntimeArray.\nFor WebGPU OpTypeRuntimeArray " - "can only appear as the final member of an OpTypeStruct, thus cannot " - "be instantiated via OpVariable\n %5 = OpVariable " - "%_ptr_UniformConstant__runtimearr_2 UniformConstant\n")); -} - TEST_F(ValidateMemory, VulkanRTAOutsideOfStructWithRuntimeDescriptorArrayGood) { std::string spirv = R"( OpCapability Shader @@ -2403,34 +2185,6 @@ OpFunctionEnd EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1)); } -TEST_F(ValidateMemory, WebGPURTAInsideStorageBufferStructGood) { - std::string spirv = R"( -OpCapability Shader -OpCapability VulkanMemoryModelKHR -OpExtension "SPV_KHR_vulkan_memory_model" -OpMemoryModel Logical VulkanKHR -OpEntryPoint Fragment %func "func" -OpExecutionMode %func OriginUpperLeft -OpDecorate %array_t ArrayStride 4 -OpMemberDecorate %struct_t 0 Offset 0 -OpDecorate %struct_t Block -%uint_t = OpTypeInt 32 0 -%array_t = OpTypeRuntimeArray %uint_t -%struct_t = OpTypeStruct %array_t -%struct_ptr = OpTypePointer StorageBuffer %struct_t -%2 = OpVariable %struct_ptr StorageBuffer -%void = OpTypeVoid -%func_t = OpTypeFunction %void -%func = OpFunction %void None %func_t -%1 = OpLabel -OpReturn -OpFunctionEnd -)"; - - CompileSuccessfully(spirv.c_str(), SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); -} - TEST_F(ValidateMemory, VulkanRTAInsideWrongStorageClassStructBad) { std::string spirv = R"( OpCapability Shader @@ -2460,36 +2214,6 @@ OpFunctionEnd "OpVariable %_ptr_Workgroup__struct_4 Workgroup\n")); } -TEST_F(ValidateMemory, WebGPURTAInsideWrongStorageClassStructBad) { - std::string spirv = R"( -OpCapability Shader -OpCapability VulkanMemoryModelKHR -OpExtension "SPV_KHR_vulkan_memory_model" -OpMemoryModel Logical VulkanKHR -OpEntryPoint Fragment %func "func" -OpExecutionMode %func OriginUpperLeft -%uint_t = OpTypeInt 32 0 -%array_t = OpTypeRuntimeArray %uint_t -%struct_t = OpTypeStruct %array_t -%struct_ptr = OpTypePointer Workgroup %struct_t -%2 = OpVariable %struct_ptr Workgroup -%void = OpTypeVoid -%func_t = OpTypeFunction %void -%func = OpFunction %void None %func_t -%1 = OpLabel -OpReturn -OpFunctionEnd -)"; - - CompileSuccessfully(spirv.c_str(), SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("For WebGPU, OpTypeStruct variables containing " - "OpTypeRuntimeArray must have storage class of StorageBuffer\n " - " %6 = OpVariable %_ptr_Workgroup__struct_4 Workgroup\n")); -} - TEST_F(ValidateMemory, VulkanRTAInsideStorageBufferStructWithoutBlockBad) { std::string spirv = R"( OpCapability Shader @@ -2518,36 +2242,6 @@ OpFunctionEnd "%_ptr_StorageBuffer__struct_4 StorageBuffer\n")); } -TEST_F(ValidateMemory, WebGPURTAInsideStorageBufferStructWithoutBlockBad) { - std::string spirv = R"( -OpCapability Shader -OpCapability VulkanMemoryModelKHR -OpExtension "SPV_KHR_vulkan_memory_model" -OpMemoryModel Logical VulkanKHR -OpEntryPoint Fragment %func "func" -OpExecutionMode %func OriginUpperLeft -%uint_t = OpTypeInt 32 0 -%array_t = OpTypeRuntimeArray %uint_t -%struct_t = OpTypeStruct %array_t -%struct_ptr = OpTypePointer StorageBuffer %struct_t -%2 = OpVariable %struct_ptr StorageBuffer -%void = OpTypeVoid -%func_t = OpTypeFunction %void -%func = OpFunction %void None %func_t -%1 = OpLabel -OpReturn -OpFunctionEnd -)"; - - CompileSuccessfully(spirv.c_str(), SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("For WebGPU, an OpTypeStruct variable containing an " - "OpTypeRuntimeArray must be decorated with Block if it " - "has storage class StorageBuffer.\n %6 = OpVariable " - "%_ptr_StorageBuffer__struct_4 StorageBuffer\n")); -} - TEST_F(ValidateMemory, VulkanRTAInsideUniformStructGood) { std::string spirv = R"( OpCapability Shader @@ -2574,39 +2268,6 @@ OpFunctionEnd EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1)); } -TEST_F(ValidateMemory, WebGPURTAInsideUniformStructBad) { - std::string spirv = R"( -OpCapability Shader -OpCapability VulkanMemoryModelKHR -OpExtension "SPV_KHR_vulkan_memory_model" -OpMemoryModel Logical VulkanKHR -OpEntryPoint Fragment %func "func" -OpExecutionMode %func OriginUpperLeft -OpDecorate %array_t ArrayStride 4 -OpMemberDecorate %struct_t 0 Offset 0 -OpDecorate %struct_t Block -%uint_t = OpTypeInt 32 0 -%array_t = OpTypeRuntimeArray %uint_t -%struct_t = OpTypeStruct %array_t -%struct_ptr = OpTypePointer Uniform %struct_t -%2 = OpVariable %struct_ptr Uniform -%void = OpTypeVoid -%func_t = OpTypeFunction %void -%func = OpFunction %void None %func_t -%1 = OpLabel -OpReturn -OpFunctionEnd -)"; - - CompileSuccessfully(spirv.c_str(), SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("For WebGPU, OpTypeStruct variables containing " - "OpTypeRuntimeArray must have storage class of StorageBuffer\n " - " %6 = OpVariable %_ptr_Uniform__struct_3 Uniform\n")); -} - TEST_F(ValidateMemory, VulkanRTAInsideUniformStructWithoutBufferBlockBad) { std::string spirv = R"( OpCapability Shader @@ -2664,37 +2325,6 @@ OpFunctionEnd "OpTypeRuntimeArray %_runtimearr_2\n")); } -TEST_F(ValidateMemory, WebGPURTAInsideRTABad) { - std::string spirv = R"( -OpCapability Shader -OpCapability VulkanMemoryModelKHR -OpExtension "SPV_KHR_vulkan_memory_model" -OpMemoryModel Logical VulkanKHR -OpEntryPoint Fragment %func "func" -OpExecutionMode %func OriginUpperLeft -%sampler_t = OpTypeSampler -%inner_array_t = OpTypeRuntimeArray %sampler_t -%array_t = OpTypeRuntimeArray %inner_array_t -%array_ptr = OpTypePointer UniformConstant %array_t -%2 = OpVariable %array_ptr UniformConstant -%void = OpTypeVoid -%func_t = OpTypeFunction %void -%func = OpFunction %void None %func_t -%1 = OpLabel -OpReturn -OpFunctionEnd -)"; - - CompileSuccessfully(spirv.c_str(), SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr( - "OpTypeRuntimeArray Element Type '3[%_runtimearr_2]' is not " - "valid in WebGPU environments.\n %_runtimearr__runtimearr_2 = " - "OpTypeRuntimeArray %_runtimearr_2\n")); -} - TEST_F(ValidateMemory, VulkanRTAInsideRTAWithRuntimeDescriptorArrayBad) { std::string spirv = R"( OpCapability RuntimeDescriptorArrayEXT @@ -2855,38 +2485,6 @@ OpFunctionEnd "OpTypeArray %_runtimearr_4 %uint_1\n")); } -TEST_F(ValidateMemory, WebGPURTAInsideArrayBad) { - std::string spirv = R"( -OpCapability Shader -OpCapability VulkanMemoryModelKHR -OpExtension "SPV_KHR_vulkan_memory_model" -OpMemoryModel Logical VulkanKHR -OpEntryPoint Fragment %func "func" -OpExecutionMode %func OriginUpperLeft -%uint_t = OpTypeInt 32 0 -%dim = OpConstant %uint_t 1 -%sampler_t = OpTypeSampler -%inner_array_t = OpTypeRuntimeArray %sampler_t -%array_t = OpTypeArray %inner_array_t %dim -%array_ptr = OpTypePointer UniformConstant %array_t -%2 = OpVariable %array_ptr UniformConstant -%void = OpTypeVoid -%func_t = OpTypeFunction %void -%func = OpFunction %void None %func_t -%1 = OpLabel -OpReturn -OpFunctionEnd -)"; - - CompileSuccessfully(spirv.c_str(), SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("OpTypeArray Element Type '5[%_runtimearr_4]' is not " - "valid in WebGPU environments.\n %_arr__runtimearr_4_uint_1 = " - "OpTypeArray %_runtimearr_4 %uint_1\n")); -} - TEST_F(ValidateMemory, VulkanRTAInsideArrayWithRuntimeDescriptorArrayBad) { std::string spirv = R"( OpCapability RuntimeDescriptorArrayEXT diff --git a/test/val/val_modes_test.cpp b/test/val/val_modes_test.cpp index 7980c9374e..7b2315945b 100644 --- a/test/val/val_modes_test.cpp +++ b/test/val/val_modes_test.cpp @@ -535,24 +535,16 @@ TEST_P(ValidateModeExecution, ExecutionMode) { std::ostringstream sstr; sstr << "OpCapability Shader\n"; - if (!spvIsWebGPUEnv(env)) { - sstr << "OpCapability Geometry\n"; - sstr << "OpCapability Tessellation\n"; - sstr << "OpCapability TransformFeedback\n"; - } - if (!spvIsVulkanOrWebGPUEnv(env)) { + sstr << "OpCapability Geometry\n"; + sstr << "OpCapability Tessellation\n"; + sstr << "OpCapability TransformFeedback\n"; + if (!spvIsVulkanEnv(env)) { sstr << "OpCapability Kernel\n"; if (env == SPV_ENV_UNIVERSAL_1_3) { sstr << "OpCapability SubgroupDispatch\n"; } } - if (spvIsWebGPUEnv(env)) { - sstr << "OpCapability VulkanMemoryModelKHR\n"; - sstr << "OpExtension \"SPV_KHR_vulkan_memory_model\"\n"; - sstr << "OpMemoryModel Logical VulkanKHR\n"; - } else { - sstr << "OpMemoryModel Logical GLSL450\n"; - } + sstr << "OpMemoryModel Logical GLSL450\n"; sstr << "OpEntryPoint " << model << " %main \"main\"\n"; if (mode.find("LocalSizeId") == 0 || mode.find("LocalSizeHintId") == 0 || mode.find("SubgroupsPerWorkgroupId") == 0) { @@ -718,39 +710,6 @@ INSTANTIATE_TEST_SUITE_P( "SubgroupsPerWorkgroup 1", "SubgroupsPerWorkgroupId %int1"), Values(SPV_ENV_UNIVERSAL_1_3))); -INSTANTIATE_TEST_SUITE_P(ValidateModeGLComputeWebGPUAllowListGood, - ValidateModeExecution, - Combine(Values(SPV_SUCCESS), Values(""), - Values("GLCompute"), Values("LocalSize 1 1 1"), - Values(SPV_ENV_WEBGPU_0))); - -INSTANTIATE_TEST_SUITE_P( - ValidateModeGLComputeWebGPUAllowListBad, ValidateModeExecution, - Combine(Values(SPV_ERROR_INVALID_DATA), - Values("Execution mode must be one of OriginUpperLeft, " - "DepthReplacing, DepthGreater, DepthLess, DepthUnchanged, " - "LocalSize, or LocalSizeHint for WebGPU environment"), - Values("GLCompute"), Values("LocalSizeId %int1 %int1 %int1"), - Values(SPV_ENV_WEBGPU_0))); - -INSTANTIATE_TEST_SUITE_P( - ValidateModeFragmentWebGPUAllowListGood, ValidateModeExecution, - Combine(Values(SPV_SUCCESS), Values(""), Values("Fragment"), - Values("OriginUpperLeft", "DepthReplacing", "DepthGreater", - "DepthLess", "DepthUnchanged"), - Values(SPV_ENV_WEBGPU_0))); - -INSTANTIATE_TEST_SUITE_P( - ValidateModeFragmentWebGPUAllowListBad, ValidateModeExecution, - Combine(Values(SPV_ERROR_INVALID_DATA), - Values("Execution mode must be one of OriginUpperLeft, " - "DepthReplacing, DepthGreater, DepthLess, DepthUnchanged, " - "LocalSize, or LocalSizeHint for WebGPU environment"), - Values("Fragment"), - Values("PixelCenterInteger", "OriginLowerLeft", - "EarlyFragmentTests"), - Values(SPV_ENV_WEBGPU_0))); - TEST_F(ValidateModeExecution, MeshNVLocalSize) { const std::string spirv = R"( OpCapability Shader diff --git a/test/val/val_storage_test.cpp b/test/val/val_storage_test.cpp index fe37a93c6d..e6f98bfff5 100644 --- a/test/val/val_storage_test.cpp +++ b/test/val/val_storage_test.cpp @@ -250,70 +250,6 @@ TEST_F(ValidateStorage, RelaxedLogicalPointerFunctionParamBad) { HasSubstr("OpFunctionCall Argument '")); } -std::string GetVarDeclStr(const std::string& storage_class) { - if (storage_class != "Output" && storage_class != "Private" && - storage_class != "Function") { - return "%var = OpVariable %ptrt " + storage_class + "\n"; - } else { - return "%var = OpVariable %ptrt " + storage_class + " %null\n"; - } -} - -TEST_P(ValidateStorageClass, WebGPU) { - std::string storage_class = std::get<0>(GetParam()); - bool is_local = std::get<1>(GetParam()); - bool is_valid = std::get<2>(GetParam()); - std::string error = std::get<3>(GetParam()); - - std::string str = R"( - OpCapability Shader - OpCapability VulkanMemoryModelKHR - OpExtension "SPV_KHR_vulkan_memory_model" - OpMemoryModel Logical VulkanKHR - OpEntryPoint Fragment %func "func" - OpExecutionMode %func OriginUpperLeft -%intt = OpTypeInt 32 1 -%voidt = OpTypeVoid -%vfunct = OpTypeFunction %voidt -%null = OpConstantNull %intt -)"; - str += "%ptrt = OpTypePointer " + storage_class + " %intt\n"; - if (!is_local) str += GetVarDeclStr(storage_class); - str += R"( -%func = OpFunction %voidt None %vfunct -%funcl = OpLabel -)"; - if (is_local) str += GetVarDeclStr(storage_class); - str += R"( -OpReturn -OpFunctionEnd -)"; - - CompileSuccessfully(str, SPV_ENV_WEBGPU_0); - if (is_valid) { - ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); - } else { - ASSERT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), HasSubstr(error)); - } -} - -INSTANTIATE_TEST_SUITE_P( - StorageClass, ValidateStorageClass, - Values(std::make_tuple("UniformConstant", false, true, ""), - std::make_tuple("Uniform", false, true, ""), - std::make_tuple("StorageBuffer", false, true, ""), - std::make_tuple("Input", false, true, ""), - std::make_tuple("Output", false, true, ""), - std::make_tuple("Image", false, true, ""), - std::make_tuple("Workgroup", false, true, ""), - std::make_tuple("Private", false, true, ""), - std::make_tuple("Function", true, true, ""), - std::make_tuple("CrossWorkgroup", false, false, - "Invalid storage class for target environment"), - std::make_tuple("PushConstant", false, false, - "Invalid storage class for target environment"))); - } // namespace } // namespace val } // namespace spvtools diff --git a/test/val/val_validation_state_test.cpp b/test/val/val_validation_state_test.cpp index 458157902e..7a38d3a162 100644 --- a/test/val/val_validation_state_test.cpp +++ b/test/val/val_validation_state_test.cpp @@ -245,12 +245,6 @@ TEST_F(ValidationStateTest, CheckVulkanNonRecursiveBodyGood) { ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1)); } -TEST_F(ValidationStateTest, CheckWebGPUNonRecursiveBodyGood) { - std::string spirv = std::string(kVulkanMemoryHeader) + kNonRecursiveBody; - CompileSuccessfully(spirv, SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(SPV_ENV_WEBGPU_0)); -} - TEST_F(ValidationStateTest, CheckDirectlyRecursiveBodyGood) { std::string spirv = std::string(kHeader) + kDirectlyRecursiveBody; CompileSuccessfully(spirv); @@ -267,16 +261,6 @@ TEST_F(ValidationStateTest, CheckVulkanDirectlyRecursiveBodyBad) { " %1 = OpFunction %void Pure|Const %3\n")); } -TEST_F(ValidationStateTest, CheckWebGPUDirectlyRecursiveBodyBad) { - std::string spirv = std::string(kVulkanMemoryHeader) + kDirectlyRecursiveBody; - CompileSuccessfully(spirv, SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_ERROR_INVALID_BINARY, - ValidateAndRetrieveValidationState(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("Entry points may not have a call graph with cycles.\n " - " %1 = OpFunction %void Pure|Const %3\n")); -} - TEST_F(ValidationStateTest, CheckIndirectlyRecursiveBodyGood) { std::string spirv = std::string(kHeader) + kIndirectlyRecursiveBody; CompileSuccessfully(spirv); @@ -294,68 +278,6 @@ TEST_F(ValidationStateTest, CheckVulkanIndirectlyRecursiveBodyBad) { " %1 = OpFunction %void Pure|Const %3\n")); } -// Indirectly recursive functions are caught by the function definition layout -// rules, because they cause a situation where there are 2 functions that have -// to be before each other, and layout is checked earlier. -TEST_F(ValidationStateTest, CheckWebGPUIndirectlyRecursiveBodyBad) { - std::string spirv = - std::string(kVulkanMemoryHeader) + kIndirectlyRecursiveBody; - CompileSuccessfully(spirv, SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_ERROR_INVALID_LAYOUT, - ValidateAndRetrieveValidationState(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("For WebGPU, functions need to be defined before being " - "called.\n %10 = OpFunctionCall %_struct_5 %11\n")); -} - -TEST_F(ValidationStateTest, - CheckWebGPUDuplicateEntryNamesDifferentFunctionsBad) { - std::string spirv = std::string(kVulkanMemoryHeader) + R"( -OpEntryPoint Fragment %func_1 "main" -OpEntryPoint Vertex %func_2 "main" -OpExecutionMode %func_1 OriginUpperLeft -%void = OpTypeVoid -%void_f = OpTypeFunction %void -%func_1 = OpFunction %void None %void_f -%label_1 = OpLabel - OpReturn - OpFunctionEnd -%func_2 = OpFunction %void None %void_f -%label_2 = OpLabel - OpReturn - OpFunctionEnd -)"; - - CompileSuccessfully(spirv, SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_ERROR_INVALID_BINARY, - ValidateAndRetrieveValidationState(SPV_ENV_WEBGPU_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("Entry point name \"main\" is not unique, which is not allow " - "in WebGPU env.\n %1 = OpFunction %void None %4\n")); -} - -TEST_F(ValidationStateTest, CheckWebGPUDuplicateEntryNamesSameFunctionBad) { - std::string spirv = std::string(kVulkanMemoryHeader) + R"( -OpEntryPoint GLCompute %func_1 "main" -OpEntryPoint Vertex %func_1 "main" -%void = OpTypeVoid -%void_f = OpTypeFunction %void -%func_1 = OpFunction %void None %void_f -%label_1 = OpLabel - OpReturn - OpFunctionEnd -)"; - - CompileSuccessfully(spirv, SPV_ENV_WEBGPU_0); - EXPECT_EQ(SPV_ERROR_INVALID_BINARY, - ValidateAndRetrieveValidationState(SPV_ENV_WEBGPU_0)); - EXPECT_THAT( - getDiagnosticString(), - HasSubstr("Entry point name \"main\" is not unique, which is not allow " - "in WebGPU env.\n %1 = OpFunction %void None %3\n")); -} - } // namespace } // namespace val } // namespace spvtools diff --git a/test/val/val_version_test.cpp b/test/val/val_version_test.cpp index 2b9542a126..98565ddb8b 100644 --- a/test/val/val_version_test.cpp +++ b/test/val/val_version_test.cpp @@ -40,21 +40,6 @@ OpReturn OpFunctionEnd )"; -const std::string webgpu_spirv = R"( -OpCapability Shader -OpCapability VulkanMemoryModelKHR -OpExtension "SPV_KHR_vulkan_memory_model" -OpMemoryModel Logical VulkanKHR -OpEntryPoint Fragment %func "func" -OpExecutionMode %func OriginUpperLeft -%void = OpTypeVoid -%functy = OpTypeFunction %void -%func = OpFunction %void None %functy -%1 = OpLabel -OpReturn -OpFunctionEnd -)"; - const std::string opencl_spirv = R"( OpCapability Addresses OpCapability Kernel @@ -85,7 +70,6 @@ std::string version(spv_target_env env) { return "1.2"; case SPV_ENV_UNIVERSAL_1_3: case SPV_ENV_VULKAN_1_1: - case SPV_ENV_WEBGPU_0: return "1.3"; case SPV_ENV_UNIVERSAL_1_4: case SPV_ENV_VULKAN_1_1_SPIRV_1_4: @@ -126,7 +110,6 @@ INSTANTIATE_TEST_SUITE_P(Universal, ValidateVersion, std::make_tuple(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_OPENGL_4_2, vulkan_spirv, true), std::make_tuple(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_OPENGL_4_3, vulkan_spirv, true), std::make_tuple(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_OPENGL_4_5, vulkan_spirv, true), - std::make_tuple(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_WEBGPU_0, webgpu_spirv, true), std::make_tuple(SPV_ENV_UNIVERSAL_1_1, SPV_ENV_UNIVERSAL_1_0, vulkan_spirv, false), std::make_tuple(SPV_ENV_UNIVERSAL_1_1, SPV_ENV_UNIVERSAL_1_1, vulkan_spirv, true), @@ -139,7 +122,6 @@ INSTANTIATE_TEST_SUITE_P(Universal, ValidateVersion, std::make_tuple(SPV_ENV_UNIVERSAL_1_1, SPV_ENV_OPENGL_4_2, vulkan_spirv, false), std::make_tuple(SPV_ENV_UNIVERSAL_1_1, SPV_ENV_OPENGL_4_3, vulkan_spirv, false), std::make_tuple(SPV_ENV_UNIVERSAL_1_1, SPV_ENV_OPENGL_4_5, vulkan_spirv, false), - std::make_tuple(SPV_ENV_UNIVERSAL_1_1, SPV_ENV_WEBGPU_0, webgpu_spirv, true), std::make_tuple(SPV_ENV_UNIVERSAL_1_2, SPV_ENV_UNIVERSAL_1_0, vulkan_spirv, false), std::make_tuple(SPV_ENV_UNIVERSAL_1_2, SPV_ENV_UNIVERSAL_1_1, vulkan_spirv, false), @@ -152,7 +134,6 @@ INSTANTIATE_TEST_SUITE_P(Universal, ValidateVersion, std::make_tuple(SPV_ENV_UNIVERSAL_1_2, SPV_ENV_OPENGL_4_2, vulkan_spirv, false), std::make_tuple(SPV_ENV_UNIVERSAL_1_2, SPV_ENV_OPENGL_4_3, vulkan_spirv, false), std::make_tuple(SPV_ENV_UNIVERSAL_1_2, SPV_ENV_OPENGL_4_5, vulkan_spirv, false), - std::make_tuple(SPV_ENV_UNIVERSAL_1_2, SPV_ENV_WEBGPU_0, webgpu_spirv, true), std::make_tuple(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_UNIVERSAL_1_0, vulkan_spirv, false), std::make_tuple(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_UNIVERSAL_1_1, vulkan_spirv, false), @@ -164,8 +145,7 @@ INSTANTIATE_TEST_SUITE_P(Universal, ValidateVersion, std::make_tuple(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_OPENGL_4_1, vulkan_spirv, false), std::make_tuple(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_OPENGL_4_2, vulkan_spirv, false), std::make_tuple(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_OPENGL_4_3, vulkan_spirv, false), - std::make_tuple(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_OPENGL_4_5, vulkan_spirv, false), - std::make_tuple(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_WEBGPU_0, webgpu_spirv, true) + std::make_tuple(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_OPENGL_4_5, vulkan_spirv, false) ) ); diff --git a/test/val/val_webgpu_test.cpp b/test/val/val_webgpu_test.cpp deleted file mode 100644 index 62fa6a7a83..0000000000 --- a/test/val/val_webgpu_test.cpp +++ /dev/null @@ -1,424 +0,0 @@ -// Copyright (c) 2018 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Validation tests for WebGPU env specific checks - -#include - -#include "gmock/gmock.h" -#include "test/val/val_fixtures.h" - -namespace spvtools { -namespace val { -namespace { - -using testing::HasSubstr; - -using ValidateWebGPU = spvtest::ValidateBase; - -TEST_F(ValidateWebGPU, OpUndefIsDisallowed) { - std::string spirv = R"( - OpCapability Shader - OpCapability VulkanMemoryModelKHR - OpExtension "SPV_KHR_vulkan_memory_model" - OpMemoryModel Logical VulkanKHR - OpEntryPoint Vertex %func "shader" -%float = OpTypeFloat 32 -%1 = OpUndef %float -%void = OpTypeVoid -%void_f = OpTypeFunction %void -%func = OpFunction %void None %void_f -%label = OpLabel - OpReturn - OpFunctionEnd -)"; - - CompileSuccessfully(spirv); - - // Control case: OpUndef is allowed in SPIR-V 1.3 - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); - - // Control case: OpUndef is disallowed in the WebGPU env - EXPECT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), HasSubstr("OpUndef is disallowed")); -} - -TEST_F(ValidateWebGPU, OpNameIsAllowed) { - std::string spirv = R"( - OpCapability Shader - OpCapability VulkanMemoryModelKHR - OpExtension "SPV_KHR_vulkan_memory_model" - OpMemoryModel Logical VulkanKHR - OpEntryPoint Vertex %func "shader" - OpName %1 "foo" - %1 = OpTypeFloat 32 - %void = OpTypeVoid - %void_f = OpTypeFunction %void - %func = OpFunction %void None %void_f - %label = OpLabel - OpReturn - OpFunctionEnd -)"; - - CompileSuccessfully(spirv); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); -} - -TEST_F(ValidateWebGPU, OpMemberNameIsAllowed) { - std::string spirv = R"( - OpCapability Shader - OpCapability VulkanMemoryModelKHR - OpExtension "SPV_KHR_vulkan_memory_model" - OpMemoryModel Logical VulkanKHR - OpEntryPoint Vertex %func "shader" - OpMemberName %2 0 "foo" - %1 = OpTypeFloat 32 - %2 = OpTypeStruct %1 - %void = OpTypeVoid - %void_f = OpTypeFunction %void - %func = OpFunction %void None %void_f - %label = OpLabel - OpReturn - OpFunctionEnd - -)"; - - CompileSuccessfully(spirv); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); -} - -TEST_F(ValidateWebGPU, OpSourceIsAllowed) { - std::string spirv = R"( - OpCapability Shader - OpCapability VulkanMemoryModelKHR - OpExtension "SPV_KHR_vulkan_memory_model" - OpMemoryModel Logical VulkanKHR - OpEntryPoint Vertex %func "shader" - OpSource GLSL 450 - %void = OpTypeVoid - %void_f = OpTypeFunction %void - %func = OpFunction %void None %void_f - %label = OpLabel - OpReturn - OpFunctionEnd -)"; - - CompileSuccessfully(spirv); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); -} - -TEST_F(ValidateWebGPU, OpSourceContinuedIsAllowed) { - std::string spirv = R"( - OpCapability Shader - OpCapability VulkanMemoryModelKHR - OpExtension "SPV_KHR_vulkan_memory_model" - OpMemoryModel Logical VulkanKHR - OpEntryPoint Vertex %func "shader" - OpSource GLSL 450 - OpSourceContinued "I am a happy shader! Yay! ;" - %void = OpTypeVoid - %void_f = OpTypeFunction %void - %func = OpFunction %void None %void_f - %label = OpLabel - OpReturn - OpFunctionEnd -)"; - - CompileSuccessfully(spirv); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); -} - -TEST_F(ValidateWebGPU, OpSourceExtensionIsAllowed) { - std::string spirv = R"( - OpCapability Shader - OpCapability VulkanMemoryModelKHR - OpExtension "SPV_KHR_vulkan_memory_model" - OpMemoryModel Logical VulkanKHR - OpEntryPoint Vertex %func "shader" - OpSourceExtension "bar" - %void = OpTypeVoid - %void_f = OpTypeFunction %void - %func = OpFunction %void None %void_f - %label = OpLabel - OpReturn - OpFunctionEnd -)"; - - CompileSuccessfully(spirv); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); -} - -TEST_F(ValidateWebGPU, OpStringIsAllowed) { - std::string spirv = R"( - OpCapability Shader - OpCapability VulkanMemoryModelKHR - OpExtension "SPV_KHR_vulkan_memory_model" - OpMemoryModel Logical VulkanKHR - OpEntryPoint Vertex %func "shader" - %1 = OpString "foo" - %void = OpTypeVoid - %void_f = OpTypeFunction %void - %func = OpFunction %void None %void_f - %label = OpLabel - OpReturn - OpFunctionEnd -)"; - - CompileSuccessfully(spirv); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); -} - -TEST_F(ValidateWebGPU, OpLineIsAllowed) { - std::string spirv = R"( - OpCapability Shader - OpCapability VulkanMemoryModelKHR - OpExtension "SPV_KHR_vulkan_memory_model" - OpMemoryModel Logical VulkanKHR - OpEntryPoint Vertex %func "shader" - %1 = OpString "minimal.vert" - OpLine %1 1 1 - %void = OpTypeVoid - %void_f = OpTypeFunction %void - %func = OpFunction %void None %void_f - %label = OpLabel - OpReturn - OpFunctionEnd -)"; - - CompileSuccessfully(spirv); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); -} - -TEST_F(ValidateWebGPU, OpNoLineIsAllowed) { - std::string spirv = R"( - OpCapability Shader - OpCapability VulkanMemoryModelKHR - OpExtension "SPV_KHR_vulkan_memory_model" - OpMemoryModel Logical VulkanKHR - OpEntryPoint Vertex %func "shader" - OpNoLine - %void = OpTypeVoid - %void_f = OpTypeFunction %void - %func = OpFunction %void None %void_f - %label = OpLabel - OpReturn - OpFunctionEnd -)"; - - CompileSuccessfully(spirv); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); -} - -TEST_F(ValidateWebGPU, LogicalAddressingVulkanKHRMemoryGood) { - std::string spirv = R"( - OpCapability Shader - OpCapability VulkanMemoryModelKHR - OpExtension "SPV_KHR_vulkan_memory_model" - OpMemoryModel Logical VulkanKHR - OpEntryPoint Vertex %func "shader" -%void = OpTypeVoid -%void_f = OpTypeFunction %void -%func = OpFunction %void None %void_f -%label = OpLabel - OpReturn - OpFunctionEnd -)"; - - CompileSuccessfully(spirv); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); -} - -TEST_F(ValidateWebGPU, LogicalAddressingGLSL450MemoryGood) { - std::string spirv = R"( - OpCapability Shader - OpMemoryModel Logical GLSL450 - OpEntryPoint Vertex %func "shader" -%void = OpTypeVoid -%void_f = OpTypeFunction %void -%func = OpFunction %void None %void_f -%label = OpLabel - OpReturn - OpFunctionEnd -)"; - - CompileSuccessfully(spirv); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); -} - -TEST_F(ValidateWebGPU, LogicalAddressingSimpleMemoryGood) { - std::string spirv = R"( - OpCapability Shader - OpMemoryModel Logical Simple - OpEntryPoint Vertex %func "shader" -%void = OpTypeVoid -%void_f = OpTypeFunction %void -%func = OpFunction %void None %void_f -%label = OpLabel - OpReturn - OpFunctionEnd -)"; - - CompileSuccessfully(spirv); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); -} - -TEST_F(ValidateWebGPU, KernelIsBad) { - std::string spirv = R"( - OpCapability Kernel - OpMemoryModel Logical Simple - OpNoLine -)"; - - CompileSuccessfully(spirv); - - EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY, - ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("Capability Kernel is not allowed by WebGPU " - "specification (or requires extension)")); -} - -TEST_F(ValidateWebGPU, OpenCLMemoryModelBad) { - std::string spirv = R"( - OpCapability Shader - OpMemoryModel Logical OpenCL - OpNoLine -)"; - - CompileSuccessfully(spirv); - - EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY, - ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("Operand 2 of MemoryModel requires one of these " - "capabilities: Kernel")); -} - -TEST_F(ValidateWebGPU, AllowListedExtendedInstructionsImportGood) { - std::string spirv = R"( - OpCapability Shader - OpCapability VulkanMemoryModelKHR - OpExtension "SPV_KHR_vulkan_memory_model" -%1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical VulkanKHR - OpEntryPoint Vertex %func "shader" -%void = OpTypeVoid -%void_f = OpTypeFunction %void -%func = OpFunction %void None %void_f -%label = OpLabel - OpReturn - OpFunctionEnd -)"; - - CompileSuccessfully(spirv); - - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); -} - -TEST_F(ValidateWebGPU, NonAllowListedExtendedInstructionsImportBad) { - std::string spirv = R"( - OpCapability Shader - OpCapability VulkanMemoryModelKHR - OpExtension "SPV_KHR_vulkan_memory_model" -%1 = OpExtInstImport "OpenCL.std" - OpMemoryModel Logical VulkanKHR -)"; - - CompileSuccessfully(spirv); - - EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("For WebGPU, the only valid parameter to " - "OpExtInstImport is \"GLSL.std.450\".\n %1 = " - "OpExtInstImport \"OpenCL.std\"\n")); -} - -TEST_F(ValidateWebGPU, NonVulkanKHRMemoryModelExtensionBad) { - std::string spirv = R"( - OpCapability Shader - OpCapability VulkanMemoryModelKHR - OpExtension "SPV_KHR_8bit_storage" - OpExtension "SPV_KHR_vulkan_memory_model" - OpMemoryModel Logical VulkanKHR -)"; - - CompileSuccessfully(spirv); - - EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("For WebGPU, the only valid parameter to OpExtension " - "is \"SPV_KHR_vulkan_memory_model\".\n OpExtension " - "\"SPV_KHR_8bit_storage\"\n")); -} - -spv_binary GenerateTrivialBinary(bool need_little_endian) { - // Smallest possible valid WebGPU SPIR-V binary in little endian. Contains all - // the required boilerplate and a trivial entry point function. - static const uint8_t binary_bytes[] = { - // clang-format off - 0x03, 0x02, 0x23, 0x07, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0xE1, 0x14, 0x00, 0x00, - 0x0A, 0x00, 0x08, 0x00, 0x53, 0x50, 0x56, 0x5F, 0x4B, 0x48, 0x52, 0x5F, - 0x76, 0x75, 0x6C, 0x6B, 0x61, 0x6E, 0x5F, 0x6D, 0x65, 0x6D, 0x6F, 0x72, - 0x79, 0x5F, 0x6D, 0x6F, 0x64, 0x65, 0x6C, 0x00, 0x0E, 0x00, 0x03, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x05, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x73, 0x68, 0x61, 0x64, - 0x65, 0x72, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, - 0x04, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00 - // clang-format on - }; - static const size_t word_count = sizeof(binary_bytes) / sizeof(uint32_t); - std::unique_ptr result(new spv_binary_t); - if (!result) return nullptr; - - result->wordCount = word_count; - result->code = new uint32_t[word_count]; - if (!result->code) return nullptr; - - if (need_little_endian) { - memcpy(result->code, binary_bytes, sizeof(binary_bytes)); - } else { - uint8_t* code_bytes = reinterpret_cast(result->code); - for (size_t word = 0; word < word_count; ++word) { - code_bytes[4 * word] = binary_bytes[4 * word + 3]; - code_bytes[4 * word + 1] = binary_bytes[4 * word + 2]; - code_bytes[4 * word + 2] = binary_bytes[4 * word + 1]; - code_bytes[4 * word + 3] = binary_bytes[4 * word]; - } - } - - return result.release(); -} - -TEST_F(ValidateWebGPU, LittleEndianGood) { - DestroyBinary(); - binary_ = GenerateTrivialBinary(true); - EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0)); -} - -TEST_F(ValidateWebGPU, BigEndianBad) { - DestroyBinary(); - binary_ = GenerateTrivialBinary(false); - EXPECT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions(SPV_ENV_WEBGPU_0)); - EXPECT_THAT(getDiagnosticString(), - HasSubstr("WebGPU requires SPIR-V to be little endian.")); -} - -} // namespace -} // namespace val -} // namespace spvtools diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index 66f9228632..e7e5899894 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -79,18 +79,6 @@ std::string GetSizePasses() { return GetListOfPassesAsString(optimizer); } -std::string GetVulkanToWebGPUPasses() { - spvtools::Optimizer optimizer(SPV_ENV_VULKAN_1_1); - optimizer.RegisterVulkanToWebGPUPasses(); - return GetListOfPassesAsString(optimizer); -} - -std::string GetWebGPUToVulkanPasses() { - spvtools::Optimizer optimizer(SPV_ENV_WEBGPU_0); - optimizer.RegisterWebGPUToVulkanPasses(); - return GetListOfPassesAsString(optimizer); -} - void PrintUsage(const char* program) { std::string target_env_list = spvTargetEnvList(16, 80); // NOTE: Please maintain flags in lexicographical order. @@ -239,10 +227,6 @@ Options (in lexicographical order):)", values, providing guarantees that satisfy Vulkan's robustBufferAccess rules.)"); printf(R"( - --generate-webgpu-initializers - Adds initial values to OpVariable instructions that are missing - them, due to their storage type requiring them for WebGPU.)"); - printf(R"( --if-conversion Convert if-then-else like assignments into OpSelect.)"); printf(R"( @@ -261,11 +245,6 @@ Options (in lexicographical order):)", option --relax-logical-pointer to the validator.)", GetLegalizationPasses().c_str()); printf(R"( - --legalize-vector-shuffle - Converts any usages of 0xFFFFFFFF for the literals in - OpVectorShuffle to a literal 0. This is done since 0xFFFFFFFF is - forbidden in WebGPU.)"); - printf(R"( --local-redundancy-elimination Looks for instructions in the same basic block that compute the same value, and deletes the redundant ones.)"); @@ -463,13 +442,6 @@ Options (in lexicographical order):)", Forwards this option to the validator. See the validator help for details.)"); printf(R"( - --split-invalid-unreachable - Attempts to legalize for WebGPU cases where an unreachable - merge-block is also a continue-target by splitting it into two - separate blocks. There exist legal, for Vulkan, instances of this - pattern that cannot be converted into legal WebGPU, so this - conversion may not succeed.)"); - printf(R"( --skip-validation Will not validate the SPIR-V before optimizing. If the SPIR-V is invalid, the optimizer may fail or generate incorrect code. @@ -513,34 +485,6 @@ Options (in lexicographical order):)", removes them from the vector. Note this would still leave around lots of dead code that a pass of ADCE will be able to remove.)"); printf(R"( - --vulkan-to-webgpu - Turns on the prescribed passes for converting from Vulkan to - WebGPU and sets the target environment to webgpu0. Other passes - may be turned on via additional flags, but such combinations are - not tested. - Using --target-env with this flag is not allowed. - - This flag is the equivalent of passing in --target-env=webgpu0 - and specifying the following optimization code names: - %s - - NOTE: This flag is a WIP and its behaviour is subject to change.)", - GetVulkanToWebGPUPasses().c_str()); - printf(R"( - --webgpu-to-vulkan - Turns on the prescribed passes for converting from WebGPU to - Vulkan and sets the target environment to vulkan1.1. Other passes - may be turned on via additional flags, but such combinations are - not tested. - Using --target-env with this flag is not allowed. - - This flag is the equivalent of passing in --target-env=vulkan1.1 - and specifying the following optimization code names: - %s - - NOTE: This flag is a WIP and its behaviour is subject to change.)", - GetWebGPUToVulkanPasses().c_str()); - printf(R"( --workaround-1209 Rewrites instructions for which there are known driver bugs to avoid triggering those bugs. @@ -714,9 +658,6 @@ OptStatus ParseFlags(int argc, const char** argv, spvtools::ValidatorOptions* validator_options, spvtools::OptimizerOptions* optimizer_options) { std::vector pass_flags; - bool target_env_set = false; - bool vulkan_to_webgpu_set = false; - bool webgpu_to_vulkan_set = false; for (int argi = 1; argi < argc; ++argi) { const char* cur_arg = argv[argi]; if ('-' == cur_arg[0]) { @@ -781,19 +722,6 @@ OptStatus ParseFlags(int argc, const char** argv, max_id_bound); } else if (0 == strncmp(cur_arg, "--target-env=", sizeof("--target-env=") - 1)) { - target_env_set = true; - if (vulkan_to_webgpu_set) { - spvtools::Error(opt_diagnostic, nullptr, {}, - "--vulkan-to-webgpu defines the target environment, " - "so --target-env cannot be set at the same time"); - return {OPT_STOP, 1}; - } - if (webgpu_to_vulkan_set) { - spvtools::Error(opt_diagnostic, nullptr, {}, - "--webgpu-to-vulkan defines the target environment, " - "so --target-env cannot be set at the same time"); - return {OPT_STOP, 1}; - } const auto split_flag = spvtools::utils::SplitFlagArgs(cur_arg); const auto target_env_str = split_flag.second.c_str(); spv_target_env target_env; @@ -803,42 +731,6 @@ OptStatus ParseFlags(int argc, const char** argv, return {OPT_STOP, 1}; } optimizer->SetTargetEnv(target_env); - } else if (0 == strcmp(cur_arg, "--vulkan-to-webgpu")) { - vulkan_to_webgpu_set = true; - if (target_env_set) { - spvtools::Error(opt_diagnostic, nullptr, {}, - "--vulkan-to-webgpu defines the target environment, " - "so --target-env cannot be set at the same time"); - return {OPT_STOP, 1}; - } - if (webgpu_to_vulkan_set) { - spvtools::Error(opt_diagnostic, nullptr, {}, - "Cannot use both --webgpu-to-vulkan and " - "--vulkan-to-webgpu at the same time, invoke twice " - "if you are wanting to go to and from"); - return {OPT_STOP, 1}; - } - - optimizer->SetTargetEnv(SPV_ENV_VULKAN_1_1); - optimizer->RegisterVulkanToWebGPUPasses(); - } else if (0 == strcmp(cur_arg, "--webgpu-to-vulkan")) { - webgpu_to_vulkan_set = true; - if (target_env_set) { - spvtools::Error(opt_diagnostic, nullptr, {}, - "--webgpu-to-vulkan defines the target environment, " - "so --target-env cannot be set at the same time"); - return {OPT_STOP, 1}; - } - if (vulkan_to_webgpu_set) { - spvtools::Error(opt_diagnostic, nullptr, {}, - "Cannot use both --webgpu-to-vulkan and " - "--vulkan-to-webgpu at the same time, invoke twice " - "if you are wanting to go to and from"); - return {OPT_STOP, 1}; - } - - optimizer->SetTargetEnv(SPV_ENV_WEBGPU_0); - optimizer->RegisterWebGPUToVulkanPasses(); } else if (0 == strcmp(cur_arg, "--validate-after-all")) { optimizer->SetValidateAfterAll(true); } else if (0 == strcmp(cur_arg, "--before-hlsl-legalization")) { diff --git a/tools/val/val.cpp b/tools/val/val.cpp index 19b8c776a8..da63245a28 100644 --- a/tools/val/val.cpp +++ b/tools/val/val.cpp @@ -108,7 +108,7 @@ int main(int argc, char** argv) { printf("%s\n", spvSoftwareVersionDetailsString()); printf( "Targets:\n %s\n %s\n %s\n %s\n %s\n %s\n %s\n %s\n %s\n " - "%s\n %s\n", + "%s\n", spvTargetEnvDescription(SPV_ENV_UNIVERSAL_1_0), spvTargetEnvDescription(SPV_ENV_UNIVERSAL_1_1), spvTargetEnvDescription(SPV_ENV_UNIVERSAL_1_2), @@ -118,8 +118,7 @@ int main(int argc, char** argv) { spvTargetEnvDescription(SPV_ENV_OPENCL_2_2), spvTargetEnvDescription(SPV_ENV_VULKAN_1_0), spvTargetEnvDescription(SPV_ENV_VULKAN_1_1), - spvTargetEnvDescription(SPV_ENV_VULKAN_1_1_SPIRV_1_4), - spvTargetEnvDescription(SPV_ENV_WEBGPU_0)); + spvTargetEnvDescription(SPV_ENV_VULKAN_1_1_SPIRV_1_4)); continue_processing = false; return_code = 0; } else if (0 == strcmp(cur_arg, "--help") || 0 == strcmp(cur_arg, "-h")) {