1// Copyright (c) 2020 The Khronos Group Inc.
2// Copyright (c) 2020 Valve Corporation
3// Copyright (c) 2020 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_DEBUG_PRINTF_PASS_H_
18#define LIBSPIRV_OPT_INST_DEBUG_PRINTF_PASS_H_
19
20#include "instrument_pass.h"
21
22namespace spvtools {
23namespace opt {
24
25// This class/pass is designed to support the debug printf GPU-assisted layer
26// of https://github.com/KhronosGroup/Vulkan-ValidationLayers. Its internal and
27// external design may change as the layer evolves.
28class InstDebugPrintfPass : public InstrumentPass {
29 public:
30 // For test harness only
31 InstDebugPrintfPass()
32 : InstrumentPass(7, 23, kInstValidationIdDebugPrintf, 2) {}
33 // For all other interfaces
34 InstDebugPrintfPass(uint32_t desc_set, uint32_t shader_id)
35 : InstrumentPass(desc_set, shader_id, kInstValidationIdDebugPrintf, 2) {}
36
37 ~InstDebugPrintfPass() override = default;
38
39 // See optimizer.hpp for pass user documentation.
40 Status Process() override;
41
42 const char* name() const override { return "inst-printf-pass"; }
43
44 private:
45 // Generate instructions for OpDebugPrintf.
46 //
47 // If |ref_inst_itr| is an OpDebugPrintf, return in |new_blocks| the result
48 // of replacing it with buffer write instructions within its block at
49 // |ref_block_itr|. The instructions write a record to the printf
50 // output buffer stream including |function_idx, instruction_idx, stage_idx|
51 // and removes the OpDebugPrintf. The block at |ref_block_itr| can just be
52 // replaced with the block in |new_blocks|. Besides the buffer writes, this
53 // block will comprise all instructions preceding and following
54 // |ref_inst_itr|.
55 //
56 // This function is designed to be passed to
57 // InstrumentPass::InstProcessEntryPointCallTree(), which applies the
58 // function to each instruction in a module and replaces the instruction
59 // if warranted.
60 //
61 // This instrumentation function utilizes GenDebugStreamWrite() to write its
62 // error records. The validation-specific part of the error record will
63 // consist of a uint32 which is the id of the format string plus a sequence
64 // of uint32s representing the values of the remaining operands of the
65 // DebugPrintf.
66 void GenDebugPrintfCode(BasicBlock::iterator ref_inst_itr,
67 UptrVectorIterator<BasicBlock> ref_block_itr,
68 uint32_t stage_idx,
69 std::vector<std::unique_ptr<BasicBlock>>* new_blocks);
70
71 // Generate a sequence of uint32 instructions in |builder| (if necessary)
72 // representing the value of |val_inst|, which must be a buffer pointer, a
73 // uint64, or a scalar or vector of type uint32, float32 or float16. Append
74 // the ids of all values to the end of |val_ids|.
75 void GenOutputValues(Instruction* val_inst, std::vector<uint32_t>* val_ids,
76 InstructionBuilder* builder);
77
78 // Generate instructions to write a record containing the operands of
79 // |printf_inst| arguments to printf buffer, adding new code to the end of
80 // the last block in |new_blocks|. Kill OpDebugPrintf instruction.
81 void GenOutputCode(Instruction* printf_inst, uint32_t stage_idx,
82 std::vector<std::unique_ptr<BasicBlock>>* new_blocks);
83
84 // Initialize state for instrumenting bindless checking
85 void InitializeInstDebugPrintf();
86
87 // Apply GenDebugPrintfCode to every instruction in module.
88 Pass::Status ProcessImpl();
89
90 uint32_t ext_inst_printf_id_;
91};
92
93} // namespace opt
94} // namespace spvtools
95
96#endif // LIBSPIRV_OPT_INST_DEBUG_PRINTF_PASS_H_
97