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
26namespace spvtools {
27namespace val {
28
29// Validates correctness of primitive instructions.
30spv_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