1 // Copyright (c) 2018 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef SOURCE_OPT_REPLACE_INVALID_OPC_H_ 16 #define SOURCE_OPT_REPLACE_INVALID_OPC_H_ 17 18 #include <string> 19 20 #include "source/opt/pass.h" 21 22 namespace spvtools { 23 namespace opt { 24 25 // This pass will runs on shader modules only. It will replace the result of 26 // instructions that are valid for shader modules, but not the current shader 27 // stage, with a constant value. If the instruction does not have a return 28 // value, the instruction will simply be deleted. 29 class ReplaceInvalidOpcodePass : public Pass { 30 public: name()31 const char* name() const override { return "replace-invalid-opcode"; } 32 Status Process() override; 33 34 private: 35 // Returns the execution model that is used by every entry point in the 36 // module. If more than one execution model is used in the module, then the 37 // return value is SpvExecutionModelMax. 38 SpvExecutionModel GetExecutionModel(); 39 40 // Replaces all instructions in |function| that are invalid with execution 41 // model |mode|, but valid for another shader model, with a special constant 42 // value. See |GetSpecialConstant|. 43 bool RewriteFunction(Function* function, SpvExecutionModel mode); 44 45 // Returns true if |inst| is valid for fragment shaders only. 46 bool IsFragmentShaderOnlyInstruction(Instruction* inst); 47 48 // Replaces all uses of the result of |inst|, if there is one, with the id of 49 // a special constant. Then |inst| is killed. |inst| cannot be a block 50 // terminator because the basic block will then become invalid. |inst| is no 51 // longer valid after calling this function. 52 void ReplaceInstruction(Instruction* inst, const char* source, 53 uint32_t line_number, uint32_t column_number); 54 55 // Returns the id of a constant with type |type_id|. The type must be an 56 // integer, float, or vector. For scalar types, the hex representation of the 57 // constant will be the concatenation of 0xDEADBEEF with itself until the 58 // width of the type has been reached. For a vector, each element of the 59 // constant will be constructed the same way. 60 uint32_t GetSpecialConstant(uint32_t type_id); 61 std::string BuildWarningMessage(SpvOp opcode); 62 }; 63 64 } // namespace opt 65 } // namespace spvtools 66 67 #endif // SOURCE_OPT_REPLACE_INVALID_OPC_H_ 68