Disable error checking by default for a substantial performance increase

This commit is contained in:
rdb 2014-07-03 17:10:41 +00:00
parent e7fd70c2bc
commit a16b98a468
6 changed files with 74 additions and 35 deletions

View File

@ -45,7 +45,7 @@ report_errors(int line, const char *source_file) {
INLINE void CLP(GraphicsStateGuardian):: INLINE void CLP(GraphicsStateGuardian)::
report_my_errors(int line, const char *source_file) { report_my_errors(int line, const char *source_file) {
#ifndef NDEBUG #ifndef NDEBUG
if (_track_errors) { if (_check_errors) {
GLenum error_code = glGetError(); GLenum error_code = glGetError();
if (error_code != GL_NO_ERROR) { if (error_code != GL_NO_ERROR) {
if (!report_errors_loop(line, source_file, error_code, _error_count)) { if (!report_errors_loop(line, source_file, error_code, _error_count)) {
@ -83,7 +83,7 @@ clear_errors(int line, const char *source_file) {
// Access: Public // Access: Public
// Description: This works like report_my_errors(), except that it // Description: This works like report_my_errors(), except that it
// always runs, even in the NDEBUG case (but not when // always runs, even in the NDEBUG case (but not when
// _track_errors is false), and it never calls // _check_errors is false), and it never calls
// panic_deactivate(). It is designed to be called when // panic_deactivate(). It is designed to be called when
// it is important to clear the error stack (for // it is important to clear the error stack (for
// instance, because we want to be able to reliably // instance, because we want to be able to reliably
@ -91,7 +91,7 @@ clear_errors(int line, const char *source_file) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE void CLP(GraphicsStateGuardian):: INLINE void CLP(GraphicsStateGuardian)::
clear_my_errors(int line, const char *source_file) { clear_my_errors(int line, const char *source_file) {
if (_track_errors) { if (_check_errors) {
GLenum error_code = glGetError(); GLenum error_code = glGetError();
if (error_code != GL_NO_ERROR) { if (error_code != GL_NO_ERROR) {
int error_count = 0; int error_count = 0;

View File

@ -306,9 +306,9 @@ CLP(GraphicsStateGuardian)(GraphicsEngine *engine, GraphicsPipe *pipe) :
// the window tells us otherwise. // the window tells us otherwise.
_is_hardware = true; _is_hardware = true;
// calling glGetError() forces a sync, this turns it off if you want to. // calling glGetError() forces a sync, this turns it on if you want to.
_track_errors = !gl_force_no_error; _check_errors = gl_check_errors;
_allow_flush = !gl_force_no_flush; _force_flush = gl_force_flush;
#ifdef DO_PSTATS #ifdef DO_PSTATS
if (gl_finish) { if (gl_finish) {
@ -436,8 +436,8 @@ reset() {
report_extensions(); report_extensions();
// Initialize OpenGL debugging output first, if enabled and supported. // Initialize OpenGL debugging output first, if enabled and supported.
_supports_debug = false;
if (gl_debug) { if (gl_debug) {
bool supports_debug = false;
PFNGLDEBUGMESSAGECALLBACKPROC _glDebugMessageCallback; PFNGLDEBUGMESSAGECALLBACKPROC _glDebugMessageCallback;
PFNGLDEBUGMESSAGECONTROLPROC _glDebugMessageControl; PFNGLDEBUGMESSAGECONTROLPROC _glDebugMessageControl;
@ -454,17 +454,17 @@ reset() {
get_extension_func("glDebugMessageControl"); get_extension_func("glDebugMessageControl");
#endif #endif
glEnable(GL_DEBUG_OUTPUT); // Not supported in ARB version glEnable(GL_DEBUG_OUTPUT); // Not supported in ARB version
supports_debug = true; _supports_debug = true;
} else if (has_extension("GL_ARB_debug_output")) { } else if (has_extension("GL_ARB_debug_output")) {
_glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC) _glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC)
get_extension_func("glDebugMessageCallbackARB"); get_extension_func("glDebugMessageCallbackARB");
_glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC) _glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC)
get_extension_func("glDebugMessageControlARB"); get_extension_func("glDebugMessageControlARB");
supports_debug = true; _supports_debug = true;
} }
if (supports_debug) { if (_supports_debug) {
// Set the categories we want to listen to. // Set the categories we want to listen to.
_glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH, _glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH,
0, NULL, GLCAT.is_error()); 0, NULL, GLCAT.is_error());
@ -487,6 +487,11 @@ reset() {
} }
} else { } else {
GLCAT.debug() << "gl-debug NOT enabled.\n"; GLCAT.debug() << "gl-debug NOT enabled.\n";
// However, still check if it is supported.
_supports_debug = is_at_least_gl_version(4, 3)
|| has_extension("GL_KHR_debug")
|| has_extension("GL_ARB_debug_output");
} }
_supported_geom_rendering = _supported_geom_rendering =
@ -2503,14 +2508,46 @@ end_frame(Thread *current_thread) {
// necessary if this is a single-buffered visual, so that the frame // necessary if this is a single-buffered visual, so that the frame
// will be finished drawing before we return to the application. // will be finished drawing before we return to the application.
// It's not clear what effect this has on our total frame time. // It's not clear what effect this has on our total frame time.
if (_allow_flush) { if (_force_flush || _current_properties->is_single_buffered()) {
gl_flush(); gl_flush();
} }
maybe_gl_finish(); maybe_gl_finish();
report_my_gl_errors(); #ifndef NDEBUG
} if (_check_errors || (_supports_debug && gl_debug)) {
report_my_gl_errors();
} else {
// If _check_errors is false, we still want to check for errors
// once during this frame, so that we know if anything went wrong.
GLenum error_code = glGetError();
if (error_code != GL_NO_ERROR) {
int error_count = 0;
bool deactivate = !report_errors_loop(__LINE__, __FILE__, error_code, error_count);
if (error_count == 1) {
GLCAT.error()
<< "An OpenGL error (" << get_error_string(error_code)
<< ") has occurred.";
} else {
GLCAT.error()
<< error_count << " OpenGL errors have occurred.";
}
if (_supports_debug) {
GLCAT.error(false) << " Set gl-debug #t "
<< "in your PRC file to display more information.\n";
} else {
GLCAT.error(false) << " Set gl-check-errors #t "
<< "in your PRC file to display more information.\n";
}
if (deactivate) {
panic_deactivate();
}
}
}
#endif
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::begin_draw_primitives // Function: GLGraphicsStateGuardian::begin_draw_primitives
@ -3079,14 +3116,12 @@ disable_standard_vertex_arrays()
glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_COLOR_ARRAY);
GLPf(Color4)(1.0f, 1.0f, 1.0f, 1.0f); GLPf(Color4)(1.0f, 1.0f, 1.0f, 1.0f);
report_my_gl_errors();
for (int stage_index=0; stage_index < _last_max_stage_index; stage_index++) { for (int stage_index=0; stage_index < _last_max_stage_index; stage_index++) {
_glClientActiveTexture(GL_TEXTURE0 + stage_index); _glClientActiveTexture(GL_TEXTURE0 + stage_index);
glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY);
} }
_last_max_stage_index = 0; _last_max_stage_index = 0;
report_my_gl_errors();
#ifndef OPENGLES #ifndef OPENGLES
if (_supports_vertex_blend) { if (_supports_vertex_blend) {
@ -3764,7 +3799,6 @@ update_texture(TextureContext *tc, bool force) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian):: void CLP(GraphicsStateGuardian)::
release_texture(TextureContext *tc) { release_texture(TextureContext *tc) {
report_my_gl_errors();
CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc); CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
glDeleteTextures(1, &gtc->_index); glDeleteTextures(1, &gtc->_index);
@ -4380,6 +4414,8 @@ end_occlusion_query() {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian):: void CLP(GraphicsStateGuardian)::
dispatch_compute(int num_groups_x, int num_groups_y, int num_groups_z) { dispatch_compute(int num_groups_x, int num_groups_y, int num_groups_z) {
maybe_gl_finish();
PStatTimer timer(_compute_dispatch_pcollector); PStatTimer timer(_compute_dispatch_pcollector);
nassertv(_supports_compute_shaders); nassertv(_supports_compute_shaders);
nassertv(_current_shader_context != NULL); nassertv(_current_shader_context != NULL);
@ -5709,9 +5745,7 @@ draw_immediate_composite_primitives(const GeomPrimitivePipelineReader *reader, G
void CLP(GraphicsStateGuardian):: void CLP(GraphicsStateGuardian)::
gl_flush() const { gl_flush() const {
PStatTimer timer(_flush_pcollector); PStatTimer timer(_flush_pcollector);
if (_allow_flush) { glFlush();
glFlush();
}
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -5721,7 +5755,7 @@ gl_flush() const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
GLenum CLP(GraphicsStateGuardian):: GLenum CLP(GraphicsStateGuardian)::
gl_get_error() const { gl_get_error() const {
if (_track_errors) { if (_check_errors) {
return glGetError(); return glGetError();
} else { } else {
return GL_NO_ERROR; return GL_NO_ERROR;
@ -9666,9 +9700,9 @@ upload_texture_image(CLP(TextureContext) *gtc,
// object. // object.
if (GLCAT.is_debug()) { if (GLCAT.is_debug()) {
GLCAT.debug() GLCAT.debug()
<< "loading new texture object, " << width << " x " << height << "loading new texture object for " << tex->get_name() << ", " << width
<< " x " << depth << ", z = " << z << ", mipmaps " << num_ram_mipmap_levels << " x " << height << " x " << depth << ", z = " << z << ", mipmaps "
<< ", uses_mipmaps = " << uses_mipmaps << "\n"; << num_ram_mipmap_levels << ", uses_mipmaps = " << uses_mipmaps << "\n";
} }
if (num_ram_mipmap_levels == 0) { if (num_ram_mipmap_levels == 0) {

View File

@ -728,8 +728,9 @@ public:
//RenderState::SlotMask _inv_state_mask; //RenderState::SlotMask _inv_state_mask;
bool _track_errors; bool _check_errors;
bool _allow_flush; bool _force_flush;
bool _supports_debug;
#ifndef NDEBUG #ifndef NDEBUG
bool _show_texture_usage; bool _show_texture_usage;

View File

@ -1099,6 +1099,8 @@ update_shader_texture_bindings(ShaderContext *prev) {
return; return;
} }
_glgsg->_glMemoryBarrier(GL_ALL_BARRIER_BITS);
#ifndef OPENGLES #ifndef OPENGLES
// First bind all the 'image units'; a bit of an esoteric OpenGL feature right now. // First bind all the 'image units'; a bit of an esoteric OpenGL feature right now.
int num_image_units = min(_glsl_img_inputs.size(), (size_t)_glgsg->_max_image_units); int num_image_units = min(_glsl_img_inputs.size(), (size_t)_glgsg->_max_image_units);
@ -1316,7 +1318,6 @@ glsl_compile_entry_point(Shader::ShaderType type) {
return 0; return 0;
} }
_glgsg->report_my_gl_errors();
return handle; return handle;
} }
@ -1356,7 +1357,6 @@ glsl_compile_shader() {
glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES, &max_vertices); glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES, &max_vertices);
_glgsg->_glProgramParameteri(_glsl_program, GL_GEOMETRY_VERTICES_OUT_ARB, max_vertices); _glgsg->_glProgramParameteri(_glsl_program, GL_GEOMETRY_VERTICES_OUT_ARB, max_vertices);
#endif #endif
_glgsg->report_my_gl_errors();
} }
if (!_shader->get_text(Shader::ST_tess_control).empty()) { if (!_shader->get_text(Shader::ST_tess_control).empty()) {

View File

@ -173,13 +173,17 @@ ConfigVariableBool gl_matrix_palette
("gl-matrix-palette", false, ("gl-matrix-palette", false,
PRC_DESC("Temporary hack variable protecting untested code. See glGraphicsStateGuardian_src.cxx.")); PRC_DESC("Temporary hack variable protecting untested code. See glGraphicsStateGuardian_src.cxx."));
ConfigVariableBool gl_force_no_error ConfigVariableBool gl_check_errors
("gl-force-no-error", false, ("gl-check-errors", false,
PRC_DESC("Avoid reporting OpenGL errors, for a small performance benefit.")); PRC_DESC("Regularly call glGetError() to check for OpenGL errors. "
"This will slow down rendering significantly. If your "
"video driver supports it, you should use gl-debug instead."));
ConfigVariableBool gl_force_no_flush ConfigVariableBool gl_force_flush
("gl-force-no-flush", false, ("gl-force-flush", false,
PRC_DESC("Avoid calling glFlush(), for a potential performance benefit. This may be a little dangerous.")); PRC_DESC("Call this to force a call to glFlush() after rendering a "
"frame, even when using a double-buffered framebuffer. "
"This can incur a significant performance penalty."));
ConfigVariableBool gl_separate_specular_color ConfigVariableBool gl_separate_specular_color
("gl-separate-specular-color", true, ("gl-separate-specular-color", true,

View File

@ -62,8 +62,8 @@ extern ConfigVariableBool gl_debug_buffers;
extern ConfigVariableBool gl_finish; extern ConfigVariableBool gl_finish;
extern ConfigVariableBool gl_force_depth_stencil; extern ConfigVariableBool gl_force_depth_stencil;
extern ConfigVariableBool gl_matrix_palette; extern ConfigVariableBool gl_matrix_palette;
extern ConfigVariableBool gl_force_no_error; extern ConfigVariableBool gl_check_errors;
extern ConfigVariableBool gl_force_no_flush; extern ConfigVariableBool gl_force_flush;
extern ConfigVariableBool gl_separate_specular_color; extern ConfigVariableBool gl_separate_specular_color;
extern ConfigVariableBool gl_cube_map_seamless; extern ConfigVariableBool gl_cube_map_seamless;
extern ConfigVariableBool gl_dump_compiled_shaders; extern ConfigVariableBool gl_dump_compiled_shaders;