Talvos  0.1
SPIR-V interpreter and dynamic analysis framework
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
PipelineExecutor.h
Go to the documentation of this file.
1 // Copyright (c) 2018 the Talvos developers. All rights reserved.
2 //
3 // This file is distributed under a three-clause BSD license. For full license
4 // terms please see the LICENSE file distributed with this source code.
5 
8 
9 #ifndef TALVOS_PIPELINEEXECUTOR_H
10 #define TALVOS_PIPELINEEXECUTOR_H
11 
12 #include <atomic>
13 #include <condition_variable>
14 #include <functional>
15 #include <map>
16 #include <thread>
17 #include <vector>
18 
19 #include "talvos/Dim3.h"
20 #include "talvos/PipelineContext.h"
21 
22 namespace talvos
23 {
24 
25 class Command;
26 class Device;
27 class DispatchCommand;
28 class DrawCommandBase;
29 class Framebuffer;
30 class Invocation;
31 class Memory;
32 class Object;
33 class PipelineStage;
34 class RenderPassInstance;
35 class Type;
36 class Variable;
37 class Workgroup;
38 
41 {
42  friend class Device;
44 };
45 
46 // TODO: Define proper Vec2/Vec3/Vec4/Vec<N> classes?
47 struct Vec4
48 {
49  float X, Y, Z, W;
50 };
51 
55 {
56 public:
59 
62 
63  // Do not allow PipelineExecutor objects to be copied.
65  PipelineExecutor(const PipelineExecutor &) = delete;
66  PipelineExecutor &operator=(const PipelineExecutor &) = delete;
68 
70  const Invocation *getCurrentInvocation() const;
71 
73  const Workgroup *getCurrentWorkgroup() const;
74 
76  const PipelineStage &getCurrentStage() const { return *CurrentStage; }
77 
79  bool isWorkerThread() const;
80 
82  void run(const DispatchCommand &Cmd);
83 
85  void run(const DrawCommandBase &Cmd);
86 
88  void signalError();
89 
90 private:
92  struct RenderPipelineState;
93 
95  struct VertexOutput;
96 
98  struct PointPrimitive;
99 
101  struct TrianglePrimitive;
102 
104  struct Fragment
105  {
106  uint32_t X;
107  uint32_t Y;
108  float Depth;
109  float InvW;
110  };
111 
113  void doWork(std::function<void()> Task);
114 
116  void runWorker();
117 
119  void runComputeWorker();
120 
123  const PipelineContext &PC,
124  const RenderPassInstance &RPI,
125  const VkViewport &Viewport);
126 
128  void runPointFragmentWorker(PointPrimitive Primitive,
129  const RenderPassInstance &RPI);
130 
132  void runVertexWorker(RenderPipelineState *State, uint32_t InstanceIndex);
133 
135  void finalizeVariables(const DescriptorSetMap &DSM);
136 
138  void initializeVariables(const DescriptorSetMap &DSM,
139  uint64_t PushConstantAddress);
140 
142  void buildPendingFragments(const DrawCommandBase &Cmd, int XMinFB, int XMaxFB,
143  int YMinFB, int YMaxFB);
144 
146  void processFragment(const Fragment &Frag, const RenderPassInstance &RPI,
147  std::function<void(uint32_t, uint32_t, const Variable *,
148  const Type *, Memory *, uint64_t)>
149  GenLocData);
150 
152  void rasterizePoint(const DrawCommandBase &Cmd, const VkViewport &Viewport,
153  const VertexOutput &Vertex);
154 
156  void rasterizeTriangle(const DrawCommandBase &Cmd, const VkViewport &Viewport,
157  const VertexOutput &VA, const VertexOutput &VB,
158  const VertexOutput &VC);
159 
161  static Vec4 getPosition(const VertexOutput &Out);
162 
164  void loadVertexInput(const PipelineContext &PC, Memory *PipelineMemory,
165  uint64_t Address, uint32_t VertexIndex,
166  uint32_t InstanceIndex, uint32_t Location,
167  uint32_t Component, const Type *ElemTy) const;
168 
171 
174 
177 
179  std::vector<Object> Objects;
180 
182  unsigned NumThreads;
183 
185  std::vector<std::thread> WorkerThreads;
186 
189 
191  std::function<void()> CurrentTask;
192 
194  uint32_t CurrentTaskID = 0;
195 
197  std::mutex WorkerMutex;
198 
200  std::condition_variable WorkerSignal;
201 
203  std::condition_variable MasterSignal;
204 
206  std::atomic<uint32_t> NumWorkersFinished;
207 
209  std::atomic<size_t> NextWorkIndex;
210 
212  std::vector<Dim3> PendingGroups;
213 
215  std::vector<Workgroup *> RunningGroups;
216 
218  std::vector<Dim3> PendingFragments;
219 
221  Workgroup *createWorkgroup(Dim3 GroupId) const;
222 
223  // Interactive debugging functionality.
224  bool Continue;
225  bool Interactive;
226 
228  void interact();
229 
231  void printContext() const;
232 
234  std::vector<std::string> LastLine;
235 
237  static uint32_t NextBreakpoint;
238 
240  static std::map<uint32_t, uint32_t> Breakpoints;
241 
245  bool brk(const std::vector<std::string> &Args);
246  bool breakpoint(const std::vector<std::string> &Args);
247  bool cont(const std::vector<std::string> &Args);
248  bool help(const std::vector<std::string> &Args);
249  bool print(const std::vector<std::string> &Args);
250  bool quit(const std::vector<std::string> &Args);
251  bool step(const std::vector<std::string> &Args);
252  bool swtch(const std::vector<std::string> &Args);
254 };
255 
256 } // namespace talvos
257 
258 #endif
This class represents a module-scope variable declaration.
Definition: Variable.h:21
std::vector< Workgroup * > RunningGroups
Pool of groups that have begun execution and been suspended.
uint32_t Y
Framebuffer y-coordinate.
const PipelineStage * CurrentStage
The pipeline stage currently being executed.
Only allow Device objects to create PipelineExecutor instances.
void run(const DispatchCommand &Cmd)
Run a compute dispatch command to completion.
bool isWorkerThread() const
Returns true if the calling thread is a PipelineExecutor worker thread.
bool brk(const std::vector< std::string > &Args)
void printContext() const
Print the context for the current invocation.
uint32_t X
Framebuffer x-coordinate.
const Command * CurrentCommand
The command currently being executed.
bool ShutDownWorkers
Signal to shut down worker threads.
std::vector< Dim3 > PendingFragments
Pool of framebuffer coordinates pending fragment processing.
~PipelineExecutor()
Destroy a pipeline executor.
void doWork(std::function< void()> Task)
Execute a function on every worker thread.
void initializeVariables(const DescriptorSetMap &DSM, uint64_t PushConstantAddress)
Initialize variables.
static std::map< uint32_t, uint32_t > Breakpoints
Map from breakpoint ID to instruction result ID.
void runComputeWorker()
Worker thread entry point for compute shaders.
const Invocation * getCurrentInvocation() const
Returns the current invocation being executed.
std::condition_variable MasterSignal
Condition variable used to notify master thread that work is complete.
This class encapsulates information about a compute kernel launch.
Definition: Commands.h:278
void signalError()
Signal that an error has occurred, breaking the interactive debugger.
const PipelineStage & getCurrentStage() const
Returns the pipeline stage that is currently being executed.
const Workgroup * getCurrentWorkgroup() const
Returns the current workgroup being executed.
void finalizeVariables(const DescriptorSetMap &DSM)
Finalize variables.
std::condition_variable WorkerSignal
Condition variable used to wake worker threads.
void runPointFragmentWorker(PointPrimitive Primitive, const RenderPassInstance &RPI)
Worker thread entry point for point rasterization.
This class is a base class for all commands.
Definition: Commands.h:31
This class represents an instance of a render pass being used for drawing.
Definition: RenderPass.h:95
This class encapsulates pipeline state and bound resources.
bool print(const std::vector< std::string > &Args)
std::atomic< size_t > NextWorkIndex
Index of next item of work to execute in the current task.
This class represents a single execution of a SPIR-V entry point.
Definition: Invocation.h:33
std::vector< Object > Objects
The initial object values for each invocation.
Triangle primitive data, used for rasterization.
Workgroup * createWorkgroup(Dim3 GroupId) const
Create a compute shader workgroup and its work-item invocations.
void interact()
Trigger interaction with the user (if necessary).
Class representing a 3-dimensional size or ID.
Definition: Dim3.h:22
void loadVertexInput(const PipelineContext &PC, Memory *PipelineMemory, uint64_t Address, uint32_t VertexIndex, uint32_t InstanceIndex, uint32_t Location, uint32_t Component, const Type *ElemTy) const
Helper function to copy vertex input data to pipeline memory.
bool breakpoint(const std::vector< std::string > &Args)
std::map< uint32_t, talvos::DescriptorSet > DescriptorSetMap
Mapping from set numbers to descriptor sets.
This is an abstract base class for draw commands.
Definition: Commands.h:311
bool cont(const std::vector< std::string > &Args)
std::vector< std::string > LastLine
Tokens for the most recent interactive command entered.
std::mutex WorkerMutex
Mutex used to synchronize with worker threads.
This file declares the Dim3 class.
bool step(const std::vector< std::string > &Args)
This class represents an address space in the virtual device.
Definition: Memory.h:37
void processFragment(const Fragment &Frag, const RenderPassInstance &RPI, std::function< void(uint32_t, uint32_t, const Variable *, const Type *, Memory *, uint64_t)> GenLocData)
Helper function to process a fragment.
An internal class that handles pipeline execution, including the interactive debugger.
void runWorker()
Worker thread entry point.
Device & Dev
The device this shader is executing on.
PipelineExecutor & operator=(const PipelineExecutor &)=delete
void rasterizePoint(const DrawCommandBase &Cmd, const VkViewport &Viewport, const VertexOutput &Vertex)
Helper function to rasterize a point primitive.
A Device instance encapsulates properties and state for the virtual device.
Definition: Device.h:29
Outputs from a vertex shading stage.
This class represents a workgroup executing a compute command.
Definition: Workgroup.h:27
std::atomic< uint32_t > NumWorkersFinished
Tally of the number of workers that have finished the current task.
Point primitive data, used for rasterization.
This file declares the PipelineContext class and related typedefs.
This class encapsulates information about a pipeline stage.
Definition: PipelineStage.h:30
void rasterizeTriangle(const DrawCommandBase &Cmd, const VkViewport &Viewport, const VertexOutput &VA, const VertexOutput &VB, const VertexOutput &VC)
Helper function to rasterize a triangle primitive.
std::vector< std::thread > WorkerThreads
List of worker threads.
uint32_t CurrentTaskID
ID used to identify the current task.
PipelineExecutor(PipelineExecutorKey Key, Device &Dev)
Create a pipeline executor on Dev.
bool swtch(const std::vector< std::string > &Args)
std::function< void()> CurrentTask
The function that worker threads should execute.
bool help(const std::vector< std::string > &Args)
This class represents a SPIR-V type.
Definition: Type.h:33
float InvW
Inverse of the interpolated clip w coordinate.
void runVertexWorker(RenderPipelineState *State, uint32_t InstanceIndex)
Worker thread entry point for vertex shaders.
static Vec4 getPosition(const VertexOutput &Out)
Helper function to get the position from vertex output builtin data.
void buildPendingFragments(const DrawCommandBase &Cmd, int XMinFB, int XMaxFB, int YMinFB, int YMaxFB)
Helper function to build list of pending fragments in a bounding box.
static uint32_t NextBreakpoint
Index of the next breakpoint to create.
bool quit(const std::vector< std::string > &Args)
bool Continue
True when the user has used continue command.
std::vector< Dim3 > PendingGroups
Pool of group IDs pending creation and execution.
void runTriangleFragmentWorker(TrianglePrimitive Primitive, const PipelineContext &PC, const RenderPassInstance &RPI, const VkViewport &Viewport)
Worker thread entry point for triangle rasterization.
unsigned NumThreads
The number of worker threads currently executing.
State to be carried through the execution of a render pipeline.
bool Interactive
True when interactive mode is enabled.
Internal structure to hold fragment data.