• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2017 LunarG Inc.
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 // Validates correctness of primitive SPIR-V instructions.
16 
17 #include "source/val/validate.h"
18 
19 #include <string>
20 
21 #include "source/diagnostic.h"
22 #include "source/opcode.h"
23 #include "source/val/instruction.h"
24 #include "source/val/validation_state.h"
25 
26 namespace spvtools {
27 namespace val {
28 
29 // Validates correctness of primitive instructions.
PrimitivesPass(ValidationState_t & _,const Instruction * inst)30 spv_result_t PrimitivesPass(ValidationState_t& _, const Instruction* inst) {
31   const SpvOp opcode = inst->opcode();
32 
33   switch (opcode) {
34     case SpvOpEmitVertex:
35     case SpvOpEndPrimitive:
36     case SpvOpEmitStreamVertex:
37     case SpvOpEndStreamPrimitive:
38       _.function(inst->function()->id())
39           ->RegisterExecutionModelLimitation(
40               SpvExecutionModelGeometry,
41               std::string(spvOpcodeString(opcode)) +
42                   " instructions require Geometry execution model");
43       break;
44     default:
45       break;
46   }
47 
48   switch (opcode) {
49     case SpvOpEmitStreamVertex:
50     case SpvOpEndStreamPrimitive: {
51       const uint32_t stream_id = inst->word(1);
52       const uint32_t stream_type = _.GetTypeId(stream_id);
53       if (!_.IsIntScalarType(stream_type)) {
54         return _.diag(SPV_ERROR_INVALID_DATA, inst)
55                << spvOpcodeString(opcode)
56                << ": expected Stream to be int scalar";
57       }
58 
59       const SpvOp stream_opcode = _.GetIdOpcode(stream_id);
60       if (!spvOpcodeIsConstant(stream_opcode)) {
61         return _.diag(SPV_ERROR_INVALID_DATA, inst)
62                << spvOpcodeString(opcode)
63                << ": expected Stream to be constant instruction";
64       }
65     }
66 
67     default:
68       break;
69   }
70 
71   return SPV_SUCCESS;
72 }
73 
74 }  // namespace val
75 }  // namespace spvtools
76