diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 9d981375ee..e5332e05e3 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -77,6 +77,7 @@ PStatCollector CLP(GraphicsStateGuardian)::_load_display_list_pcollector("Draw:T PStatCollector CLP(GraphicsStateGuardian)::_primitive_batches_display_list_pcollector("Primitive batches:Display lists"); PStatCollector CLP(GraphicsStateGuardian)::_vertices_display_list_pcollector("Vertices:Display lists"); PStatCollector CLP(GraphicsStateGuardian)::_vertices_immediate_pcollector("Vertices:Immediate mode"); +PStatCollector CLP(GraphicsStateGuardian)::_compute_dispatch_pcollector("Draw:Compute dispatch"); #ifdef OPENGLES_2 PT(Shader) CLP(GraphicsStateGuardian)::_default_shader = NULL; @@ -480,9 +481,9 @@ reset() { glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); } - GLCAT.error() << "gl-debug enabled.\n"; + GLCAT.debug() << "gl-debug enabled.\n"; } else { - GLCAT.error() << "gl-debug enabled, but NOT supported.\n"; + GLCAT.debug() << "gl-debug enabled, but NOT supported.\n"; } } else { GLCAT.debug() << "gl-debug NOT enabled.\n"; @@ -1705,12 +1706,16 @@ reset() { if (is_at_least_gl_version(4, 2) || has_extension("GL_ARB_shader_image_load_store")) { _glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC) get_extension_func("glBindImageTexture"); + _glMemoryBarrier = (PFNGLMEMORYBARRIERPROC) + get_extension_func("glMemoryBarrier"); glGetIntegerv(GL_MAX_IMAGE_UNITS, &_max_image_units); } else if (has_extension("GL_EXT_shader_image_load_store")) { _glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC) get_extension_func("glBindImageTextureEXT"); + _glMemoryBarrier = (PFNGLMEMORYBARRIERPROC) + get_extension_func("glMemoryBarrierEXT"); glGetIntegerv(GL_MAX_IMAGE_UNITS_EXT, &_max_image_units); } @@ -1730,6 +1735,19 @@ reset() { } #endif +#ifndef OPENGLES + _supports_get_program_binary = false; + + if (is_at_least_gl_version(4, 1) || has_extension("GL_ARB_get_program_binary")) { + _glGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC) + get_extension_func("glGetProgramBinary"); + + if (_glGetProgramBinary != NULL) { + _supports_get_program_binary = true; + } + } +#endif + report_my_gl_errors(); if (support_stencil) { @@ -4333,9 +4351,12 @@ end_occlusion_query() { //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: dispatch_compute(int num_groups_x, int num_groups_y, int num_groups_z) { + PStatTimer timer(_compute_dispatch_pcollector); nassertv(_supports_compute_shaders); nassertv(_current_shader_context != NULL); _glDispatchCompute(num_groups_x, num_groups_y, num_groups_z); + + maybe_gl_finish(); } //////////////////////////////////////////////////////////////////// @@ -8987,6 +9008,11 @@ specify_texture(CLP(TextureContext) *gtc) { glTexParameteri(target, GL_TEXTURE_MAG_FILTER, get_texture_filter_type(magfilter, true)); + if (!uses_mipmaps) { + // NVIDIA drivers complain if we don't do this. + glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, 0); + } + // Set anisotropic filtering. if (_supports_anisotropy) { PN_stdfloat anisotropy = tex->get_effective_anisotropic_degree(); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index 4f7cc182d2..af12e7c1ca 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -176,6 +176,8 @@ typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei co typedef void (APIENTRYP PFNGLBINDIMAGETEXTUREPROC) (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); typedef void (APIENTRYP PFNGLBINDIMAGETEXTURESPROC) (GLuint first, GLsizei count, const GLuint *textures); typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); +typedef void (APIENTRYP PFNGLMEMORYBARRIERPROC) (GLbitfield barriers); +typedef void (APIENTRYP PFNGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufsize, GLsizei *length, GLenum *binaryFormat, void *binary); #endif // OPENGLES #endif // __EDG__ @@ -534,6 +536,7 @@ protected: bool _supports_anisotropy; GLint _max_image_units; bool _supports_multi_bind; + bool _supports_get_program_binary; #ifdef OPENGLES bool _supports_depth24; @@ -702,6 +705,8 @@ public: PFNGLBINDIMAGETEXTUREPROC _glBindImageTexture; PFNGLBINDIMAGETEXTURESPROC _glBindImageTextures; PFNGLDISPATCHCOMPUTEPROC _glDispatchCompute; + PFNGLMEMORYBARRIERPROC _glMemoryBarrier; + PFNGLGETPROGRAMBINARYPROC _glGetProgramBinary; #endif // OPENGLES GLenum _edge_clamp; @@ -745,6 +750,7 @@ public: static PStatCollector _primitive_batches_display_list_pcollector; static PStatCollector _vertices_display_list_pcollector; static PStatCollector _vertices_immediate_pcollector; + static PStatCollector _compute_dispatch_pcollector; public: virtual TypeHandle get_type() const { diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index 54b6fbfcdd..1f79b90197 100755 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -1750,6 +1750,13 @@ glsl_compile_shader(GSG *gsg) { glsl_report_shader_errors(gsg, _glsl_teshader); } + // If we requested to retrieve the shader, we should indicate that before linking. +#if !defined(NDEBUG) && !defined(OPENGLES) + if (gl_dump_compiled_shaders && gsg->_supports_get_program_binary) { + gsg->_glProgramParameteri(_glsl_program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE); + } +#endif + gsg->_glLinkProgram(_glsl_program); GLint status; @@ -1760,9 +1767,36 @@ glsl_compile_shader(GSG *gsg) { return false; } + // Dump the binary if requested. +#if !defined(NDEBUG) && !defined(OPENGLES) + if (gl_dump_compiled_shaders && gsg->_supports_get_program_binary) { + GLint length = 0; + gsg->_glGetProgramiv(_glsl_program, GL_PROGRAM_BINARY_LENGTH, &length); + length += 2; + + char filename[64]; + static int gl_dump_count = 0; + sprintf(filename, "glsl_program%d.dump", gl_dump_count++); + + char *binary = new char[length]; + GLenum format; + GLsizei num_bytes; + gsg->_glGetProgramBinary(_glsl_program, length, &num_bytes, &format, (void*)binary); + + pofstream s; + s.open(filename, ios::out | ios::binary); + s.write(binary, num_bytes); + s.close(); + + GLCAT.info() + << "Dumped " << num_bytes << " bytes of program binary with format 0x" + << hex << format << dec << " to " << filename << "\n"; + delete[] binary; + } +#endif // NDEBUG + gsg->report_my_gl_errors(); return true; } #endif // OPENGLES_1 - diff --git a/panda/src/glstuff/glmisc_src.cxx b/panda/src/glstuff/glmisc_src.cxx index 0b9bcff9d7..5ec109cf75 100644 --- a/panda/src/glstuff/glmisc_src.cxx +++ b/panda/src/glstuff/glmisc_src.cxx @@ -198,6 +198,12 @@ ConfigVariableBool gl_cube_map_seamless "this is causing problems or if you simply don't need the " "functionality.")); +ConfigVariableBool gl_dump_compiled_shaders + ("gl-dump-compiled-shaders", false, + PRC_DESC("This configures Panda to dump the binary content of GLSL " + "programs to disk with a filename like glsl_program0.dump " + "into the current directory.")); + extern ConfigVariableBool gl_parallel_arrays; void CLP(init_classes)() { diff --git a/panda/src/glstuff/glmisc_src.h b/panda/src/glstuff/glmisc_src.h index d999172aa1..2daf5fab13 100644 --- a/panda/src/glstuff/glmisc_src.h +++ b/panda/src/glstuff/glmisc_src.h @@ -66,6 +66,7 @@ extern ConfigVariableBool gl_force_no_error; extern ConfigVariableBool gl_force_no_flush; extern ConfigVariableBool gl_separate_specular_color; extern ConfigVariableBool gl_cube_map_seamless; +extern ConfigVariableBool gl_dump_compiled_shaders; extern EXPCL_GL void CLP(init_classes)();