Skip to content

Commit c18cdcf

Browse files
committed
display: add support for debug markers, to help with debugging
This is useful when running Panda in a tool like apitrace, so that the different calls in a frame are ordered in a neat hierarchy.
1 parent b1eec5f commit c18cdcf

13 files changed

+139
-12
lines changed

panda/src/display/displayRegion.I

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,14 @@ get_draw_region_pcollector() {
523523
return _draw_region_pcollector;
524524
}
525525

526+
/**
527+
* Returns a unique name used for debugging.
528+
*/
529+
INLINE const std::string &DisplayRegion::
530+
get_debug_name() const {
531+
return _debug_name;
532+
}
533+
526534
/**
527535
*
528536
*/

panda/src/display/displayRegion.cxx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,7 @@ do_compute_pixels(int i, int x_size, int y_size, CData *cdata) {
677677
*/
678678
void DisplayRegion::
679679
set_active_index(int index) {
680-
#ifdef DO_PSTATS
680+
#if defined(DO_PSTATS) || !defined(NDEBUG)
681681
std::ostringstream strm;
682682

683683
// To make a more useful name for PStats and debug output, we add the scene
@@ -697,10 +697,12 @@ set_active_index(int index) {
697697
// And add the index in case we have two scene graphs with the same name.
698698
strm << "#" << index;
699699

700-
string name = strm.str();
700+
_debug_name = strm.str();
701+
#endif
701702

702-
_cull_region_pcollector = PStatCollector(_window->get_cull_window_pcollector(), name);
703-
_draw_region_pcollector = PStatCollector(_window->get_draw_window_pcollector(), name);
703+
#ifdef DO_PSTATS
704+
_cull_region_pcollector = PStatCollector(_window->get_cull_window_pcollector(), _debug_name);
705+
_draw_region_pcollector = PStatCollector(_window->get_draw_window_pcollector(), _debug_name);
704706
#endif // DO_PSTATS
705707
}
706708

panda/src/display/displayRegion.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,8 @@ class EXPCL_PANDA_DISPLAY DisplayRegion : public TypedReferenceCount, public Dra
184184
INLINE PStatCollector &get_cull_region_pcollector();
185185
INLINE PStatCollector &get_draw_region_pcollector();
186186

187+
INLINE const std::string &get_debug_name() const;
188+
187189
struct Region {
188190
INLINE Region();
189191

@@ -277,6 +279,7 @@ class EXPCL_PANDA_DISPLAY DisplayRegion : public TypedReferenceCount, public Dra
277279

278280
PStatCollector _cull_region_pcollector;
279281
PStatCollector _draw_region_pcollector;
282+
std::string _debug_name;
280283

281284
public:
282285
static TypeHandle get_class_type() {

panda/src/display/graphicsEngine.cxx

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,7 +1174,8 @@ extract_texture_data(Texture *tex, GraphicsStateGuardian *gsg) {
11741174
*/
11751175
void GraphicsEngine::
11761176
dispatch_compute(const LVecBase3i &work_groups, const ShaderAttrib *sattr, GraphicsStateGuardian *gsg) {
1177-
nassertv(sattr->get_shader() != nullptr);
1177+
const Shader *shader = sattr->get_shader();
1178+
nassertv(shader != nullptr);
11781179
nassertv(gsg != nullptr);
11791180

11801181
ReMutexHolder holder(_lock);
@@ -1184,8 +1185,10 @@ dispatch_compute(const LVecBase3i &work_groups, const ShaderAttrib *sattr, Graph
11841185
string draw_name = gsg->get_threading_model().get_draw_name();
11851186
if (draw_name.empty()) {
11861187
// A single-threaded environment. No problem.
1188+
gsg->push_group_marker(std::string("Compute ") + shader->get_filename(Shader::ST_compute).get_basename());
11871189
gsg->set_state_and_transform(state, TransformState::make_identity());
11881190
gsg->dispatch_compute(work_groups[0], work_groups[1], work_groups[2]);
1191+
gsg->pop_group_marker();
11891192

11901193
} else {
11911194
// A multi-threaded environment. We have to wait until the draw thread
@@ -1434,7 +1437,9 @@ cull_and_draw_together(GraphicsEngine::Windows wlist,
14341437
if (win->is_any_clear_active()) {
14351438
GraphicsStateGuardian *gsg = win->get_gsg();
14361439
PStatGPUTimer timer(gsg, win->get_clear_window_pcollector(), current_thread);
1440+
gsg->push_group_marker("Clear");
14371441
win->clear(current_thread);
1442+
gsg->pop_group_marker();
14381443
}
14391444

14401445
int num_display_regions = win->get_num_active_display_regions();
@@ -1472,6 +1477,8 @@ cull_and_draw_together(GraphicsOutput *win, DisplayRegion *dr,
14721477
GraphicsStateGuardian *gsg = win->get_gsg();
14731478
nassertv(gsg != nullptr);
14741479

1480+
gsg->push_group_marker(dr->get_debug_name());
1481+
14751482
PT(SceneSetup) scene_setup;
14761483

14771484
{
@@ -1517,6 +1524,8 @@ cull_and_draw_together(GraphicsOutput *win, DisplayRegion *dr,
15171524
gsg->end_scene();
15181525
}
15191526
}
1527+
1528+
gsg->pop_group_marker();
15201529
}
15211530

15221531
/**
@@ -1658,7 +1667,9 @@ draw_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
16581667
PStatGPUTimer timer(gsg, win->get_draw_window_pcollector(), current_thread);
16591668
if (win->is_any_clear_active()) {
16601669
PStatGPUTimer timer(gsg, win->get_clear_window_pcollector(), current_thread);
1670+
win->get_gsg()->push_group_marker("Clear");
16611671
win->clear(current_thread);
1672+
win->get_gsg()->pop_group_marker();
16621673
}
16631674

16641675
if (display_cat.is_spam()) {
@@ -2008,6 +2019,8 @@ do_draw(GraphicsOutput *win, GraphicsStateGuardian *gsg, DisplayRegion *dr, Thre
20082019
// Statistics
20092020
PStatGPUTimer timer(gsg, dr->get_draw_region_pcollector(), current_thread);
20102021

2022+
gsg->push_group_marker(dr->get_debug_name());
2023+
20112024
PT(CullResult) cull_result;
20122025
PT(SceneSetup) scene_setup;
20132026
{
@@ -2043,11 +2056,7 @@ do_draw(GraphicsOutput *win, GraphicsStateGuardian *gsg, DisplayRegion *dr, Thre
20432056
// We don't trust the state the callback may have left us in.
20442057
gsg->clear_state_and_transform();
20452058

2046-
// The callback has taken care of the drawing.
2047-
return;
2048-
}
2049-
2050-
if (cull_result == nullptr || scene_setup == nullptr) {
2059+
} else if (cull_result == nullptr || scene_setup == nullptr) {
20512060
// Nothing to see here.
20522061

20532062
} else if (dr->is_stereo()) {
@@ -2068,6 +2077,8 @@ do_draw(GraphicsOutput *win, GraphicsStateGuardian *gsg, DisplayRegion *dr, Thre
20682077
gsg->end_scene();
20692078
}
20702079
}
2080+
2081+
gsg->pop_group_marker();
20712082
}
20722083

20732084
/**
@@ -2677,8 +2688,14 @@ thread_main() {
26772688

26782689
case TS_do_compute:
26792690
nassertd(_gsg != nullptr && _state != nullptr) break;
2680-
_gsg->set_state_and_transform(_state, TransformState::make_identity());
2681-
_gsg->dispatch_compute(_work_groups[0], _work_groups[1], _work_groups[2]);
2691+
{
2692+
const ShaderAttrib *sattr;
2693+
_state->get_attrib(sattr);
2694+
_gsg->push_group_marker(std::string("Compute ") + sattr->get_shader()->get_filename(Shader::ST_compute).get_basename());
2695+
_gsg->set_state_and_transform(_state, TransformState::make_identity());
2696+
_gsg->dispatch_compute(_work_groups[0], _work_groups[1], _work_groups[2]);
2697+
_gsg->pop_group_marker();
2698+
}
26822699
break;
26832700

26842701
case TS_do_extract:

panda/src/glstuff/glGraphicsBuffer_src.cxx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,9 @@ begin_frame(FrameMode mode, Thread *current_thread) {
230230
}
231231
}
232232

233+
CLP(GraphicsStateGuardian) *glgsg = (CLP(GraphicsStateGuardian) *)_gsg.p();
234+
glgsg->push_group_marker(std::string(CLASSPREFIX_QUOTED "GraphicsBuffer ") + get_name());
235+
233236
// Figure out the desired size of the buffer.
234237
if (mode == FM_render) {
235238
clear_cube_map_selection();
@@ -255,6 +258,7 @@ begin_frame(FrameMode mode, Thread *current_thread) {
255258
if (_needs_rebuild) {
256259
// If we still need rebuild, something went wrong with
257260
// rebuild_bitplanes().
261+
glgsg->pop_group_marker();
258262
return false;
259263
}
260264

@@ -1314,6 +1318,8 @@ end_frame(FrameMode mode, Thread *current_thread) {
13141318
clear_cube_map_selection();
13151319
}
13161320
report_my_gl_errors();
1321+
1322+
glgsg->pop_group_marker();
13171323
}
13181324

13191325
/**

panda/src/glstuff/glGraphicsStateGuardian_src.I

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,30 @@
1111
* @date 1999-02-02
1212
*/
1313

14+
/**
15+
* If debug markers are enabled, pushes the beginning of a group marker.
16+
*/
17+
INLINE void CLP(GraphicsStateGuardian)::
18+
push_group_marker(const std::string &marker) {
19+
#if !defined(NDEBUG) && !defined(OPENGLES_1)
20+
if (_glPushGroupMarker != nullptr) {
21+
_glPushGroupMarker(marker.size(), marker.data());
22+
}
23+
#endif
24+
}
25+
26+
/**
27+
* If debug markers are enabled, closes a group debug marker.
28+
*/
29+
INLINE void CLP(GraphicsStateGuardian)::
30+
pop_group_marker() {
31+
#if !defined(NDEBUG) && !defined(OPENGLES_1)
32+
if (_glPopGroupMarker != nullptr) {
33+
_glPopGroupMarker();
34+
}
35+
#endif
36+
}
37+
1438
/**
1539
* Checks for any outstanding error codes and outputs them, if found. If
1640
* NDEBUG is defined, this function does nothing. The return value is true if

panda/src/glstuff/glGraphicsStateGuardian_src.cxx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,22 @@ reset() {
616616
// Print out a list of all extensions.
617617
report_extensions();
618618

619+
// Check if we are running under a profiling tool such as apitrace.
620+
#if !defined(NDEBUG) && !defined(OPENGLES_1)
621+
if (has_extension("GL_EXT_debug_marker")) {
622+
_glPushGroupMarker = (PFNGLPUSHGROUPMARKEREXTPROC)
623+
get_extension_func("glPushGroupMarkerEXT");
624+
_glPopGroupMarker = (PFNGLPOPGROUPMARKEREXTPROC)
625+
get_extension_func("glPopGroupMarkerEXT");
626+
627+
// Start a group right away.
628+
push_group_marker("reset");
629+
} else {
630+
_glPushGroupMarker = nullptr;
631+
_glPopGroupMarker = nullptr;
632+
}
633+
#endif
634+
619635
// Initialize OpenGL debugging output first, if enabled and supported.
620636
_supports_debug = false;
621637
_use_object_labels = false;
@@ -3373,6 +3389,8 @@ reset() {
33733389
}
33743390
#endif
33753391

3392+
pop_group_marker();
3393+
33763394
// Now that the GSG has been initialized, make it available for
33773395
// optimizations.
33783396
add_gsg(this);

panda/src/glstuff/glGraphicsStateGuardian_src.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,9 @@ class EXPCL_GL CLP(GraphicsStateGuardian) : public GraphicsStateGuardian {
275275

276276
static void APIENTRY debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, GLvoid *userParam);
277277

278+
INLINE virtual void push_group_marker(const std::string &marker) final;
279+
INLINE virtual void pop_group_marker() final;
280+
278281
virtual void reset();
279282

280283
virtual void prepare_display_region(DisplayRegionPipelineReader *dr);
@@ -1091,6 +1094,11 @@ class EXPCL_GL CLP(GraphicsStateGuardian) : public GraphicsStateGuardian {
10911094
GLuint _white_texture;
10921095

10931096
#ifndef NDEBUG
1097+
#ifndef OPENGLES_1
1098+
PFNGLPUSHGROUPMARKEREXTPROC _glPushGroupMarker;
1099+
PFNGLPOPGROUPMARKEREXTPROC _glPopGroupMarker;
1100+
#endif
1101+
10941102
bool _show_texture_usage;
10951103
int _show_texture_usage_max_size;
10961104
int _show_texture_usage_index;

panda/src/glxdisplay/glxGraphicsWindow.cxx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ begin_frame(FrameMode mode, Thread *current_thread) {
8989
glxgsg->reset_if_new();
9090

9191
if (mode == FM_render) {
92+
glxgsg->push_group_marker(std::string("glxGraphicsWindow ") + get_name());
9293
// begin_render_texture();
9394
clear_cube_map_selection();
9495
}
@@ -97,6 +98,34 @@ begin_frame(FrameMode mode, Thread *current_thread) {
9798
return _gsg->begin_frame(current_thread);
9899
}
99100

101+
102+
/**
103+
* This function will be called within the draw thread after rendering is
104+
* completed for a given frame. It should do whatever finalization is
105+
* required.
106+
*/
107+
void glxGraphicsWindow::
108+
end_frame(FrameMode mode, Thread *current_thread) {
109+
end_frame_spam(mode);
110+
nassertv(_gsg != nullptr);
111+
112+
if (mode == FM_render) {
113+
// end_render_texture();
114+
copy_to_textures();
115+
}
116+
117+
_gsg->end_frame(current_thread);
118+
119+
if (mode == FM_render) {
120+
trigger_flip();
121+
clear_cube_map_selection();
122+
123+
glxGraphicsStateGuardian *glxgsg;
124+
DCAST_INTO_V(glxgsg, _gsg);
125+
glxgsg->pop_group_marker();
126+
}
127+
}
128+
100129
/**
101130
* This function will be called within the draw thread after begin_flip() has
102131
* been called on all windows, to finish the exchange of the front and back

panda/src/glxdisplay/glxGraphicsWindow.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class glxGraphicsWindow : public x11GraphicsWindow {
3636
virtual ~glxGraphicsWindow() {};
3737

3838
virtual bool begin_frame(FrameMode mode, Thread *current_thread);
39+
virtual void end_frame(FrameMode mode, Thread *current_thread);
3940
virtual void end_flip();
4041

4142
protected:

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy