• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 The Amber Authors.
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 SRC_DEBUG_H_
16 #define SRC_DEBUG_H_
17 
18 #include <stdint.h>
19 
20 #include <functional>
21 #include <memory>
22 #include <string>
23 #include <vector>
24 
25 #include "amber/result.h"
26 
27 /// amber::debug holds the types used for testing a graphics debugger.
28 namespace amber {
29 namespace debug {
30 
31 // Forward declaration.
32 class ThreadScript;
33 
34 /// Location holds a file path and a 1-based line number.
35 struct Location {
36   std::string file;   // empty represents unspecified.
37   uint32_t line = 0;  // 0 represents unspecified.
38 };
39 
40 // StackFrame holds name and location of a stack frame.
41 struct StackFrame {
42   std::string name;
43   Location location;
44 };
45 
46 /// Thread is the interface used to control a single debugger thread of
47 /// execution.
48 class Thread {
49  public:
50   virtual ~Thread();
51 
52   /// StepOver instructs the debugger to perform a single line step on the given
53   /// thread of execution, stepping over any function call instructions.
54   virtual void StepOver() = 0;
55 
56   /// StepIn instructs the debugger to perform a single line step on the given
57   /// thread of execution, stepping into any function call instructions.
58   virtual void StepIn() = 0;
59 
60   /// StepOut instructs the debugger to resume execution of the given thread of
61   /// execution. If the current function is not the top most of the call stack,
62   /// then the debugger will pause at the next line after the call to the
63   /// current function.
64   virtual void StepOut() = 0;
65 
66   /// Continue instructs the debugger to resume execution of the given thread of
67   /// execution.
68   virtual void Continue() = 0;
69 
70   /// ExpectLocation verifies that the debugger is currently suspended for the
71   /// given thread of execution at the specified source location. If |line| is
72   /// non-empty, then the line's textual source will also be verified.
73   virtual void ExpectLocation(const Location& location,
74                               const std::string& line) = 0;
75 
76   /// ExpectCallstack verifies that the debugger is currently suspended for the
77   /// given thread of execution with the specified callstack.
78   /// callstack is ordered with the 0th element representing the most nested
79   /// call.
80   virtual void ExpectCallstack(const std::vector<StackFrame>& callstack) = 0;
81 
82   /// ExpectLocal verifies that the local variable with the given name has the
83   /// expected value. |name| may contain `.` delimiters to index structure or
84   /// array types.
85   virtual void ExpectLocal(const std::string& name, int64_t value) = 0;
86   virtual void ExpectLocal(const std::string& name, double value) = 0;
87   virtual void ExpectLocal(const std::string& name,
88                            const std::string& value) = 0;
89 };
90 
91 /// Events is the interface used to control the debugger.
92 class Events {
93  public:
94   virtual ~Events();
95 
96   /// BreakOnComputeGlobalInvocation instructs the debugger to set a breakpoint
97   /// at the start of the compute shader program for the invocation with the
98   /// global invocation identifier [|x|, |y|, |z|], and run the |ThreadScript|
99   /// once the breakpoint is hit.
100   virtual void BreakOnComputeGlobalInvocation(
101       uint32_t x,
102       uint32_t y,
103       uint32_t z,
104       const std::shared_ptr<const ThreadScript>&) = 0;
105 
106   /// BreakOnVertexIndex instructs the debugger to set a breakpoint at the start
107   /// of the vertex shader program for the invocation with the vertex index
108   /// |index|, and run the |ThreadScript| once the breakpoint is hit.
109   virtual void BreakOnVertexIndex(
110       uint32_t index,
111       const std::shared_ptr<const ThreadScript>&) = 0;
112 
113   /// BreakOnFragmentWindowSpacePosition instructs the debugger to set a
114   /// breakpoint at the start of the fragment shader program for the invocation
115   /// with the window space coordinate [x, y], and run the |ThreadScript| once
116   /// the breakpoint is hit.
117   virtual void BreakOnFragmentWindowSpacePosition(
118       uint32_t x,
119       uint32_t y,
120       const std::shared_ptr<const ThreadScript>&) = 0;
121 };
122 
123 /// ThreadScript is a specialization of the |amber::debug::Thread| interface,
124 /// and is used to record all the calls made on it, which can be later replayed
125 /// with |ThreadScript::Run|.
126 class ThreadScript : public Thread {
127  public:
128   ~ThreadScript() override;
129 
130   /// Run replays all the calls made to the |ThreadScript| on the given |Thread|
131   /// parameter.
132   virtual void Run(Thread*) const = 0;
133 
134   // Create constructs and returns a new ThreadScript.
135   static std::shared_ptr<ThreadScript> Create();
136 };
137 
138 /// Script is an specialization of the |amber::debug::Events| interface, and is
139 /// used to record all the calls made on it, which can be later replayed with
140 /// |Script::Run|.
141 class Script : public Events {
142  public:
143   ~Script() override;
144 
145   /// Run replays all the calls made to the |Script| on the given |Events|
146   /// parameter.
147   virtual void Run(Events*) const = 0;
148 
149   // Create constructs and returns a new Script.
150   static std::unique_ptr<Script> Create();
151 };
152 
153 }  // namespace debug
154 }  // namespace amber
155 
156 #endif  // SRC_DEBUG_H_
157