mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-29 08:15:18 -04:00
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.
This commit is contained in:
parent
b1eec5fae0
commit
c18cdcf36e
@ -523,6 +523,14 @@ get_draw_region_pcollector() {
|
||||
return _draw_region_pcollector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a unique name used for debugging.
|
||||
*/
|
||||
INLINE const std::string &DisplayRegion::
|
||||
get_debug_name() const {
|
||||
return _debug_name;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -677,7 +677,7 @@ do_compute_pixels(int i, int x_size, int y_size, CData *cdata) {
|
||||
*/
|
||||
void DisplayRegion::
|
||||
set_active_index(int index) {
|
||||
#ifdef DO_PSTATS
|
||||
#if defined(DO_PSTATS) || !defined(NDEBUG)
|
||||
std::ostringstream strm;
|
||||
|
||||
// To make a more useful name for PStats and debug output, we add the scene
|
||||
@ -697,10 +697,12 @@ set_active_index(int index) {
|
||||
// And add the index in case we have two scene graphs with the same name.
|
||||
strm << "#" << index;
|
||||
|
||||
string name = strm.str();
|
||||
_debug_name = strm.str();
|
||||
#endif
|
||||
|
||||
_cull_region_pcollector = PStatCollector(_window->get_cull_window_pcollector(), name);
|
||||
_draw_region_pcollector = PStatCollector(_window->get_draw_window_pcollector(), name);
|
||||
#ifdef DO_PSTATS
|
||||
_cull_region_pcollector = PStatCollector(_window->get_cull_window_pcollector(), _debug_name);
|
||||
_draw_region_pcollector = PStatCollector(_window->get_draw_window_pcollector(), _debug_name);
|
||||
#endif // DO_PSTATS
|
||||
}
|
||||
|
||||
|
@ -184,6 +184,8 @@ public:
|
||||
INLINE PStatCollector &get_cull_region_pcollector();
|
||||
INLINE PStatCollector &get_draw_region_pcollector();
|
||||
|
||||
INLINE const std::string &get_debug_name() const;
|
||||
|
||||
struct Region {
|
||||
INLINE Region();
|
||||
|
||||
@ -277,6 +279,7 @@ private:
|
||||
|
||||
PStatCollector _cull_region_pcollector;
|
||||
PStatCollector _draw_region_pcollector;
|
||||
std::string _debug_name;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
|
@ -1174,7 +1174,8 @@ extract_texture_data(Texture *tex, GraphicsStateGuardian *gsg) {
|
||||
*/
|
||||
void GraphicsEngine::
|
||||
dispatch_compute(const LVecBase3i &work_groups, const ShaderAttrib *sattr, GraphicsStateGuardian *gsg) {
|
||||
nassertv(sattr->get_shader() != nullptr);
|
||||
const Shader *shader = sattr->get_shader();
|
||||
nassertv(shader != nullptr);
|
||||
nassertv(gsg != nullptr);
|
||||
|
||||
ReMutexHolder holder(_lock);
|
||||
@ -1184,8 +1185,10 @@ dispatch_compute(const LVecBase3i &work_groups, const ShaderAttrib *sattr, Graph
|
||||
string draw_name = gsg->get_threading_model().get_draw_name();
|
||||
if (draw_name.empty()) {
|
||||
// A single-threaded environment. No problem.
|
||||
gsg->push_group_marker(std::string("Compute ") + shader->get_filename(Shader::ST_compute).get_basename());
|
||||
gsg->set_state_and_transform(state, TransformState::make_identity());
|
||||
gsg->dispatch_compute(work_groups[0], work_groups[1], work_groups[2]);
|
||||
gsg->pop_group_marker();
|
||||
|
||||
} else {
|
||||
// A multi-threaded environment. We have to wait until the draw thread
|
||||
@ -1434,7 +1437,9 @@ cull_and_draw_together(GraphicsEngine::Windows wlist,
|
||||
if (win->is_any_clear_active()) {
|
||||
GraphicsStateGuardian *gsg = win->get_gsg();
|
||||
PStatGPUTimer timer(gsg, win->get_clear_window_pcollector(), current_thread);
|
||||
gsg->push_group_marker("Clear");
|
||||
win->clear(current_thread);
|
||||
gsg->pop_group_marker();
|
||||
}
|
||||
|
||||
int num_display_regions = win->get_num_active_display_regions();
|
||||
@ -1472,6 +1477,8 @@ cull_and_draw_together(GraphicsOutput *win, DisplayRegion *dr,
|
||||
GraphicsStateGuardian *gsg = win->get_gsg();
|
||||
nassertv(gsg != nullptr);
|
||||
|
||||
gsg->push_group_marker(dr->get_debug_name());
|
||||
|
||||
PT(SceneSetup) scene_setup;
|
||||
|
||||
{
|
||||
@ -1517,6 +1524,8 @@ cull_and_draw_together(GraphicsOutput *win, DisplayRegion *dr,
|
||||
gsg->end_scene();
|
||||
}
|
||||
}
|
||||
|
||||
gsg->pop_group_marker();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1658,7 +1667,9 @@ draw_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
|
||||
PStatGPUTimer timer(gsg, win->get_draw_window_pcollector(), current_thread);
|
||||
if (win->is_any_clear_active()) {
|
||||
PStatGPUTimer timer(gsg, win->get_clear_window_pcollector(), current_thread);
|
||||
win->get_gsg()->push_group_marker("Clear");
|
||||
win->clear(current_thread);
|
||||
win->get_gsg()->pop_group_marker();
|
||||
}
|
||||
|
||||
if (display_cat.is_spam()) {
|
||||
@ -2008,6 +2019,8 @@ do_draw(GraphicsOutput *win, GraphicsStateGuardian *gsg, DisplayRegion *dr, Thre
|
||||
// Statistics
|
||||
PStatGPUTimer timer(gsg, dr->get_draw_region_pcollector(), current_thread);
|
||||
|
||||
gsg->push_group_marker(dr->get_debug_name());
|
||||
|
||||
PT(CullResult) cull_result;
|
||||
PT(SceneSetup) scene_setup;
|
||||
{
|
||||
@ -2043,11 +2056,7 @@ do_draw(GraphicsOutput *win, GraphicsStateGuardian *gsg, DisplayRegion *dr, Thre
|
||||
// We don't trust the state the callback may have left us in.
|
||||
gsg->clear_state_and_transform();
|
||||
|
||||
// The callback has taken care of the drawing.
|
||||
return;
|
||||
}
|
||||
|
||||
if (cull_result == nullptr || scene_setup == nullptr) {
|
||||
} else if (cull_result == nullptr || scene_setup == nullptr) {
|
||||
// Nothing to see here.
|
||||
|
||||
} else if (dr->is_stereo()) {
|
||||
@ -2068,6 +2077,8 @@ do_draw(GraphicsOutput *win, GraphicsStateGuardian *gsg, DisplayRegion *dr, Thre
|
||||
gsg->end_scene();
|
||||
}
|
||||
}
|
||||
|
||||
gsg->pop_group_marker();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2677,8 +2688,14 @@ thread_main() {
|
||||
|
||||
case TS_do_compute:
|
||||
nassertd(_gsg != nullptr && _state != nullptr) break;
|
||||
_gsg->set_state_and_transform(_state, TransformState::make_identity());
|
||||
_gsg->dispatch_compute(_work_groups[0], _work_groups[1], _work_groups[2]);
|
||||
{
|
||||
const ShaderAttrib *sattr;
|
||||
_state->get_attrib(sattr);
|
||||
_gsg->push_group_marker(std::string("Compute ") + sattr->get_shader()->get_filename(Shader::ST_compute).get_basename());
|
||||
_gsg->set_state_and_transform(_state, TransformState::make_identity());
|
||||
_gsg->dispatch_compute(_work_groups[0], _work_groups[1], _work_groups[2]);
|
||||
_gsg->pop_group_marker();
|
||||
}
|
||||
break;
|
||||
|
||||
case TS_do_extract:
|
||||
|
@ -230,6 +230,9 @@ begin_frame(FrameMode mode, Thread *current_thread) {
|
||||
}
|
||||
}
|
||||
|
||||
CLP(GraphicsStateGuardian) *glgsg = (CLP(GraphicsStateGuardian) *)_gsg.p();
|
||||
glgsg->push_group_marker(std::string(CLASSPREFIX_QUOTED "GraphicsBuffer ") + get_name());
|
||||
|
||||
// Figure out the desired size of the buffer.
|
||||
if (mode == FM_render) {
|
||||
clear_cube_map_selection();
|
||||
@ -255,6 +258,7 @@ begin_frame(FrameMode mode, Thread *current_thread) {
|
||||
if (_needs_rebuild) {
|
||||
// If we still need rebuild, something went wrong with
|
||||
// rebuild_bitplanes().
|
||||
glgsg->pop_group_marker();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1314,6 +1318,8 @@ end_frame(FrameMode mode, Thread *current_thread) {
|
||||
clear_cube_map_selection();
|
||||
}
|
||||
report_my_gl_errors();
|
||||
|
||||
glgsg->pop_group_marker();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -11,6 +11,30 @@
|
||||
* @date 1999-02-02
|
||||
*/
|
||||
|
||||
/**
|
||||
* If debug markers are enabled, pushes the beginning of a group marker.
|
||||
*/
|
||||
INLINE void CLP(GraphicsStateGuardian)::
|
||||
push_group_marker(const std::string &marker) {
|
||||
#if !defined(NDEBUG) && !defined(OPENGLES_1)
|
||||
if (_glPushGroupMarker != nullptr) {
|
||||
_glPushGroupMarker(marker.size(), marker.data());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* If debug markers are enabled, closes a group debug marker.
|
||||
*/
|
||||
INLINE void CLP(GraphicsStateGuardian)::
|
||||
pop_group_marker() {
|
||||
#if !defined(NDEBUG) && !defined(OPENGLES_1)
|
||||
if (_glPopGroupMarker != nullptr) {
|
||||
_glPopGroupMarker();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for any outstanding error codes and outputs them, if found. If
|
||||
* NDEBUG is defined, this function does nothing. The return value is true if
|
||||
|
@ -616,6 +616,22 @@ reset() {
|
||||
// Print out a list of all extensions.
|
||||
report_extensions();
|
||||
|
||||
// Check if we are running under a profiling tool such as apitrace.
|
||||
#if !defined(NDEBUG) && !defined(OPENGLES_1)
|
||||
if (has_extension("GL_EXT_debug_marker")) {
|
||||
_glPushGroupMarker = (PFNGLPUSHGROUPMARKEREXTPROC)
|
||||
get_extension_func("glPushGroupMarkerEXT");
|
||||
_glPopGroupMarker = (PFNGLPOPGROUPMARKEREXTPROC)
|
||||
get_extension_func("glPopGroupMarkerEXT");
|
||||
|
||||
// Start a group right away.
|
||||
push_group_marker("reset");
|
||||
} else {
|
||||
_glPushGroupMarker = nullptr;
|
||||
_glPopGroupMarker = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Initialize OpenGL debugging output first, if enabled and supported.
|
||||
_supports_debug = false;
|
||||
_use_object_labels = false;
|
||||
@ -3373,6 +3389,8 @@ reset() {
|
||||
}
|
||||
#endif
|
||||
|
||||
pop_group_marker();
|
||||
|
||||
// Now that the GSG has been initialized, make it available for
|
||||
// optimizations.
|
||||
add_gsg(this);
|
||||
|
@ -275,6 +275,9 @@ public:
|
||||
|
||||
static void APIENTRY debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, GLvoid *userParam);
|
||||
|
||||
INLINE virtual void push_group_marker(const std::string &marker) final;
|
||||
INLINE virtual void pop_group_marker() final;
|
||||
|
||||
virtual void reset();
|
||||
|
||||
virtual void prepare_display_region(DisplayRegionPipelineReader *dr);
|
||||
@ -1091,6 +1094,11 @@ public:
|
||||
GLuint _white_texture;
|
||||
|
||||
#ifndef NDEBUG
|
||||
#ifndef OPENGLES_1
|
||||
PFNGLPUSHGROUPMARKEREXTPROC _glPushGroupMarker;
|
||||
PFNGLPOPGROUPMARKEREXTPROC _glPopGroupMarker;
|
||||
#endif
|
||||
|
||||
bool _show_texture_usage;
|
||||
int _show_texture_usage_max_size;
|
||||
int _show_texture_usage_index;
|
||||
|
@ -89,6 +89,7 @@ begin_frame(FrameMode mode, Thread *current_thread) {
|
||||
glxgsg->reset_if_new();
|
||||
|
||||
if (mode == FM_render) {
|
||||
glxgsg->push_group_marker(std::string("glxGraphicsWindow ") + get_name());
|
||||
// begin_render_texture();
|
||||
clear_cube_map_selection();
|
||||
}
|
||||
@ -97,6 +98,34 @@ begin_frame(FrameMode mode, Thread *current_thread) {
|
||||
return _gsg->begin_frame(current_thread);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function will be called within the draw thread after rendering is
|
||||
* completed for a given frame. It should do whatever finalization is
|
||||
* required.
|
||||
*/
|
||||
void glxGraphicsWindow::
|
||||
end_frame(FrameMode mode, Thread *current_thread) {
|
||||
end_frame_spam(mode);
|
||||
nassertv(_gsg != nullptr);
|
||||
|
||||
if (mode == FM_render) {
|
||||
// end_render_texture();
|
||||
copy_to_textures();
|
||||
}
|
||||
|
||||
_gsg->end_frame(current_thread);
|
||||
|
||||
if (mode == FM_render) {
|
||||
trigger_flip();
|
||||
clear_cube_map_selection();
|
||||
|
||||
glxGraphicsStateGuardian *glxgsg;
|
||||
DCAST_INTO_V(glxgsg, _gsg);
|
||||
glxgsg->pop_group_marker();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will be called within the draw thread after begin_flip() has
|
||||
* been called on all windows, to finish the exchange of the front and back
|
||||
|
@ -36,6 +36,7 @@ public:
|
||||
virtual ~glxGraphicsWindow() {};
|
||||
|
||||
virtual bool begin_frame(FrameMode mode, Thread *current_thread);
|
||||
virtual void end_frame(FrameMode mode, Thread *current_thread);
|
||||
virtual void end_flip();
|
||||
|
||||
protected:
|
||||
|
@ -235,6 +235,9 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual void push_group_marker(const std::string &marker) {}
|
||||
virtual void pop_group_marker() {}
|
||||
|
||||
PUBLISHED:
|
||||
static GraphicsStateGuardianBase *get_default_gsg();
|
||||
static void set_default_gsg(GraphicsStateGuardianBase *default_gsg);
|
||||
|
@ -295,7 +295,10 @@ draw(Thread *current_thread) {
|
||||
nassertv(bin_index >= 0);
|
||||
|
||||
if (bin_index < (int)_bins.size() && _bins[bin_index] != nullptr) {
|
||||
|
||||
_gsg->push_group_marker(_bins[bin_index]->get_name());
|
||||
_bins[bin_index]->draw(force, current_thread);
|
||||
_gsg->pop_group_marker();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -87,6 +87,7 @@ begin_frame(FrameMode mode, Thread *current_thread) {
|
||||
wglgsg->reset_if_new();
|
||||
|
||||
if (mode == FM_render) {
|
||||
wglgsg->push_group_marker(std::string("wglGraphicsWindow ") + get_name());
|
||||
clear_cube_map_selection();
|
||||
}
|
||||
|
||||
@ -114,6 +115,10 @@ end_frame(FrameMode mode, Thread *current_thread) {
|
||||
if (mode == FM_render) {
|
||||
trigger_flip();
|
||||
clear_cube_map_selection();
|
||||
|
||||
wglGraphicsStateGuardian *wglgsg;
|
||||
DCAST_INTO_V(wglgsg, _gsg);
|
||||
wglgsg->pop_group_marker();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user