1 // Copyright (c) 2018 The Khronos Group Inc.
2 // Copyright (c) 2018 Valve Corporation
3 // Copyright (c) 2018 LunarG Inc.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 
17 #ifndef LIBSPIRV_OPT_INST_BINDLESS_CHECK_PASS_H_
18 #define LIBSPIRV_OPT_INST_BINDLESS_CHECK_PASS_H_
19 
20 #include "instrument_pass.h"
21 
22 namespace spvtools {
23 namespace opt {
24 
25 // This class/pass is designed to support the bindless (descriptor indexing)
26 // GPU-assisted validation layer of
27 // https://github.com/KhronosGroup/Vulkan-ValidationLayers. Its internal and
28 // external design may change as the layer evolves.
29 class InstBindlessCheckPass : public InstrumentPass {
30  public:
31   // For test harness only
InstBindlessCheckPass()32   InstBindlessCheckPass() : InstrumentPass(7, 23, kInstValidationIdBindless) {}
33   // For all other interfaces
InstBindlessCheckPass(uint32_t desc_set,uint32_t shader_id)34   InstBindlessCheckPass(uint32_t desc_set, uint32_t shader_id)
35       : InstrumentPass(desc_set, shader_id, kInstValidationIdBindless) {}
36 
37   ~InstBindlessCheckPass() override = default;
38 
39   // See optimizer.hpp for pass user documentation.
40   Status Process() override;
41 
name()42   const char* name() const override { return "inst-bindless-check-pass"; }
43 
44  private:
45   // Initialize state for instrumenting bindless checking
46   void InitializeInstBindlessCheck();
47 
48   // This function does bindless checking instrumentation on a single
49   // instruction. It is designed to be passed to
50   // InstrumentPass::InstProcessEntryPointCallTree(), which applies the
51   // function to each instruction in a module and replaces the instruction
52   // if warranted.
53   //
54   // If |ref_inst_itr| is a bindless reference, return in |new_blocks| the
55   // result of instrumenting it with validation code within its block at
56   // |ref_block_itr|. Specifically, generate code to check that the index
57   // into the descriptor array is in-bounds. If the check passes, execute
58   // the remainder of the reference, otherwise write a record to the debug
59   // output buffer stream including |function_idx, instruction_idx, stage_idx|
60   // and replace the reference with the null value of the original type. The
61   // block at |ref_block_itr| can just be replaced with the blocks in
62   // |new_blocks|, which will contain at least two blocks. The last block will
63   // comprise all instructions following |ref_inst_itr|,
64   // preceded by a phi instruction.
65   //
66   // This instrumentation pass utilizes GenDebugStreamWrite() to write its
67   // error records. The validation-specific part of the error record will
68   // have the format:
69   //
70   //    Validation Error Code (=kInstErrorBindlessBounds)
71   //    Descriptor Index
72   //    Descriptor Array Size
73   //
74   // The Descriptor Index is the index which has been determined to be
75   // out-of-bounds.
76   //
77   // The Descriptor Array Size is the size of the descriptor array which was
78   // indexed.
79   void GenBindlessCheckCode(
80       BasicBlock::iterator ref_inst_itr,
81       UptrVectorIterator<BasicBlock> ref_block_itr, uint32_t instruction_idx,
82       uint32_t stage_idx, std::vector<std::unique_ptr<BasicBlock>>* new_blocks);
83 
84   Pass::Status ProcessImpl();
85 
86   // True if VK_EXT_descriptor_indexing is defined
87   bool ext_descriptor_indexing_defined_;
88 };
89 
90 }  // namespace opt
91 }  // namespace spvtools
92 
93 #endif  // LIBSPIRV_OPT_INST_BINDLESS_CHECK_PASS_H_
94