Skip to content

Commit 971a080

Browse files
committed
Redesign debug output for custom writers
1 parent afab09d commit 971a080

13 files changed

+639
-139
lines changed

CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,14 @@ add_library(
4545
"include/fg/ResourceEntry.inl"
4646
"include/fg/Blackboard.hpp"
4747
"include/fg/Blackboard.inl"
48+
"include/fg/GraphvizWriter.hpp"
4849
"include/fg/Fwd.hpp"
4950
"src/FrameGraph.cpp"
5051
"src/GraphNode.cpp"
5152
"src/PassNode.cpp"
5253
"src/ResourceNode.cpp"
53-
"src/ResourceEntry.cpp")
54+
"src/ResourceEntry.cpp"
55+
"src/GraphvizWriter.cpp")
5456

5557
target_include_directories(
5658
FrameGraph PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>

README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ This is a renderer agnostic implementation of **FrameGraph**, inspired by the **
1616
- [Blackboard](#blackboard)
1717
- [Automatic resource bindings and barriers](#automatic-resource-bindings-and-barriers)
1818
- [Visualization](#visualization)
19+
- [Custom writer](#custom-writer)
1920
- [Installation](#installation)
2021
- [Example](#example)
2122
- [License](#license)
@@ -239,12 +240,39 @@ fg.addCallbackPass<Data>(
239240
### Visualization
240241

241242
```cpp
243+
// Built in graphviz writer.
242244
std::ofstream{"fg.dot"} << fg;
243245
```
244246
245247
![graph](media/deferred_pipeline.svg)
246248
_(Graph created by one of tests)_
247249
250+
#### Custom writer
251+
252+
Implement a struct with the following methods:
253+
254+
```cpp
255+
struct JsonWriter {
256+
nlohmann::json j;
257+
258+
void operator()(const PassNode &node,
259+
const std::vector<ResourceNode> &resourceNodes) {
260+
// ...
261+
}
262+
void operator()(const ResourceNode &node, const ResourceEntry &entry,
263+
const std::vector<PassNode> &passNodes) {
264+
// ...
265+
}
266+
267+
void flush(std::ostream &os) const { os << std::setw(2) << j << "\n"; }
268+
};
269+
```
270+
271+
```cpp
272+
std::ofstream f{"fg.json"};
273+
fg.debugOutput(f, JsonWriter{});
274+
```
275+
248276
## Installation
249277
250278
```bash

include/fg/FrameGraph.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ class FrameGraph {
8484
/** Invokes execution callbacks. */
8585
void execute(void *context = nullptr, void *allocator = nullptr);
8686

87-
void exportGraphviz(std::ostream &) const;
87+
template <class Writer>
88+
std::ostream &debugOutput(std::ostream &, Writer &&) const;
8889

8990
private:
9091
[[nodiscard]] PassNode &

include/fg/FrameGraph.inl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,19 @@ inline FrameGraphResource FrameGraph::import(const std::string_view name,
3939
return _createResourceNode(name, resourceId).m_id;
4040
}
4141

42+
template <class Writer>
43+
inline std::ostream &FrameGraph::debugOutput(std::ostream &os,
44+
Writer &&writer) const {
45+
for (const auto &node : m_passNodes) {
46+
writer(node, m_resourceNodes);
47+
}
48+
for (const auto &node : m_resourceNodes) {
49+
writer(node, m_resourceRegistry[node.m_resourceId], m_passNodes);
50+
}
51+
writer.flush(os);
52+
return os;
53+
}
54+
4255
_VIRTUALIZABLE_CONCEPT_IMPL
4356
inline FrameGraphResource FrameGraph::_create(const std::string_view name,
4457
typename T::Desc &&desc) {

include/fg/GraphNode.hpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33
#include <string>
44
#include <cstdint>
55

6+
class FrameGraph;
7+
68
class GraphNode {
9+
friend class FrameGraph;
10+
711
public:
812
GraphNode() = delete;
913
GraphNode(const GraphNode &) = delete;
@@ -13,10 +17,14 @@ class GraphNode {
1317
GraphNode &operator=(const GraphNode &) = delete;
1418
GraphNode &operator=(GraphNode &&) noexcept = delete;
1519

20+
[[nodiscard]] auto getId() const { return m_id; }
21+
[[nodiscard]] std::string_view getName() const { return m_name; }
22+
[[nodiscard]] auto getRefCount() const { return m_refCount; }
23+
1624
protected:
1725
GraphNode(const std::string_view name, uint32_t id);
1826

19-
protected:
27+
private:
2028
const std::string m_name;
2129
const uint32_t m_id; // Unique id, matches an array index in FrameGraph
2230
int32_t m_refCount{0};

include/fg/GraphvizWriter.hpp

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
#pragma once
2+
3+
#include "fg/ResourceNode.hpp"
4+
#include "fg/ResourceEntry.hpp"
5+
6+
namespace graphviz {
7+
8+
// https://graphviz.org/doc/info/colors.html
9+
enum class Color : uint8_t {
10+
aliceblue,
11+
antiquewhite,
12+
aqua,
13+
aquamarine,
14+
azure,
15+
beige,
16+
bisque,
17+
black,
18+
blanchedalmond,
19+
blue,
20+
blueviolet,
21+
brown,
22+
burlywood,
23+
cadetblue,
24+
chartreuse,
25+
chocolate,
26+
coral,
27+
cornflowerblue,
28+
cornsilk,
29+
crimson,
30+
cyan,
31+
darkblue,
32+
darkcyan,
33+
darkgoldenrod,
34+
darkgray,
35+
darkgreen,
36+
darkgrey,
37+
darkkhaki,
38+
darkmagenta,
39+
darkolivegreen,
40+
darkorange,
41+
darkorchid,
42+
darkred,
43+
darksalmon,
44+
darkseagreen,
45+
darkslateblue,
46+
darkslategray,
47+
darkslategrey,
48+
darkturquoise,
49+
darkviolet,
50+
deeppink,
51+
deepskyblue,
52+
dimgray,
53+
dimgrey,
54+
dodgerblue,
55+
firebrick,
56+
floralwhite,
57+
forestgreen,
58+
fuchsia,
59+
gainsboro,
60+
ghostwhite,
61+
gold,
62+
goldenrod,
63+
gray,
64+
grey,
65+
green,
66+
greenyellow,
67+
honeydew,
68+
hotpink,
69+
indianred,
70+
indigo,
71+
ivory,
72+
khaki,
73+
lavender,
74+
lavenderblush,
75+
lawngreen,
76+
lemonchiffon,
77+
lightblue,
78+
lightcoral,
79+
lightcyan,
80+
lightgoldenrodyellow,
81+
lightgray,
82+
lightgreen,
83+
lightgrey,
84+
lightpink,
85+
lightsalmon,
86+
lightseagreen,
87+
lightskyblue,
88+
lightslategray,
89+
lightslategrey,
90+
lightsteelblue,
91+
lightyellow,
92+
lime,
93+
limegreen,
94+
linen,
95+
magenta,
96+
maroon,
97+
mediumaquamarine,
98+
mediumblue,
99+
mediumorchid,
100+
mediumpurple,
101+
mediumseagreen,
102+
mediumslateblue,
103+
mediumspringgreen,
104+
mediumturquoise,
105+
mediumvioletred,
106+
midnightblue,
107+
mintcream,
108+
mistyrose,
109+
moccasin,
110+
navajowhite,
111+
navy,
112+
oldlace,
113+
olive,
114+
olivedrab,
115+
orange,
116+
orangered,
117+
orchid,
118+
palegoldenrod,
119+
palegreen,
120+
paleturquoise,
121+
palevioletred,
122+
papayawhip,
123+
peachpuff,
124+
peru,
125+
pink,
126+
plum,
127+
powderblue,
128+
purple,
129+
red,
130+
rosybrown,
131+
royalblue,
132+
saddlebrown,
133+
salmon,
134+
sandybrown,
135+
seagreen,
136+
seashell,
137+
sienna,
138+
silver,
139+
skyblue,
140+
slateblue,
141+
slategray,
142+
slategrey,
143+
snow,
144+
springgreen,
145+
steelblue,
146+
tan,
147+
teal,
148+
thistle,
149+
tomato,
150+
turquoise,
151+
violet,
152+
wheat,
153+
white,
154+
whitesmoke,
155+
yellow,
156+
yellowgreen,
157+
};
158+
enum class RankDir : uint8_t { TB, BT, LR, RL };
159+
160+
struct Graph {
161+
struct Style {
162+
RankDir rankDir{RankDir::TB};
163+
struct Font {
164+
std::string_view name{"helvetica"};
165+
uint16_t size{10};
166+
};
167+
Font font;
168+
};
169+
const Style style;
170+
171+
#ifdef __GNUG__
172+
static constexpr Style defaultStyle() { return Style{}; }
173+
explicit Graph(Style = defaultStyle());
174+
#else
175+
explicit Graph(Style = {});
176+
#endif
177+
178+
struct Vertex {
179+
std::string key;
180+
std::string label;
181+
Color fillcolor;
182+
std::vector<std::string> cluster;
183+
};
184+
std::vector<Vertex> vertices;
185+
186+
struct Edge {
187+
std::string key;
188+
Color color;
189+
std::vector<std::string> vertices;
190+
};
191+
std::vector<Edge> edges;
192+
193+
std::vector<uint32_t> imported;
194+
};
195+
196+
struct Writer {
197+
struct Colors {
198+
struct {
199+
Color executed{Color::orange};
200+
Color culled{Color::lightgray};
201+
} pass;
202+
struct {
203+
Color imported{Color::lightsteelblue};
204+
Color transient{Color::skyblue};
205+
} resource;
206+
struct {
207+
Color read{Color::yellowgreen};
208+
Color write{Color::orangered};
209+
} edge;
210+
};
211+
const Colors colors;
212+
213+
Graph graph{};
214+
215+
void operator()(const PassNode &, const std::vector<ResourceNode> &);
216+
void operator()(const ResourceNode &, const ResourceEntry &,
217+
const std::vector<PassNode> &);
218+
219+
void flush(std::ostream &) const;
220+
};
221+
222+
} // namespace graphviz

include/fg/PassNode.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ class PassNode final : public GraphNode {
2424
[[nodiscard]] bool hasSideEffect() const;
2525
[[nodiscard]] bool canExecute() const;
2626

27+
struct Create {};
28+
[[nodiscard]] decltype(auto) each(const Create) const { return m_creates; }
29+
struct Read {};
30+
[[nodiscard]] decltype(auto) each(const Read) const { return m_reads; }
31+
struct Write {};
32+
[[nodiscard]] decltype(auto) each(const Write) const { return m_writes; }
33+
2734
private:
2835
PassNode(const std::string_view name, uint32_t id,
2936
std::unique_ptr<FrameGraphPassConcept> &&);

include/fg/ResourceEntry.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class ResourceEntry final {
3131
m_concept->preWrite(flags, context);
3232
}
3333

34+
[[nodiscard]] uint32_t getId() const;
3435
[[nodiscard]] uint32_t getVersion() const;
3536
[[nodiscard]] bool isImported() const;
3637
[[nodiscard]] bool isTransient() const;

include/fg/ResourceNode.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ constexpr uint32_t kResourceInitialVersion{1u};
77
class ResourceNode final : public GraphNode {
88
friend class FrameGraph;
99

10+
public:
11+
[[nodiscard]] auto getResourceId() const { return m_resourceId; }
12+
[[nodiscard]] auto getVersion() const { return m_version; }
13+
14+
private:
1015
ResourceNode(const std::string_view name, uint32_t id, uint32_t resourceId,
1116
uint32_t version);
1217

0 commit comments

Comments
 (0)