From dafae50ce26b89ffbdd6a154a273d17e5ebbbfeb Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 17 Jul 2015 15:55:24 +0200 Subject: [PATCH 01/12] Protect against self-move-assignment to fix stable_sort in MSVC --- panda/src/express/pointerToBase.I | 15 +++++++++------ panda/src/putil/copyOnWritePointer.I | 13 ++++++++----- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/panda/src/express/pointerToBase.I b/panda/src/express/pointerToBase.I index 783d59353e..ce319a5f50 100644 --- a/panda/src/express/pointerToBase.I +++ b/panda/src/express/pointerToBase.I @@ -71,14 +71,17 @@ PointerToBase(PointerToBase &&from) NOEXCEPT { template INLINE void PointerToBase:: reassign(PointerToBase &&from) NOEXCEPT { - To *old_ptr = (To *)this->_void_ptr; + // Protect against self-move-assignment. + if (from._void_ptr != this->_void_ptr) { + To *old_ptr = (To *)this->_void_ptr; - this->_void_ptr = from._void_ptr; - from._void_ptr = NULL; + this->_void_ptr = from._void_ptr; + from._void_ptr = NULL; - // Now delete the old pointer. - if (old_ptr != (To *)NULL) { - unref_delete(old_ptr); + // Now delete the old pointer. + if (old_ptr != (To *)NULL) { + unref_delete(old_ptr); + } } } #endif // USE_MOVE_SEMANTICS diff --git a/panda/src/putil/copyOnWritePointer.I b/panda/src/putil/copyOnWritePointer.I index d9c81d9de5..47e51fab15 100644 --- a/panda/src/putil/copyOnWritePointer.I +++ b/panda/src/putil/copyOnWritePointer.I @@ -102,12 +102,15 @@ CopyOnWritePointer(CopyOnWritePointer &&move) NOEXCEPT : //////////////////////////////////////////////////////////////////// INLINE void CopyOnWritePointer:: operator = (CopyOnWritePointer &&move) NOEXCEPT { - CopyOnWriteObject *old_object = _cow_object; - _cow_object = move._cow_object; - move._cow_object = NULL; + // Protect against self-move-assignment. + if (move._cow_object != _cow_object) { + CopyOnWriteObject *old_object = _cow_object; + _cow_object = move._cow_object; + move._cow_object = NULL; - if (old_object != (CopyOnWriteObject *)NULL) { - cache_unref_delete(old_object); + if (old_object != (CopyOnWriteObject *)NULL) { + cache_unref_delete(old_object); + } } } #endif // USE_MOVE_SEMANTICS From 946f273ebb6f30969bf7d099bf9a3fdd06cad64f Mon Sep 17 00:00:00 2001 From: Jeremy Koletar Date: Fri, 17 Jul 2015 13:39:41 -0500 Subject: [PATCH 02/12] controls: Don't make scene graph assumptions when setting the CollisionRay's height --- direct/src/controls/GravityWalker.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/direct/src/controls/GravityWalker.py b/direct/src/controls/GravityWalker.py index 5552168860..7c232e55f4 100755 --- a/direct/src/controls/GravityWalker.py +++ b/direct/src/controls/GravityWalker.py @@ -179,9 +179,9 @@ class GravityWalker(DirectObject.DirectObject): # a higher or lower value depending on whether you want an avatar # that is outside of the world to step up to the floor when they # get under valid floor: - cRay = CollisionRay(0.0, 0.0, CollisionHandlerRayStart, 0.0, 0.0, -1.0) + self.cRay = CollisionRay(0.0, 0.0, CollisionHandlerRayStart, 0.0, 0.0, -1.0) cRayNode = CollisionNode('GW.cRayNode') - cRayNode.addSolid(cRay) + cRayNode.addSolid(self.cRay) self.cRayNodePath = self.avatarNodePath.attachNewNode(cRayNode) cRayNode.setFromCollideMask(bitmask) cRayNode.setIntoCollideMask(BitMask32.allOff()) @@ -697,8 +697,4 @@ class GravityWalker(DirectObject.DirectObject): # There are sometimes issues if the collision ray height is # so tall that it collides with multiple levels of floors. def setCollisionRayHeight(self, height): - oldNode = self.avatarNodePath.getNode(0) - cRayNode = oldNode.getChild(2) - cRayNode.removeSolid(0) - cRay = CollisionRay(0.0, 0.0, height, 0.0, 0.0, -1.0) - cRayNode.addSolid(cRay) \ No newline at end of file + self.cRay.setOrigin(0.0, 0.0, height) From 221507437a4be6d3b9c0b3295d67f05b5ebad2e2 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 17 Jul 2015 21:28:51 +0200 Subject: [PATCH 03/12] Fix crash when passing an undersized array to a GLSL array input --- panda/src/glstuff/glShaderContext_src.cxx | 29 ++++++++++++----------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index 5288c446b5..5566680c17 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -1186,6 +1186,7 @@ issue_parameters(int altered) { } GLint p = _glsl_parameter_map[spec._id._seqno]; + int array_size = min(spec._dim[0], ptr_data->_size / spec._dim[1]); switch (spec._type) { case Shader::SPT_float: { @@ -1194,16 +1195,16 @@ issue_parameters(int altered) { switch (ptr_data->_type) { case Shader::SPT_int: // Convert int data to float data. - data = (float*) alloca(sizeof(float) * spec._dim[0] * spec._dim[1]); - for (int i = 0; i < (spec._dim[0] * spec._dim[1]); ++i) { + data = (float*) alloca(sizeof(float) * array_size * spec._dim[1]); + for (int i = 0; i < (array_size * spec._dim[1]); ++i) { data[i] = (float)(((int*)ptr_data->_ptr)[i]); } break; case Shader::SPT_double: // Downgrade double data to float data. - data = (float*) alloca(sizeof(float) * spec._dim[0] * spec._dim[1]); - for (int i = 0; i < (spec._dim[0] * spec._dim[1]); ++i) { + data = (float*) alloca(sizeof(float) * array_size * spec._dim[1]); + for (int i = 0; i < (array_size * spec._dim[1]); ++i) { data[i] = (float)(((double*)ptr_data->_ptr)[i]); } break; @@ -1217,12 +1218,12 @@ issue_parameters(int altered) { } switch (spec._dim[1]) { - case 1: _glgsg->_glUniform1fv(p, spec._dim[0], (float*)data); continue; - case 2: _glgsg->_glUniform2fv(p, spec._dim[0], (float*)data); continue; - case 3: _glgsg->_glUniform3fv(p, spec._dim[0], (float*)data); continue; - case 4: _glgsg->_glUniform4fv(p, spec._dim[0], (float*)data); continue; - case 9: _glgsg->_glUniformMatrix3fv(p, spec._dim[0], GL_FALSE, (float*)data); continue; - case 16: _glgsg->_glUniformMatrix4fv(p, spec._dim[0], GL_FALSE, (float*)data); continue; + case 1: _glgsg->_glUniform1fv(p, array_size, (float*)data); continue; + case 2: _glgsg->_glUniform2fv(p, array_size, (float*)data); continue; + case 3: _glgsg->_glUniform3fv(p, array_size, (float*)data); continue; + case 4: _glgsg->_glUniform4fv(p, array_size, (float*)data); continue; + case 9: _glgsg->_glUniformMatrix3fv(p, array_size, GL_FALSE, (float*)data); continue; + case 16: _glgsg->_glUniformMatrix4fv(p, array_size, GL_FALSE, (float*)data); continue; } nassertd(false) continue; } @@ -1239,10 +1240,10 @@ issue_parameters(int altered) { } else { switch (spec._dim[1]) { - case 1: _glgsg->_glUniform1iv(p, spec._dim[0], (int*)ptr_data->_ptr); continue; - case 2: _glgsg->_glUniform2iv(p, spec._dim[0], (int*)ptr_data->_ptr); continue; - case 3: _glgsg->_glUniform3iv(p, spec._dim[0], (int*)ptr_data->_ptr); continue; - case 4: _glgsg->_glUniform4iv(p, spec._dim[0], (int*)ptr_data->_ptr); continue; + case 1: _glgsg->_glUniform1iv(p, array_size, (int*)ptr_data->_ptr); continue; + case 2: _glgsg->_glUniform2iv(p, array_size, (int*)ptr_data->_ptr); continue; + case 3: _glgsg->_glUniform3iv(p, array_size, (int*)ptr_data->_ptr); continue; + case 4: _glgsg->_glUniform4iv(p, array_size, (int*)ptr_data->_ptr); continue; } nassertd(false) continue; } From 5e219f6438935c6dfd526d5bbd10f4db66a6e231 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 17 Jul 2015 21:34:29 +0200 Subject: [PATCH 04/12] Add support for uniform int osg_FrameNumber in GLSL --- panda/src/glstuff/glShaderContext_src.cxx | 28 +++++++++++++++++++---- panda/src/glstuff/glShaderContext_src.h | 2 ++ 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index a0a6f35959..7101fb62d0 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -266,6 +266,8 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext _color_attrib_index = -1; _transform_table_index = -1; _slider_table_index = -1; + _frame_number_loc = -1; + _frame_number = -1; _validated = !gl_validate_shaders; nassertv(s->get_language() == Shader::SL_GLSL); @@ -941,7 +943,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { if (noprefix == "TransformTable") { if (param_type != GL_FLOAT_MAT4) { GLCAT.error() - << "p3d_TransformTable should be uniform mat4\n"; + << "p3d_TransformTable should be uniform mat4[]\n"; return; } _transform_table_index = p; @@ -951,7 +953,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { if (noprefix == "SliderTable") { if (param_type != GL_FLOAT) { GLCAT.error() - << "p3d_SliderTable should be uniform float\n"; + << "p3d_SliderTable should be uniform float[]\n"; return; } _slider_table_index = p; @@ -965,8 +967,6 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { string noprefix(name_buffer + 4); // These inputs are supported by OpenSceneGraph. We can support // them as well, to increase compatibility. - // Other inputs we may support in the future: - // int osg_FrameNumber Shader::ShaderMatSpec bind; bind._id = arg_id; @@ -983,7 +983,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { _shader->_mat_spec.push_back(bind); return; - } else if (noprefix == "InverseViewMatrix") { + } else if (noprefix == "InverseViewMatrix" || noprefix == "ViewMatrixInverse") { bind._piece = Shader::SMP_whole; bind._func = Shader::SMF_compose; bind._part[0] = Shader::SMO_apiview_to_view; @@ -1012,6 +1012,16 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._dep[1] = Shader::SSD_NONE; _shader->_mat_spec.push_back(bind); return; + + } else if (noprefix == "FrameNumber") { + // We don't currently support ints with this mechanism, + // so we special-case this one. + if (param_type != GL_INT) { + GLCAT.error() << "osg_FrameNumber should be uniform int\n"; + } else { + _frame_number_loc = p; + } + return; } } else { @@ -1514,6 +1524,14 @@ issue_parameters(int altered) { return; } + if (_frame_number_loc != -1) { + int current_frame = ClockObject::get_global_clock()->get_frame_count(); + if (current_frame != _frame_number) { + _glgsg->_glUniform1i(_frame_number_loc, current_frame); + _frame_number = current_frame; + } + } + // Iterate through _ptr parameters for (int i = 0; i < (int)_shader->_ptr_spec.size(); ++i) { Shader::ShaderPtrSpec &spec = _shader->_ptr_spec[i]; diff --git a/panda/src/glstuff/glShaderContext_src.h b/panda/src/glstuff/glShaderContext_src.h index 9147bcf1b1..cc04500c9d 100644 --- a/panda/src/glstuff/glShaderContext_src.h +++ b/panda/src/glstuff/glShaderContext_src.h @@ -80,6 +80,8 @@ private: GLint _slider_table_index; GLsizei _transform_table_size; GLsizei _slider_table_size; + GLint _frame_number_loc; + GLint _frame_number; pmap _glsl_uniform_handles; struct ImageInput { From c224f351ecb6594cff7fedae7dd089b652e659bd Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 17 Jul 2015 21:50:06 +0200 Subject: [PATCH 05/12] Fix gcc/clang compile error --- panda/src/glstuff/glShaderContext_src.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index 5566680c17..bb58a45572 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -1186,7 +1186,7 @@ issue_parameters(int altered) { } GLint p = _glsl_parameter_map[spec._id._seqno]; - int array_size = min(spec._dim[0], ptr_data->_size / spec._dim[1]); + int array_size = min(spec._dim[0], (int)ptr_data->_size / spec._dim[1]); switch (spec._type) { case Shader::SPT_float: { From 96a9e223950f6d832b7a9eca0d6987a9f31f3e32 Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 18 Jul 2015 11:06:11 +0200 Subject: [PATCH 06/12] Add uniform mat4 p3d_TextureMatrix[] input to GLSL --- panda/src/display/graphicsStateGuardian.cxx | 24 +++++++++++---- .../glstuff/glGraphicsStateGuardian_src.cxx | 11 +++++-- panda/src/glstuff/glShaderContext_src.cxx | 29 +++++++++++++++++-- panda/src/gobj/shader.cxx | 8 +++-- panda/src/gobj/shader.h | 5 +++- 5 files changed, 63 insertions(+), 14 deletions(-) diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index a3979a6c2c..15ebcd9dc2 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -1190,14 +1190,26 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, } return &t; } - case Shader::SMO_texmat_x: { - const TexMatrixAttrib *tma = DCAST(TexMatrixAttrib, _target_rs->get_attrib_def(TexMatrixAttrib::get_class_slot())); - const TextureAttrib *ta = DCAST(TextureAttrib, _target_rs->get_attrib_def(TextureAttrib::get_class_slot())); - int stagenr = atoi(name->get_name().c_str()); - if (stagenr >= ta->get_num_on_stages()) { + case Shader::SMO_texmat_i: { + const TexMatrixAttrib *tma; + const TextureAttrib *ta; + if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma) && + index < ta->get_num_on_stages()) { + return &tma->get_mat(ta->get_on_stage(index)); + } else { + return &LMatrix4::ident_mat(); + } + } + case Shader::SMO_inv_texmat_i: { + const TexMatrixAttrib *tma; + const TextureAttrib *ta; + if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma) && + index < ta->get_num_on_stages()) { + t = tma->get_transform(ta->get_on_stage(index))->get_inverse()->get_mat(); + return &t; + } else { return &LMatrix4::ident_mat(); } - return &tma->get_mat(ta->get_on_stage(stagenr)); } case Shader::SMO_plane_x: { const NodePath &np = _target_shader->get_shader_input_nodepath(name); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index e594579d4c..6159dd5cfb 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -9217,7 +9217,6 @@ set_state_and_transform(const RenderState *target, // If one of the previously-loaded TexGen modes modified the texture // matrix, then if either state changed, we have to change both of // them now. -#ifdef SUPPORT_FIXED_FUNCTION if (_tex_gen_modifies_mat) { int tex_gen_slot = TexGenAttrib::get_class_slot(); int tex_matrix_slot = TexMatrixAttrib::get_class_slot(); @@ -9234,10 +9233,16 @@ set_state_and_transform(const RenderState *target, if (_target_rs->get_attrib(tex_matrix_slot) != _state_rs->get_attrib(tex_matrix_slot) || !_state_mask.get_bit(tex_matrix_slot)) { //PStatGPUTimer timer(this, _draw_set_state_tex_matrix_pcollector); +#ifdef SUPPORT_FIXED_FUNCTION do_issue_tex_matrix(); - _state_mask.set_bit(tex_matrix_slot); - } #endif + _state_mask.set_bit(tex_matrix_slot); +#ifndef OPENGLES_1 + if (_current_shader_context) { + _current_shader_context->issue_parameters(Shader::SSD_tex_matrix); + } +#endif + } #ifdef SUPPORT_FIXED_FUNCTION int tex_gen_slot = TexGenAttrib::get_class_slot(); diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index 50a40f4e30..f2f0bd8a27 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -690,12 +690,16 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { } else { bind._piece = Shader::SMP_transpose3x3; } - } else { + } else if (param_type == GL_FLOAT_MAT4) { if (transpose) { bind._piece = Shader::SMP_transpose; } else { bind._piece = Shader::SMP_whole; } + } else { + GLCAT.error() + << "Matrix input p3d_" << matrix_name << " should be mat3 or mat4\n"; + return; } bind._arg[0] = NULL; bind._arg[1] = NULL; @@ -731,7 +735,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._part[1] = Shader::SMO_identity; if (param_type != GL_FLOAT_MAT3) { - GLCAT.error() << "p3d_NormalMatrix input should be mat3, not mat4!\n"; + GLCAT.warning() << "p3d_NormalMatrix input should be mat3, not mat4!\n"; } } else if (matrix_name == "ModelMatrix") { @@ -761,6 +765,27 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { bind._part[1] = Shader::SMO_view_to_apiclip; } + } else if (matrix_name == "TextureMatrix") { + // We may support 2-D texmats later, but let's make sure that people + // don't think they can just use a mat3 to get the 2-D version. + if (param_type != GL_FLOAT_MAT4) { + GLCAT.error() << "p3d_TextureMatrix should be mat4[], not mat3[]!\n"; + return; + } + + bind._func = Shader::SMF_first; + bind._part[0] = inverse ? Shader::SMO_inv_texmat_i + : Shader::SMO_texmat_i; + bind._part[1] = Shader::SMO_identity; + bind._dep[0] = Shader::SSD_general | Shader::SSD_tex_matrix; + bind._dep[1] = 0; + + // Add it once for each index. + for (bind._index = 0; bind._index < param_size; ++bind._index) { + _shader->_mat_spec.push_back(bind); + } + return; + } else { GLCAT.error() << "Unrecognized uniform matrix name '" << matrix_name << "'!\n"; return; diff --git a/panda/src/gobj/shader.cxx b/panda/src/gobj/shader.cxx index 8f1cc70d33..b20ac8e1b2 100644 --- a/panda/src/gobj/shader.cxx +++ b/panda/src/gobj/shader.cxx @@ -452,6 +452,9 @@ cp_dependency(ShaderMatInput inp) { (inp == SMO_apiview_clipplane_i)) { dep |= SSD_clip_planes; } + if (inp == SMO_texmat_i || inp == SMO_inv_texmat_i) { + dep |= SSD_tex_matrix; + } return dep; } @@ -1040,10 +1043,11 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { bind._id = p._id; bind._piece = SMP_whole; bind._func = SMF_first; - bind._part[0] = SMO_texmat_x; - bind._arg[0] = InternalName::make(pieces[1]); + bind._part[0] = SMO_texmat_i; + bind._arg[0] = NULL; bind._part[1] = SMO_identity; bind._arg[1] = NULL; + bind._index = atoi(pieces[1].c_str()); cp_optimize_mat_spec(bind); _mat_spec.push_back(bind); diff --git a/panda/src/gobj/shader.h b/panda/src/gobj/shader.h index e56960b1f5..33fe43b799 100644 --- a/panda/src/gobj/shader.h +++ b/panda/src/gobj/shader.h @@ -132,7 +132,7 @@ public: SMO_plight_x, SMO_slight_x, SMO_satten_x, - SMO_texmat_x, + SMO_texmat_i, SMO_plane_x, SMO_clipplane_x, @@ -191,6 +191,8 @@ public: SMO_apiview_to_apiclip, SMO_apiclip_to_apiview, + SMO_inv_texmat_i, + SMO_INVALID }; @@ -270,6 +272,7 @@ public: SSD_fog = 0x040, SSD_light = 0x080, SSD_clip_planes = 0x100, + SSD_tex_matrix = 0x200, }; enum ShaderBug { From e91a9100ed3398bfe14bfa793d274a02fbbcb871 Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 18 Jul 2015 22:40:57 +0200 Subject: [PATCH 07/12] Support specifying custom gl-version or requesting debug context on Windows Also works around NVIDIA driver bug where GL_VERSION is always reported as 1.2 for pview.exe --- .../glstuff/glGraphicsStateGuardian_src.cxx | 65 +++++++++++++++---- .../wgldisplay/wglGraphicsStateGuardian.cxx | 39 ++++++++++- .../src/wgldisplay/wglGraphicsStateGuardian.h | 2 + panda/src/wgldisplay/wglGraphicsWindow.cxx | 12 +++- 4 files changed, 103 insertions(+), 15 deletions(-) diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 6159dd5cfb..476e1af9f1 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -6835,10 +6835,9 @@ show_gl_string(const string &name, GLenum id) { const GLubyte *text = glGetString(id); if (text == (const GLubyte *)NULL) { - if (GLCAT.is_debug()) { - GLCAT.debug() - << "Unable to query " << name << "\n"; - } + GLCAT.warning() + << "Unable to query " << name << "\n"; + } else { result = (const char *)text; if (GLCAT.is_debug()) { @@ -6859,20 +6858,60 @@ void CLP(GraphicsStateGuardian):: query_gl_version() { _gl_vendor = show_gl_string("GL_VENDOR", GL_VENDOR); _gl_renderer = show_gl_string("GL_RENDERER", GL_RENDERER); + _gl_version = show_gl_string("GL_VERSION", GL_VERSION); _gl_version_major = 0; _gl_version_minor = 0; + // This is the most preposterous driver bug: NVIDIA drivers will claim + // that the version is 1.2 as long as the process is named pview.exe! +#ifndef OPENGLES + if (_gl_version.substr(0, 10) == "1.2 NVIDIA") { + Filename exec_name = ExecutionEnvironment::get_binary_name(); + if (cmp_nocase(exec_name.get_basename(), "pview.exe") == 0) { + glGetIntegerv(GL_MAJOR_VERSION, &_gl_version_major); + glGetIntegerv(GL_MINOR_VERSION, &_gl_version_minor); + + if (glGetError() == GL_INVALID_ENUM) { + _gl_version_major = 1; + _gl_version_minor = 2; + GLCAT.warning() + << "Driver possibly misreported GL_VERSION! Unable to detect " + "correct OpenGL version.\n"; + + } else if (_gl_version_major != 1 || _gl_version_minor != 2) { + GLCAT.debug() + << "Driver misreported GL_VERSION! Correct version detected as " + << _gl_version_major << "." << _gl_version_minor << "\n"; + } + return; + } + } +#endif + + // If we asked for a GL 3 context, let's first try and see if we + // can use the OpenGL 3 way to query version. + if (gl_version.get_num_words() > 0 && gl_version[0] >= 3) { + glGetIntegerv(GL_MAJOR_VERSION, &_gl_version_major); + glGetIntegerv(GL_MINOR_VERSION, &_gl_version_minor); + + if (_gl_version_major >= 1) { + // Fair enough, seems to check out. + if (GLCAT.is_debug()) { + GLCAT.debug() + << "Detected OpenGL version: " + << _gl_version_major << "." << _gl_version_minor << "\n"; + } + return; + } + } + + // Otherwise, parse the GL_VERSION string. + if (_gl_version.empty()) { + GLCAT.error() << "Unable to detect OpenGL version\n"; - const GLubyte *text = glGetString(GL_VERSION); - if (text == (const GLubyte *)NULL) { - GLCAT.warning() - << "Unable to query GL_VERSION\n"; } else { - string version((const char *)text); - _gl_version = version; - - string input = version; + string input = _gl_version; // Skip any initial words that don't begin with a digit. while (!input.empty() && !isdigit(input[0])) { @@ -6904,7 +6943,7 @@ query_gl_version() { if (GLCAT.is_debug()) { GLCAT.debug() - << "GL_VERSION = " << version << ", decoded to " + << "GL_VERSION decoded to: " << _gl_version_major << "." << _gl_version_minor << "\n"; } diff --git a/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx b/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx index e89ce1fdb6..236ab57a77 100644 --- a/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx +++ b/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx @@ -47,6 +47,8 @@ wglGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe, _supports_wgl_multisample = false; _supports_wgl_render_texture = false; + _wglCreateContextAttribsARB = NULL; + get_gamma_table(); atexit(atexit_function); } @@ -345,6 +347,14 @@ choose_pixel_format(const FrameBufferProperties &properties, get_extra_extensions(); _supports_pixel_format = has_extension("WGL_ARB_pixel_format"); _supports_wgl_multisample = has_extension("WGL_ARB_multisample"); + + if (has_extension("WGL_ARB_create_context")) { + _wglCreateContextAttribsARB = + (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB"); + } else { + _wglCreateContextAttribsARB = NULL; + } + _extensions.clear(); if (!_supports_pixel_format) { @@ -614,7 +624,34 @@ make_context(HDC hdc) { // Attempt to create a context. wglGraphicsPipe::_current_valid = false; - _context = wglCreateContext(hdc); + + if (_wglCreateContextAttribsARB != NULL) { + // We have a fancier version of wglCreateContext that allows us + // to specify what kind of OpenGL context we would like. + int attrib_list[32]; + int n = 0; + attrib_list[0] = NULL; + + if (gl_version.get_num_words() > 0) { + attrib_list[n++] = WGL_CONTEXT_MAJOR_VERSION_ARB; + attrib_list[n++] = gl_version[0]; + if (gl_version.get_num_words() > 1) { + attrib_list[n++] = WGL_CONTEXT_MINOR_VERSION_ARB; + attrib_list[n++] = gl_version[1]; + } + } + if (gl_debug) { + attrib_list[n++] = WGL_CONTEXT_FLAGS_ARB; + attrib_list[n++] = WGL_CONTEXT_DEBUG_BIT_ARB; + } + attrib_list[n++] = WGL_CONTEXT_PROFILE_MASK_ARB; + attrib_list[n++] = WGL_CONTEXT_CORE_PROFILE_BIT_ARB; + attrib_list[n] = NULL; + + _context = _wglCreateContextAttribsARB(hdc, 0, attrib_list); + } else { + _context = wglCreateContext(hdc); + } if (_context == NULL) { wgldisplay_cat.error() diff --git a/panda/src/wgldisplay/wglGraphicsStateGuardian.h b/panda/src/wgldisplay/wglGraphicsStateGuardian.h index 4fa70b2a46..b76dac9578 100644 --- a/panda/src/wgldisplay/wglGraphicsStateGuardian.h +++ b/panda/src/wgldisplay/wglGraphicsStateGuardian.h @@ -118,6 +118,8 @@ public: PFNWGLRELEASETEXIMAGEARBPROC _wglReleaseTexImageARB; PFNWGLSETPBUFFERATTRIBARBPROC _wglSetPbufferAttribARB; + PFNWGLCREATECONTEXTATTRIBSARBPROC _wglCreateContextAttribsARB; + public: static TypeHandle get_class_type() { return _type_handle; diff --git a/panda/src/wgldisplay/wglGraphicsWindow.cxx b/panda/src/wgldisplay/wglGraphicsWindow.cxx index 0ddcdb208a..43a3d5a480 100644 --- a/panda/src/wgldisplay/wglGraphicsWindow.cxx +++ b/panda/src/wgldisplay/wglGraphicsWindow.cxx @@ -304,8 +304,18 @@ open_window() { // Initializes _colormap setup_colormap(pixelformat); + // Make sure we have a context created. + HGLRC context = wglgsg->get_context(_hdc); + if (!context) { + // The context failed to create for some reason. + wgldisplay_cat.error() + << "Closing window because no valid context is available.\n"; + close_window(); + return false; + } + // Initialize the gsg. - wglGraphicsPipe::wgl_make_current(_hdc, wglgsg->get_context(_hdc), &_make_current_pcollector); + wglGraphicsPipe::wgl_make_current(_hdc, context, &_make_current_pcollector); wglgsg->reset_if_new(); wglgsg->report_my_gl_errors(); if (!wglgsg->get_fb_properties().verify_hardware_software From 23441aa5bb7edf3ed170d2c926e6399bece53b8d Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 19 Jul 2015 09:22:57 +0200 Subject: [PATCH 08/12] Fix intel driver issues, particularly with geometry shaders --- panda/src/glstuff/glGraphicsBuffer_src.cxx | 1 + .../glstuff/glGraphicsStateGuardian_src.cxx | 74 ++++++++++++------- panda/src/glstuff/glShaderContext_src.cxx | 18 +++-- 3 files changed, 58 insertions(+), 35 deletions(-) diff --git a/panda/src/glstuff/glGraphicsBuffer_src.cxx b/panda/src/glstuff/glGraphicsBuffer_src.cxx index 05d8c4b78f..cd40b52384 100644 --- a/panda/src/glstuff/glGraphicsBuffer_src.cxx +++ b/panda/src/glstuff/glGraphicsBuffer_src.cxx @@ -1062,6 +1062,7 @@ attach_tex(int layer, int view, Texture *attach, GLenum attachpoint) { #ifndef OPENGLES if (_rb_size_z != 1) { // Bind all of the layers of the texture. + nassertv(glgsg->_glFramebufferTexture != NULL); glgsg->_glFramebufferTexture(GL_FRAMEBUFFER_EXT, attachpoint, gtc->_index, 0); return; diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index cb7b0e4da3..db342f423a 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -829,13 +829,22 @@ reset() { _supports_2d_texture_array = false; #ifndef OPENGLES - _supports_2d_texture_array = has_extension("GL_EXT_texture_array"); - if (_supports_2d_texture_array) { + if (is_at_least_gl_version(3, 0)) { + _supports_2d_texture_array = true; + + _glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC) + get_extension_func("glFramebufferTextureLayer"); + + } else if (has_extension("GL_EXT_texture_array")) { + _supports_2d_texture_array = true; + _glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC) get_extension_func("glFramebufferTextureLayerEXT"); - } else { - // ARB_geometry_shader4 also provides a version. - _glFramebufferTextureLayer = NULL; + } + + if (_supports_2d_texture_array && _glFramebufferTextureLayer == NULL) { + GLCAT.warning() + << "Texture arrays advertised as supported by OpenGL runtime, but could not get pointer to glFramebufferTextureLayer function.\n"; } #endif @@ -1263,20 +1272,40 @@ reset() { #endif // HAVE_CG -#ifdef OPENGLES_2 +#if defined(OPENGLES_1) + _supports_glsl = false; + _supports_geometry_shaders = false; + _supports_tessellation_shaders = false; +#elif defined(OPENGLES) _supports_glsl = true; _supports_geometry_shaders = false; _supports_tessellation_shaders = false; #else - #ifdef OPENGLES_1 - _supports_glsl = false; + _supports_glsl = is_at_least_gl_version(2, 0) || has_extension("GL_ARB_shading_language_100"); + _supports_tessellation_shaders = is_at_least_gl_version(4, 0) || has_extension("GL_ARB_tessellation_shader"); + + if (is_at_least_gl_version(3, 2)) { + _supports_geometry_shaders = true; + _glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREARBPROC) + get_extension_func("glFramebufferTexture"); + + } else if (has_extension("GL_ARB_geometry_shader4")) { + _supports_geometry_shaders = true; + _glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREARBPROC) + get_extension_func("glFramebufferTextureARB"); + _glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC) + get_extension_func("glProgramParameteriARB"); + + } else if (has_extension("GL_EXT_geometry_shader4")) { + _supports_geometry_shaders = true; + _glFramebufferTexture = NULL; + _glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC) + get_extension_func("glProgramParameteriEXT"); + + } else { _supports_geometry_shaders = false; - _supports_tessellation_shaders = false; - #else - _supports_glsl = is_at_least_gl_version(2, 0) || has_extension("GL_ARB_shading_language_100"); - _supports_geometry_shaders = is_at_least_gl_version(3, 2) || has_extension("GL_ARB_geometry_shader4"); - _supports_tessellation_shaders = is_at_least_gl_version(4, 0) || has_extension("GL_ARB_tessellation_shader"); - #endif + _glFramebufferTexture = NULL; + } #endif _shader_caps._supports_glsl = _supports_glsl; @@ -1378,17 +1407,6 @@ reset() { _glVertexAttribLPointer = NULL; } - if (_supports_geometry_shaders) { - _glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC) - get_extension_func("glProgramParameteri"); - _glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREARBPROC) - get_extension_func("glFramebufferTextureARB"); - - if (_glFramebufferTextureLayer == NULL) { - _glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC) - get_extension_func("glFramebufferTextureLayerARB"); - } - } if (_supports_tessellation_shaders) { _glPatchParameteri = (PFNGLPATCHPARAMETERIPROC) get_extension_func("glPatchParameteri"); @@ -1533,7 +1551,7 @@ reset() { _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC) get_extension_func("glDrawElementsInstancedARB"); _supports_geometry_instancing = true; - + } else if (has_extension("GL_EXT_draw_instanced")) { _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC) get_extension_func("glDrawArraysInstancedEXT"); @@ -2202,8 +2220,10 @@ reset() { if (is_at_least_gl_version(4, 1) || has_extension("GL_ARB_get_program_binary")) { _glGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC) get_extension_func("glGetProgramBinary"); + _glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC) + get_extension_func("glProgramParameteri"); - if (_glGetProgramBinary != NULL) { + if (_glGetProgramBinary != NULL && _glProgramParameteri != NULL) { _supports_get_program_binary = true; } } diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index bb58a45572..2a67e0ba21 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -212,10 +212,11 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext if (_glsl_parameter_map.size() == 0) { int seqno = 0, texunitno = 0, imgunitno = 0; string noprefix; - GLint param_count, param_maxlength, param_size; + GLint param_count = 0, param_maxlength = 0, param_size; GLenum param_type; _glgsg->_glGetProgramiv(_glsl_program, GL_ACTIVE_UNIFORMS, ¶m_count); _glgsg->_glGetProgramiv(_glsl_program, GL_ACTIVE_UNIFORM_MAX_LENGTH, ¶m_maxlength); + param_maxlength = max(64, param_maxlength); char* param_name_cstr = (char *)alloca(param_maxlength); for (int i = 0; i < param_count; ++i) { @@ -856,6 +857,7 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext // Now we've processed the uniforms, we'll process the attribs. _glgsg->_glGetProgramiv(_glsl_program, GL_ACTIVE_ATTRIBUTES, ¶m_count); _glgsg->_glGetProgramiv(_glsl_program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, ¶m_maxlength); + param_maxlength = max(64, param_maxlength); param_name_cstr = (char *)alloca(param_maxlength); for (int i = 0; i < param_count; ++i) { @@ -1940,13 +1942,13 @@ glsl_compile_and_link() { if (!_shader->get_text(Shader::ST_geometry).empty()) { valid &= glsl_compile_shader(Shader::ST_geometry); - // Set the vertex output limit to the maximum. - // This is slow, but it is probably reasonable to require - // the user to override this in his shader using layout(). - nassertr(_glgsg->_glProgramParameteri != NULL, false); - GLint max_vertices; - glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES, &max_vertices); - _glgsg->_glProgramParameteri(_glsl_program, GL_GEOMETRY_VERTICES_OUT_ARB, max_vertices); + //XXX Actually, it turns out that this is unavailable in the core + // version of geometry shaders. Probably no need to bother with it. + + //nassertr(_glgsg->_glProgramParameteri != NULL, false); + //GLint max_vertices; + //glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES, &max_vertices); + //_glgsg->_glProgramParameteri(_glsl_program, GL_GEOMETRY_VERTICES_OUT_ARB, max_vertices); } #endif From 1bb1cc79f4fae129fa1b991349ffa85459324ac4 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 19 Jul 2015 20:13:55 +0200 Subject: [PATCH 09/12] Improve reporting of supported extensions and compressed formats --- .../glstuff/glGraphicsStateGuardian_src.cxx | 190 +++++++++++++----- .../src/glstuff/glGraphicsStateGuardian_src.h | 4 + 2 files changed, 146 insertions(+), 48 deletions(-) diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 20bc4c2ae8..601b1a3215 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -2128,61 +2128,22 @@ reset() { GLCAT.debug() << "No specific compressed texture formats are supported.\n"; } else { +#ifndef NDEBUG GLCAT.debug() << "Supported compressed texture formats:\n"; GLint *formats = (GLint *)alloca(num_compressed_formats * sizeof(GLint)); glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, formats); for (int i = 0; i < num_compressed_formats; ++i) { - switch (formats[i]) { - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - GLCAT.debug(false) << " GL_COMPRESSED_RGB_S3TC_DXT1_EXT\n"; - break; - - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - GLCAT.debug(false) << " GL_COMPRESSED_RGBA_S3TC_DXT1_EXT\n"; - break; -#ifdef OPENGLES - case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG: - GLCAT.debug(false) << " GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG\n"; - break; - - case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: - GLCAT.debug(false) << " GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG\n"; - break; - - case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG: - GLCAT.debug(false) << " GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG\n"; - break; - - case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: - GLCAT.debug(false) << " GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG\n"; - break; -#endif -#ifndef OPENGLES_1 - case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - GLCAT.debug(false) << " GL_COMPRESSED_RGBA_S3TC_DXT3_EXT\n"; - break; - - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - GLCAT.debug(false) << " GL_COMPRESSED_RGBA_S3TC_DXT5_EXT\n"; - break; -#endif -#ifndef OPENGLES - case GL_COMPRESSED_RGB_FXT1_3DFX: - GLCAT.debug(false) << " GL_COMPRESSED_RGB_FXT1_3DFX\n"; - break; - - case GL_COMPRESSED_RGBA_FXT1_3DFX: - GLCAT.debug(false) << " GL_COMPRESSED_RGBA_FXT1_3DFX\n"; - break; -#endif - - default: + const char *format_str = get_compressed_format_string(formats[i]); + if (format_str != NULL) { + GLCAT.debug(false) << " " << format_str << '\n'; + } else { GLCAT.debug(false) << " Unknown compressed format 0x" << hex << formats[i] << dec << "\n"; } } +#endif } } } @@ -7049,11 +7010,25 @@ get_extra_extensions() { void CLP(GraphicsStateGuardian):: report_extensions() const { if (GLCAT.is_debug()) { - GLCAT.debug() - << "GL Extensions:\n"; + ostream &out = GLCAT.debug(); + out << "GL Extensions:\n"; + + size_t maxlen = 0; pset::const_iterator ei; for (ei = _extensions.begin(); ei != _extensions.end(); ++ei) { - GLCAT.debug() << (*ei) << "\n"; + size_t len = (*ei).size(); + out << " " << (*ei); + + // Display a second column. + if (len <= 38) { + if (++ei != _extensions.end()) { + for (int i = len; i < 38; ++i) { + out.put(' '); + } + out << ' ' << (*ei); + } + } + out.put('\n'); } } } @@ -8801,6 +8776,125 @@ get_usage(Geom::UsageHint usage_hint) { return GL_STATIC_DRAW; } +//////////////////////////////////////////////////////////////////// +// Function: GLGraphicsStateGuardian::get_compressed_format_string +// Access: Public, Static +// Description: Returns a string describing an compression format. +//////////////////////////////////////////////////////////////////// +const char *CLP(GraphicsStateGuardian):: +get_compressed_format_string(GLenum format) { + switch (format) { + case 0x83F0: return "GL_COMPRESSED_RGB_S3TC_DXT1_EXT"; + case 0x83F1: return "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT"; + case 0x83F2: return "GL_COMPRESSED_RGBA_S3TC_DXT3_EXT"; + case 0x83F3: return "GL_COMPRESSED_RGBA_S3TC_DXT5_EXT"; + case 0x86B0: return "GL_COMPRESSED_RGB_FXT1_3DFX"; + case 0x86B1: return "GL_COMPRESSED_RGBA_FXT1_3DFX"; + case 0x8A54: return "GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT"; + case 0x8A55: return "GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT"; + case 0x8A56: return "GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT"; + case 0x8A57: return "GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT"; + case 0x8B90: return "GL_PALETTE4_RGB8_OES"; + case 0x8B91: return "GL_PALETTE4_RGBA8_OES"; + case 0x8B92: return "GL_PALETTE4_R5_G6_B5_OES"; + case 0x8B93: return "GL_PALETTE4_RGBA4_OES"; + case 0x8B94: return "GL_PALETTE4_RGB5_A1_OES"; + case 0x8B95: return "GL_PALETTE8_RGB8_OES"; + case 0x8B96: return "GL_PALETTE8_RGBA8_OES"; + case 0x8B97: return "GL_PALETTE8_R5_G6_B5_OES"; + case 0x8B98: return "GL_PALETTE8_RGBA4_OES"; + case 0x8B99: return "GL_PALETTE8_RGB5_A1_OES"; + case 0x8C00: return "GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG"; + case 0x8C01: return "GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG"; + case 0x8C02: return "GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG"; + case 0x8C03: return "GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG"; + case 0x8C48: return "GL_COMPRESSED_SRGB_EXT"; + case 0x8C49: return "GL_COMPRESSED_SRGB_ALPHA_EXT"; + case 0x8C4A: return "GL_COMPRESSED_SLUMINANCE_EXT"; + case 0x8C4B: return "GL_COMPRESSED_SLUMINANCE_ALPHA_EXT"; + case 0x8C4C: return "GL_COMPRESSED_SRGB_S3TC_DXT1_EXT"; + case 0x8C4D: return "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT"; + case 0x8C4E: return "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT"; + case 0x8C4F: return "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT"; + case 0x8C70: return "GL_COMPRESSED_LUMINANCE_LATC1_EXT"; + case 0x8C71: return "GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT"; + case 0x8C72: return "GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT"; + case 0x8C73: return "GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT"; + case 0x8DBB: return "GL_COMPRESSED_RED_RGTC1"; + case 0x8DBC: return "GL_COMPRESSED_SIGNED_RED_RGTC1"; + case 0x8DBD: return "GL_COMPRESSED_RG_RGTC2"; + case 0x8DBE: return "GL_COMPRESSED_SIGNED_RG_RGTC2"; + case 0x8E8C: return "GL_COMPRESSED_RGBA_BPTC_UNORM"; + case 0x8E8D: return "GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM"; + case 0x8E8E: return "GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT"; + case 0x8E8F: return "GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT"; + case 0x9137: return "GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG"; + case 0x9138: return "GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG"; + case 0x9270: return "GL_COMPRESSED_R11_EAC"; + case 0x9271: return "GL_COMPRESSED_SIGNED_R11_EAC"; + case 0x9272: return "GL_COMPRESSED_RG11_EAC"; + case 0x9273: return "GL_COMPRESSED_SIGNED_RG11_EAC"; + case 0x9274: return "GL_COMPRESSED_RGB8_ETC2"; + case 0x9275: return "GL_COMPRESSED_SRGB8_ETC2"; + case 0x9276: return "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2"; + case 0x9277: return "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2"; + case 0x9278: return "GL_COMPRESSED_RGBA8_ETC2_EAC"; + case 0x9279: return "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC"; + case 0x93B0: return "GL_COMPRESSED_RGBA_ASTC_4x4_KHR"; + case 0x93B1: return "GL_COMPRESSED_RGBA_ASTC_5x4_KHR"; + case 0x93B2: return "GL_COMPRESSED_RGBA_ASTC_5x5_KHR"; + case 0x93B3: return "GL_COMPRESSED_RGBA_ASTC_6x5_KHR"; + case 0x93B4: return "GL_COMPRESSED_RGBA_ASTC_6x6_KHR"; + case 0x93B5: return "GL_COMPRESSED_RGBA_ASTC_8x5_KHR"; + case 0x93B6: return "GL_COMPRESSED_RGBA_ASTC_8x6_KHR"; + case 0x93B7: return "GL_COMPRESSED_RGBA_ASTC_8x8_KHR"; + case 0x93B8: return "GL_COMPRESSED_RGBA_ASTC_10x5_KHR"; + case 0x93B9: return "GL_COMPRESSED_RGBA_ASTC_10x6_KHR"; + case 0x93BA: return "GL_COMPRESSED_RGBA_ASTC_10x8_KHR"; + case 0x93BB: return "GL_COMPRESSED_RGBA_ASTC_10x10_KHR"; + case 0x93BC: return "GL_COMPRESSED_RGBA_ASTC_12x10_KHR"; + case 0x93BD: return "GL_COMPRESSED_RGBA_ASTC_12x12_KHR"; + case 0x93C0: return "GL_COMPRESSED_RGBA_ASTC_3x3x3_OES"; + case 0x93C1: return "GL_COMPRESSED_RGBA_ASTC_4x3x3_OES"; + case 0x93C2: return "GL_COMPRESSED_RGBA_ASTC_4x4x3_OES"; + case 0x93C3: return "GL_COMPRESSED_RGBA_ASTC_4x4x4_OES"; + case 0x93C4: return "GL_COMPRESSED_RGBA_ASTC_5x4x4_OES"; + case 0x93C5: return "GL_COMPRESSED_RGBA_ASTC_5x5x4_OES"; + case 0x93C6: return "GL_COMPRESSED_RGBA_ASTC_5x5x5_OES"; + case 0x93C7: return "GL_COMPRESSED_RGBA_ASTC_6x5x5_OES"; + case 0x93C8: return "GL_COMPRESSED_RGBA_ASTC_6x6x5_OES"; + case 0x93C9: return "GL_COMPRESSED_RGBA_ASTC_6x6x6_OES"; + case 0x93D0: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR"; + case 0x93D1: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR"; + case 0x93D2: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR"; + case 0x93D3: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR"; + case 0x93D4: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR"; + case 0x93D5: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR"; + case 0x93D6: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR"; + case 0x93D7: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR"; + case 0x93D8: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR"; + case 0x93D9: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR"; + case 0x93DA: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR"; + case 0x93DB: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR"; + case 0x93DC: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR"; + case 0x93DD: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR"; + case 0x93E0: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES"; + case 0x93E1: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES"; + case 0x93E2: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES"; + case 0x93E3: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES"; + case 0x93E4: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES"; + case 0x93E5: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES"; + case 0x93E6: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES"; + case 0x93E7: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES"; + case 0x93E8: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES"; + case 0x93E9: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES"; + case 0x93F0: return "GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2_IMG"; + case 0x93F1: return "GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV2_IMG"; + default: + return NULL; + } +} + //////////////////////////////////////////////////////////////////// // Function: GLGraphicsStateGuardian::get_light_color // Access: Public diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index 71339e4b23..63c4cb8abd 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -511,6 +511,10 @@ protected: static GLenum get_blend_func(ColorBlendAttrib::Operand operand); static GLenum get_usage(Geom::UsageHint usage_hint); +#ifndef NDEBUG + static const char *get_compressed_format_string(GLenum format); +#endif + void unbind_buffers(); #ifdef SUPPORT_FIXED_FUNCTION void disable_standard_vertex_arrays(); From e515cbdbd1dae5319a667a6b9d538db434316753 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 19 Jul 2015 21:11:43 +0200 Subject: [PATCH 10/12] Reintroduce display mode information in Windows via Win32 API Also clean up the CPUID code in winGraphicsPipe a bit --- panda/src/display/displayInformation.cxx | 59 +- panda/src/display/displayInformation.h | 23 +- panda/src/windisplay/winGraphicsPipe.cxx | 667 ++++++++++------------- 3 files changed, 353 insertions(+), 396 deletions(-) diff --git a/panda/src/display/displayInformation.cxx b/panda/src/display/displayInformation.cxx index 0c3dc53ebe..41eab9d020 100644 --- a/panda/src/display/displayInformation.cxx +++ b/panda/src/display/displayInformation.cxx @@ -15,10 +15,52 @@ #include "graphicsStateGuardian.h" #include "displayInformation.h" +//////////////////////////////////////////////////////////////////// +// Function: DisplayMode::Comparison Operator +// Access: Published +// Description: Returns true if these two DisplayModes are identical. +//////////////////////////////////////////////////////////////////// +bool DisplayMode:: +operator == (const DisplayMode &other) const { + return (width == other.width && height == other.height && + bits_per_pixel == other.bits_per_pixel && + refresh_rate == other.refresh_rate && + fullscreen_only == other.fullscreen_only); +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayMode::Comparison Operator +// Access: Published +// Description: Returns false if these two DisplayModes are identical. +//////////////////////////////////////////////////////////////////// +bool DisplayMode:: +operator != (const DisplayMode &other) const { + return !operator == (other); +} + +//////////////////////////////////////////////////////////////////// +// Function: DisplayMode::output +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void DisplayMode:: +output(ostream &out) const { + out << width << 'x' << height; + if (bits_per_pixel > 0) { + out << ' ' << bits_per_pixel << "bpp"; + } + if (refresh_rate > 0) { + out << ' ' << refresh_rate << "Hz"; + } + if (fullscreen_only > 0) { + out << " (fullscreen only)"; + } +} + //////////////////////////////////////////////////////////////////// // Function: DisplayInformation::Destructor // Access: Published -// Description: +// Description: //////////////////////////////////////////////////////////////////// DisplayInformation:: ~DisplayInformation() { @@ -181,6 +223,21 @@ get_total_display_modes() { return _total_display_modes; } +//////////////////////////////////////////////////////////////////// +// Function: DisplayInformation::get_display_mode +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +const DisplayMode &DisplayInformation:: +get_display_mode(int display_index) { +#ifndef NDEBUG + static DisplayMode err_mode = {0}; + nassertr(display_index >= 0 && display_index < _total_display_modes, err_mode); +#endif + + return _display_mode_array[display_index]; +} + //////////////////////////////////////////////////////////////////// // Function: DisplayInformation::get_display_mode_width // Access: Published diff --git a/panda/src/display/displayInformation.h b/panda/src/display/displayInformation.h index df158e45f3..32ee8c687e 100644 --- a/panda/src/display/displayInformation.h +++ b/panda/src/display/displayInformation.h @@ -17,29 +17,30 @@ #include "typedef.h" -typedef struct { +struct EXPCL_PANDA_DISPLAY DisplayMode { +PUBLISHED: int width; int height; int bits_per_pixel; int refresh_rate; int fullscreen_only; -} -DisplayMode; + + bool operator == (const DisplayMode &other) const; + bool operator != (const DisplayMode &other) const; + void output(ostream &out) const; +}; //////////////////////////////////////////////////////////////////// // Class : DisplayInformation // Description : This class contains various display information. //////////////////////////////////////////////////////////////////// - class EXPCL_PANDA_DISPLAY DisplayInformation { - PUBLISHED: - enum DetectionState { - DS_unknown, - DS_success, + DS_unknown, + DS_success, - DS_direct_3d_create_error, + DS_direct_3d_create_error, DS_create_window_error, DS_create_device_error, }; @@ -54,6 +55,10 @@ PUBLISHED: int get_window_bits_per_pixel(); int get_total_display_modes(); + const DisplayMode &get_display_mode(int display_index); + MAKE_SEQ(get_display_modes, get_total_display_modes, get_display_mode); + + // Older interface for display modes. int get_display_mode_width(int display_index); int get_display_mode_height(int display_index); int get_display_mode_bits_per_pixel(int display_index); diff --git a/panda/src/windisplay/winGraphicsPipe.cxx b/panda/src/windisplay/winGraphicsPipe.cxx index 1fd25e52e1..3776e8dbc5 100644 --- a/panda/src/windisplay/winGraphicsPipe.cxx +++ b/panda/src/windisplay/winGraphicsPipe.cxx @@ -15,6 +15,7 @@ #include "winGraphicsPipe.h" #include "config_windisplay.h" #include "displaySearchParameters.h" +#include "displayInformation.h" #include "dtool_config.h" #include "pbitops.h" @@ -52,49 +53,47 @@ static GetProcessMemoryInfoType GetProcessMemoryInfoFunction = 0; static GlobalMemoryStatusExType GlobalMemoryStatusExFunction = 0; static CallNtPowerInformationType CallNtPowerInformationFunction = 0; -void get_memory_information (DisplayInformation *display_information) -{ +void get_memory_information (DisplayInformation *display_information) { if (initialize == false) { - psapi_dll = LoadLibrary ("psapi.dll"); + psapi_dll = LoadLibrary("psapi.dll"); if (psapi_dll) { - GetProcessMemoryInfoFunction = (GetProcessMemoryInfoType) GetProcAddress (psapi_dll, "GetProcessMemoryInfo"); + GetProcessMemoryInfoFunction = (GetProcessMemoryInfoType) GetProcAddress(psapi_dll, "GetProcessMemoryInfo"); } - kernel32_dll = LoadLibrary ("kernel32.dll"); + kernel32_dll = LoadLibrary("kernel32.dll"); if (kernel32_dll) { - GlobalMemoryStatusExFunction = (GlobalMemoryStatusExType) GetProcAddress (kernel32_dll, "GlobalMemoryStatusEx"); + GlobalMemoryStatusExFunction = (GlobalMemoryStatusExType) GetProcAddress(kernel32_dll, "GlobalMemoryStatusEx"); } - + initialize = true; } if (GlobalMemoryStatusExFunction) { MEMORYSTATUSEX memory_status; - memory_status.dwLength = sizeof (MEMORYSTATUSEX); - if (GlobalMemoryStatusExFunction (&memory_status)) { - display_information -> _physical_memory = memory_status.ullTotalPhys; - display_information -> _available_physical_memory = memory_status.ullAvailPhys; - display_information -> _page_file_size = memory_status.ullTotalPageFile; - display_information -> _available_page_file_size = memory_status.ullAvailPageFile; - display_information -> _process_virtual_memory = memory_status.ullTotalVirtual; - display_information -> _available_process_virtual_memory = memory_status.ullAvailVirtual; - display_information -> _memory_load = memory_status.dwMemoryLoad; - } - } - else { + memory_status.dwLength = sizeof(MEMORYSTATUSEX); + if (GlobalMemoryStatusExFunction(&memory_status)) { + display_information->_physical_memory = memory_status.ullTotalPhys; + display_information->_available_physical_memory = memory_status.ullAvailPhys; + display_information->_page_file_size = memory_status.ullTotalPageFile; + display_information->_available_page_file_size = memory_status.ullAvailPageFile; + display_information->_process_virtual_memory = memory_status.ullTotalVirtual; + display_information->_available_process_virtual_memory = memory_status.ullAvailVirtual; + display_information->_memory_load = memory_status.dwMemoryLoad; + } + } else { MEMORYSTATUS memory_status; - memory_status.dwLength = sizeof (MEMORYSTATUS); + memory_status.dwLength = sizeof(MEMORYSTATUS); GlobalMemoryStatus (&memory_status); - display_information -> _physical_memory = memory_status.dwTotalPhys; - display_information -> _available_physical_memory = memory_status.dwAvailPhys; - display_information -> _page_file_size = memory_status.dwTotalPageFile; - display_information -> _available_page_file_size = memory_status.dwAvailPageFile; - display_information -> _process_virtual_memory = memory_status.dwTotalVirtual; - display_information -> _available_process_virtual_memory = memory_status.dwAvailVirtual; - display_information -> _memory_load = memory_status.dwMemoryLoad; + display_information->_physical_memory = memory_status.dwTotalPhys; + display_information->_available_physical_memory = memory_status.dwAvailPhys; + display_information->_page_file_size = memory_status.dwTotalPageFile; + display_information->_available_page_file_size = memory_status.dwAvailPageFile; + display_information->_process_virtual_memory = memory_status.dwTotalVirtual; + display_information->_available_process_virtual_memory = memory_status.dwAvailVirtual; + display_information->_memory_load = memory_status.dwMemoryLoad; } if (GetProcessMemoryInfoFunction) { @@ -105,21 +104,20 @@ void get_memory_information (DisplayInformation *display_information) process_id = GetCurrentProcessId(); process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, process_id); if (process) { - if (GetProcessMemoryInfoFunction (process, &process_memory_counters, sizeof (PROCESS_MEMORY_COUNTERS))) { - display_information -> _page_fault_count = process_memory_counters.PageFaultCount; - display_information -> _process_memory = process_memory_counters.WorkingSetSize; - display_information -> _peak_process_memory = process_memory_counters.PeakWorkingSetSize; - display_information -> _page_file_usage = process_memory_counters.PagefileUsage; - display_information -> _peak_page_file_usage = process_memory_counters.PeakPagefileUsage; + if (GetProcessMemoryInfoFunction (process, &process_memory_counters, sizeof(PROCESS_MEMORY_COUNTERS))) { + display_information->_page_fault_count = process_memory_counters.PageFaultCount; + display_information->_process_memory = process_memory_counters.WorkingSetSize; + display_information->_peak_process_memory = process_memory_counters.PeakWorkingSetSize; + display_information->_page_file_usage = process_memory_counters.PagefileUsage; + display_information->_peak_page_file_usage = process_memory_counters.PeakPagefileUsage; } CloseHandle(process); } - } + } } -typedef union -{ +typedef union { PN_uint64 long_integer; } LONG_INTEGER; @@ -130,11 +128,10 @@ PN_uint64 cpu_time_function (void) { #else LONG_INTEGER long_integer; LONG_INTEGER *long_integer_pointer; - + long_integer_pointer = &long_integer; - - __asm - { + + __asm { mov ebx,[long_integer_pointer] rdtsc mov [ebx + 0], eax @@ -145,14 +142,10 @@ PN_uint64 cpu_time_function (void) { #endif } -typedef union -{ - struct - { - union - { - struct - { +typedef union { + struct { + union { + struct { unsigned char al; unsigned char ah; }; @@ -162,15 +155,11 @@ typedef union unsigned int ecx; unsigned int edx; }; -} -CPU_ID_REGISTERS; +} CPU_ID_REGISTERS; -typedef struct -{ - union - { - struct - { +typedef struct { + union { + struct { int maximum_cpu_id_input; char cpu_vendor [16]; }; @@ -178,19 +167,15 @@ typedef struct CPU_ID_REGISTERS cpu_id_registers_0; }; - union - { + union { CPU_ID_REGISTERS cpu_id_registers_1; - struct - { + struct { // eax - union - { + union { unsigned int eax; unsigned int version_information; - struct - { + struct { unsigned int stepping_id : 4; unsigned int model : 4; unsigned int family : 4; @@ -203,11 +188,9 @@ typedef struct }; // ebx - union - { + union { unsigned int ebx; - struct - { + struct { unsigned int brand_index : 8; unsigned int clflush : 8; unsigned int maximum_logical_processors : 8; @@ -216,11 +199,9 @@ typedef struct }; // ecx - union - { + union { unsigned int ecx; - struct - { + struct { unsigned int sse3 : 1; unsigned int reserved_1_to_2 : 2; unsigned int monitor : 1; @@ -239,11 +220,9 @@ typedef struct }; // edx - union - { + union { unsigned int edx; - struct - { + struct { unsigned int fpu : 1; unsigned int vme : 1; unsigned int de : 1; @@ -282,71 +261,47 @@ typedef struct }; #define MAXIMUM_2 8 - #define MAXIMUM_CHARACTERS (MAXIMUM_2 * sizeof (CPU_ID_REGISTERS)) + #define MAXIMUM_CHARACTERS (MAXIMUM_2 * sizeof(CPU_ID_REGISTERS)) - union - { + union { CPU_ID_REGISTERS cpu_id_registers_2; unsigned char character_array_2 [MAXIMUM_CHARACTERS]; CPU_ID_REGISTERS cpu_id_registers_2_array [MAXIMUM_2]; }; - union - { + union { CPU_ID_REGISTERS cpu_id_registers_0x80000000; }; - union - { + union { CPU_ID_REGISTERS cpu_id_registers_0x80000001; }; - union - { - char cpu_brand_string [sizeof (CPU_ID_REGISTERS) * 3]; - struct - { + union { + char cpu_brand_string [sizeof(CPU_ID_REGISTERS) * 3]; + struct { CPU_ID_REGISTERS cpu_id_registers_0x80000002; CPU_ID_REGISTERS cpu_id_registers_0x80000003; CPU_ID_REGISTERS cpu_id_registers_0x80000004; }; }; - union - { - struct - { - // eax - union - { - unsigned int eax; - }; - - // ebx - union - { - unsigned int ebx; - }; - - // ecx - union - { + union { + struct { + unsigned int eax; + unsigned int ebx; + union { unsigned int ecx; - struct - { + struct { unsigned int l1_data_cache_line_size : 8; unsigned int l1_data_reserved_8_to_15 : 8; unsigned int l1_data_associativity : 8; unsigned int l1_data_cache_size : 8; }; }; - - // edx - union - { + union { unsigned int edx; - struct - { + struct { unsigned int l1_code_cache_line_size : 8; unsigned int l1_code_reserved_8_to_15 : 8; unsigned int l1_code_associativity : 8; @@ -357,82 +312,31 @@ typedef struct CPU_ID_REGISTERS cpu_id_registers_0x80000005; }; - union - { - struct - { - // eax - union - { - unsigned int eax; - }; - - // ebx - union - { - unsigned int ebx; - }; - - // ecx - union - { + union { + struct { + unsigned int eax; + unsigned int ebx; + union { unsigned int ecx; - struct - { + struct { unsigned int l2_cache_line_size : 8; unsigned int l2_reserved_8_to_11 : 4; unsigned int l2_associativity : 4; unsigned int l2_cache_size : 16; }; }; - - // edx - union - { - unsigned int edx; - }; + unsigned int edx; }; CPU_ID_REGISTERS cpu_id_registers_0x80000006; }; - union - { - struct - { - // eax - union - { - unsigned int eax; - }; + CPU_ID_REGISTERS cpu_id_registers_0x80000008; - // ebx - union - { - unsigned int ebx; - }; - - // ecx - union - { - unsigned int ecx; - }; - - // edx - union - { - unsigned int edx; - }; - }; - CPU_ID_REGISTERS cpu_id_registers_0x80000008; - }; - unsigned int cache_line_size; unsigned int log_base_2_cache_line_size; -} -CPU_ID; +} CPU_ID; -typedef struct -{ +typedef struct { CPU_ID_REGISTERS cpu_id_registers_0; CPU_ID_REGISTERS cpu_id_registers_1; @@ -445,63 +349,48 @@ typedef struct CPU_ID_REGISTERS cpu_id_registers_0x80000006; CPU_ID_REGISTERS cpu_id_registers_0x80000008; -} -CPU_ID_BINARY_DATA; - -typedef struct -{ - union - { - CPU_ID_BINARY_DATA cpu_binary_data; - unsigned int data_array [sizeof (CPU_ID_BINARY_DATA) / 4]; - }; -} -CPU_ID_BINARY_DATA_ARRAY; +} CPU_ID_BINARY_DATA; void cpu_id_to_cpu_id_binary_data (CPU_ID *cpu_id, CPU_ID_BINARY_DATA *cpu_id_binary_data) { - - cpu_id_binary_data -> cpu_id_registers_0 = cpu_id -> cpu_id_registers_0; - cpu_id_binary_data -> cpu_id_registers_1 = cpu_id -> cpu_id_registers_1; - cpu_id_binary_data -> cpu_id_registers_0x80000000 = cpu_id -> cpu_id_registers_0x80000000; - cpu_id_binary_data -> cpu_id_registers_0x80000001 = cpu_id -> cpu_id_registers_0x80000001; - cpu_id_binary_data -> cpu_id_registers_0x80000002 = cpu_id -> cpu_id_registers_0x80000002; - cpu_id_binary_data -> cpu_id_registers_0x80000003 = cpu_id -> cpu_id_registers_0x80000003; - cpu_id_binary_data -> cpu_id_registers_0x80000004 = cpu_id -> cpu_id_registers_0x80000004; - cpu_id_binary_data -> cpu_id_registers_0x80000006 = cpu_id -> cpu_id_registers_0x80000006; - cpu_id_binary_data -> cpu_id_registers_0x80000008 = cpu_id -> cpu_id_registers_0x80000008; + cpu_id_binary_data->cpu_id_registers_0 = cpu_id->cpu_id_registers_0; + cpu_id_binary_data->cpu_id_registers_1 = cpu_id->cpu_id_registers_1; + cpu_id_binary_data->cpu_id_registers_0x80000000 = cpu_id->cpu_id_registers_0x80000000; + cpu_id_binary_data->cpu_id_registers_0x80000001 = cpu_id->cpu_id_registers_0x80000001; + cpu_id_binary_data->cpu_id_registers_0x80000002 = cpu_id->cpu_id_registers_0x80000002; + cpu_id_binary_data->cpu_id_registers_0x80000003 = cpu_id->cpu_id_registers_0x80000003; + cpu_id_binary_data->cpu_id_registers_0x80000004 = cpu_id->cpu_id_registers_0x80000004; + cpu_id_binary_data->cpu_id_registers_0x80000006 = cpu_id->cpu_id_registers_0x80000006; + cpu_id_binary_data->cpu_id_registers_0x80000008 = cpu_id->cpu_id_registers_0x80000008; } void cpu_id_binary_data_to_cpu_id (CPU_ID_BINARY_DATA *cpu_id_binary_data, CPU_ID *cpu_id) { + memset (cpu_id, 0, sizeof(CPU_ID)); - memset (cpu_id, 0, sizeof (CPU_ID)); - - cpu_id -> cpu_id_registers_0 = cpu_id_binary_data -> cpu_id_registers_0; - cpu_id -> cpu_id_registers_1 = cpu_id_binary_data -> cpu_id_registers_1; - cpu_id -> cpu_id_registers_0x80000000 = cpu_id_binary_data -> cpu_id_registers_0x80000000; - cpu_id -> cpu_id_registers_0x80000001 = cpu_id_binary_data -> cpu_id_registers_0x80000001; - cpu_id -> cpu_id_registers_0x80000002 = cpu_id_binary_data -> cpu_id_registers_0x80000002; - cpu_id -> cpu_id_registers_0x80000003 = cpu_id_binary_data -> cpu_id_registers_0x80000003; - cpu_id -> cpu_id_registers_0x80000004 = cpu_id_binary_data -> cpu_id_registers_0x80000004; - cpu_id -> cpu_id_registers_0x80000006 = cpu_id_binary_data -> cpu_id_registers_0x80000006; - cpu_id -> cpu_id_registers_0x80000008 = cpu_id_binary_data -> cpu_id_registers_0x80000008; + cpu_id->cpu_id_registers_0 = cpu_id_binary_data->cpu_id_registers_0; + cpu_id->cpu_id_registers_1 = cpu_id_binary_data->cpu_id_registers_1; + cpu_id->cpu_id_registers_0x80000000 = cpu_id_binary_data->cpu_id_registers_0x80000000; + cpu_id->cpu_id_registers_0x80000001 = cpu_id_binary_data->cpu_id_registers_0x80000001; + cpu_id->cpu_id_registers_0x80000002 = cpu_id_binary_data->cpu_id_registers_0x80000002; + cpu_id->cpu_id_registers_0x80000003 = cpu_id_binary_data->cpu_id_registers_0x80000003; + cpu_id->cpu_id_registers_0x80000004 = cpu_id_binary_data->cpu_id_registers_0x80000004; + cpu_id->cpu_id_registers_0x80000006 = cpu_id_binary_data->cpu_id_registers_0x80000006; + cpu_id->cpu_id_registers_0x80000008 = cpu_id_binary_data->cpu_id_registers_0x80000008; } -int cpuid (int input_eax, CPU_ID_REGISTERS *cpu_id_registers) { +int cpuid(int input_eax, CPU_ID_REGISTERS *cpu_id_registers) { int state; - state = false; - __try - { + state = false; + __try { if (input_eax == 0) { // the order of ecx and edx is swapped when saved to make a proper vendor string #ifdef _WIN64 - __cpuid((int*)cpu_id_registers, input_eax); - unsigned int tmp = cpu_id_registers->edx; - cpu_id_registers->edx = cpu_id_registers->ecx; - cpu_id_registers->ecx = tmp; + __cpuid((int*)cpu_id_registers, input_eax); + unsigned int tmp = cpu_id_registers->edx; + cpu_id_registers->edx = cpu_id_registers->ecx; + cpu_id_registers->ecx = tmp; #else - __asm - { + __asm { mov eax, [input_eax] mov edi, [cpu_id_registers] @@ -513,13 +402,11 @@ int cpuid (int input_eax, CPU_ID_REGISTERS *cpu_id_registers) { mov [edi + 12], ecx } #endif - } - else { + } else { #ifdef _WIN64 - __cpuid((int*)cpu_id_registers, input_eax); + __cpuid((int*)cpu_id_registers, input_eax); #else - __asm - { + __asm { mov eax, [input_eax] mov edi, [cpu_id_registers] @@ -535,153 +422,144 @@ int cpuid (int input_eax, CPU_ID_REGISTERS *cpu_id_registers) { state = true; } - __except (1) - { + __except (1) { state = false; } return state; } -void parse_cpu_id (CPU_ID *cpu_id) { +void parse_cpu_id(CPU_ID *cpu_id) { + printf("CPUID\n"); + printf(" vendor = %s\n", cpu_id->cpu_vendor); + printf(" brand string %s\n", cpu_id->cpu_brand_string); + printf(" maximum_cpu_id_input = %u\n", cpu_id->maximum_cpu_id_input); + printf(" maximum extended information = 0x%X\n", cpu_id->cpu_id_registers_0x80000000.eax); - printf ("CPUID\n"); - printf (" vendor = %s \n", cpu_id -> cpu_vendor); - printf (" brand string %s \n", cpu_id -> cpu_brand_string); - printf (" maximum_cpu_id_input = %u \n", cpu_id -> maximum_cpu_id_input); - printf (" maximum extended information = 0x%X \n", cpu_id -> cpu_id_registers_0x80000000.eax); + printf(" MMX = %u\n", cpu_id->mmx); + printf(" SSE = %u\n", cpu_id->sse); + printf(" SSE2 = %u\n", cpu_id->sse2); + printf(" SSE3 = %u\n", cpu_id->sse3); - printf (" MMX = %u \n", cpu_id -> mmx); - printf (" SSE = %u \n", cpu_id -> sse); - printf (" SSE2 = %u \n", cpu_id -> sse2); - printf (" SSE3 = %u \n", cpu_id -> sse3); + printf(" EST = %u\n", cpu_id->est); - printf (" EST = %u \n", cpu_id -> est); + if (cpu_id->maximum_cpu_id_input >= 1) { + printf(" version_information\n"); + printf(" stepping_id %u\n", cpu_id->stepping_id); + printf(" model %u\n", cpu_id->model); + printf(" family %u\n", cpu_id->family); + printf(" processor_type %u\n", cpu_id->processor_type); + printf(" extended_model_id %u\n", cpu_id->extended_model_id); + printf(" extended_family_id %u\n", cpu_id->extended_family_id); - if (cpu_id -> maximum_cpu_id_input >= 1) { - printf (" version_information \n"); - printf (" stepping_id %u \n", cpu_id -> stepping_id); - printf (" model %u \n", cpu_id -> model); - printf (" family %u \n", cpu_id -> family); - printf (" processor_type %u \n", cpu_id -> processor_type); - printf (" extended_model_id %u \n", cpu_id -> extended_model_id); - printf (" extended_family_id %u \n", cpu_id -> extended_family_id); + printf(" brand_index %u\n", cpu_id->brand_index); + printf(" clflush %u\n", cpu_id->clflush); + printf(" maximum_logical_processors %u\n", cpu_id->maximum_logical_processors); + printf(" initial_apic_id %u\n", cpu_id->initial_apic_id); - printf (" brand_index %u \n", cpu_id -> brand_index); - printf (" clflush %u \n", cpu_id -> clflush); - printf (" maximum_logical_processors %u \n", cpu_id -> maximum_logical_processors); - printf (" initial_apic_id %u \n", cpu_id -> initial_apic_id); - -// printf (" cache_line_size %u \n", cpu_id -> cache_line_size); -// printf (" log_base_2_cache_line_size %u \n", cpu_id -> log_base_2_cache_line_size); +// printf(" cache_line_size %u\n", cpu_id->cache_line_size); +// printf(" log_base_2_cache_line_size %u\n", cpu_id->log_base_2_cache_line_size); } - if (cpu_id -> cpu_id_registers_0x80000000.eax >= 0x80000005) { - printf (" l1_data_cache_line_size %d \n", cpu_id -> l1_data_cache_line_size); - printf (" l1_data_associativity %d \n", cpu_id -> l1_data_associativity); - printf (" l1_data_cache_size %dK \n", cpu_id -> l1_data_cache_size); + if (cpu_id->cpu_id_registers_0x80000000.eax >= 0x80000005) { + printf(" l1_data_cache_line_size %d\n", cpu_id->l1_data_cache_line_size); + printf(" l1_data_associativity %d\n", cpu_id->l1_data_associativity); + printf(" l1_data_cache_size %dK\n", cpu_id->l1_data_cache_size); - printf (" l1_code_cache_line_size %d \n", cpu_id -> l1_code_cache_line_size); - printf (" l1_code_associativity %d \n", cpu_id -> l1_code_associativity); - printf (" l1_code_cache_size %dK \n", cpu_id -> l1_code_cache_size); + printf(" l1_code_cache_line_size %d\n", cpu_id->l1_code_cache_line_size); + printf(" l1_code_associativity %d\n", cpu_id->l1_code_associativity); + printf(" l1_code_cache_size %dK\n", cpu_id->l1_code_cache_size); } - if (cpu_id -> cpu_id_registers_0x80000000.eax >= 0x80000006) { - printf (" l2_cache_line_size %d \n", cpu_id -> l2_cache_line_size); - printf (" l2_associativity %d \n", cpu_id -> l2_associativity); - printf (" l2_cache_size %dK \n", cpu_id -> l2_cache_size); + if (cpu_id->cpu_id_registers_0x80000000.eax >= 0x80000006) { + printf(" l2_cache_line_size %d\n", cpu_id->l2_cache_line_size); + printf(" l2_associativity %d\n", cpu_id->l2_associativity); + printf(" l2_cache_size %dK\n", cpu_id->l2_cache_size); } } -int initialize_cpu_id (CPU_ID *cpu_id) { +int initialize_cpu_id(CPU_ID *cpu_id) { + int debug = false; + memset(cpu_id, 0, sizeof(CPU_ID)); - int state; - int debug; - - state = false; - debug = false; - memset (cpu_id, 0, sizeof (CPU_ID)); - - if (cpuid (0, &cpu_id -> cpu_id_registers_0)) { - if (cpu_id -> maximum_cpu_id_input >= 1) { - cpuid (1, &cpu_id -> cpu_id_registers_1); + if (cpuid(0, &cpu_id->cpu_id_registers_0)) { + if (cpu_id->maximum_cpu_id_input >= 1) { + cpuid(1, &cpu_id->cpu_id_registers_1); } - if (cpu_id -> maximum_cpu_id_input >= 2) { + if (cpu_id->maximum_cpu_id_input >= 2) { unsigned int index; - cpuid (2, &cpu_id -> cpu_id_registers_2); + cpuid(2, &cpu_id->cpu_id_registers_2); if (debug) { - printf (" al = %u \n", cpu_id -> cpu_id_registers_2.al); + printf(" al = %u\n", cpu_id->cpu_id_registers_2.al); } - - for (index = 1; index < cpu_id -> cpu_id_registers_2.al && index < MAXIMUM_2; index++) { - cpuid (2, &cpu_id -> cpu_id_registers_2_array [index]); + + for (index = 1; index < cpu_id->cpu_id_registers_2.al && index < MAXIMUM_2; index++) { + cpuid(2, &cpu_id->cpu_id_registers_2_array [index]); } for (index = 1; index < MAXIMUM_CHARACTERS; index++) { - if (cpu_id -> character_array_2 [index]) { + if (cpu_id->character_array_2 [index]) { if (debug) { - printf (" cache/TLB byte = %X \n", cpu_id -> character_array_2 [index]); + printf(" cache/TLB byte = %X\n", cpu_id->character_array_2 [index]); } - switch (cpu_id -> character_array_2 [index]) - { - case 0x0A: - case 0x0C: - cpu_id -> cache_line_size = 32; - cpu_id -> log_base_2_cache_line_size = 5; - break; + switch (cpu_id->character_array_2 [index]) { + case 0x0A: + case 0x0C: + cpu_id->cache_line_size = 32; + cpu_id->log_base_2_cache_line_size = 5; + break; - case 0x2C: - case 0x60: - case 0x66: - case 0x67: - case 0x68: - cpu_id -> cache_line_size = 64; - cpu_id -> log_base_2_cache_line_size = 6; - break; + case 0x2C: + case 0x60: + case 0x66: + case 0x67: + case 0x68: + cpu_id->cache_line_size = 64; + cpu_id->log_base_2_cache_line_size = 6; + break; } } } } - cpuid (0x80000000, &cpu_id -> cpu_id_registers_0x80000000); + cpuid(0x80000000, &cpu_id->cpu_id_registers_0x80000000); - if (cpu_id -> cpu_id_registers_0x80000000.eax >= 0x80000001) { - cpuid (0x80000001, &cpu_id -> cpu_id_registers_0x80000001); - } - - if (cpu_id -> cpu_id_registers_0x80000000.eax >= 0x80000004) { - cpuid (0x80000002, &cpu_id -> cpu_id_registers_0x80000002); - cpuid (0x80000003, &cpu_id -> cpu_id_registers_0x80000003); - cpuid (0x80000004, &cpu_id -> cpu_id_registers_0x80000004); + if (cpu_id->cpu_id_registers_0x80000000.eax >= 0x80000001) { + cpuid(0x80000001, &cpu_id->cpu_id_registers_0x80000001); } - if (cpu_id -> cpu_id_registers_0x80000000.eax >= 0x80000005) { - cpuid (0x80000005, &cpu_id -> cpu_id_registers_0x80000005); + if (cpu_id->cpu_id_registers_0x80000000.eax >= 0x80000004) { + cpuid(0x80000002, &cpu_id->cpu_id_registers_0x80000002); + cpuid(0x80000003, &cpu_id->cpu_id_registers_0x80000003); + cpuid(0x80000004, &cpu_id->cpu_id_registers_0x80000004); } - if (cpu_id -> cpu_id_registers_0x80000000.eax >= 0x80000006) { - cpuid (0x80000006, &cpu_id -> cpu_id_registers_0x80000006); + if (cpu_id->cpu_id_registers_0x80000000.eax >= 0x80000005) { + cpuid(0x80000005, &cpu_id->cpu_id_registers_0x80000005); } - if (cpu_id -> cpu_id_registers_0x80000000.eax >= 0x80000008) { - cpuid (0x80000008, &cpu_id -> cpu_id_registers_0x80000008); - } + if (cpu_id->cpu_id_registers_0x80000000.eax >= 0x80000006) { + cpuid(0x80000006, &cpu_id->cpu_id_registers_0x80000006); + } - state = true; + if (cpu_id->cpu_id_registers_0x80000000.eax >= 0x80000008) { + cpuid(0x80000008, &cpu_id->cpu_id_registers_0x80000008); + } + + return true; } - - return state; + + return false; } -int update_cpu_frequency_function (int processor_number, DisplayInformation *display_information) -{ +int update_cpu_frequency_function(int processor_number, DisplayInformation *display_information) { int update; - + update = false; - display_information -> _maximum_cpu_frequency = 0; - display_information -> _current_cpu_frequency = 0; - + display_information->_maximum_cpu_frequency = 0; + display_information->_current_cpu_frequency = 0; + if (CallNtPowerInformationFunction) { int i; @@ -692,38 +570,38 @@ int update_cpu_frequency_function (int processor_number, DisplayInformation *dis POWER_INFORMATION_LEVEL information_level; PROCESSOR_POWER_INFORMATION *processor_power_information; PROCESSOR_POWER_INFORMATION processor_power_information_array [MAXIMUM_PROCESSORS]; - - memset (processor_power_information_array, 0, sizeof (PROCESSOR_POWER_INFORMATION) * MAXIMUM_PROCESSORS); + + memset(processor_power_information_array, 0, sizeof(PROCESSOR_POWER_INFORMATION) * MAXIMUM_PROCESSORS); processor_power_information = processor_power_information_array; for (i = 0; i < MAXIMUM_PROCESSORS; i++) { - processor_power_information -> Number = 0xFFFFFFFF; + processor_power_information->Number = 0xFFFFFFFF; processor_power_information++; } - + information_level = ProcessorInformation; input_buffer = NULL; output_buffer = processor_power_information_array; input_buffer_size = 0; - output_buffer_size = sizeof (PROCESSOR_POWER_INFORMATION) * MAXIMUM_PROCESSORS; - if (CallNtPowerInformationFunction (information_level, input_buffer, input_buffer_size, output_buffer, output_buffer_size) == 0) { + output_buffer_size = sizeof(PROCESSOR_POWER_INFORMATION) * MAXIMUM_PROCESSORS; + if (CallNtPowerInformationFunction(information_level, input_buffer, input_buffer_size, output_buffer, output_buffer_size) == 0) { processor_power_information = processor_power_information_array; for (i = 0; i < MAXIMUM_PROCESSORS; i++) { - if (processor_power_information -> Number == processor_number) { + if (processor_power_information->Number == processor_number) { PN_uint64 value; - value = processor_power_information -> MaxMhz; - display_information -> _maximum_cpu_frequency = value * 1000000; + value = processor_power_information->MaxMhz; + display_information->_maximum_cpu_frequency = value * 1000000; - value = processor_power_information -> CurrentMhz; - display_information -> _current_cpu_frequency = value * 1000000; + value = processor_power_information->CurrentMhz; + display_information->_current_cpu_frequency = value * 1000000; update = true; break; } processor_power_information++; - } + } } } @@ -736,7 +614,7 @@ count_number_of_cpus(DisplayInformation *display_information) { int num_logical_cpus = 0; // Get a pointer to the GetLogicalProcessorInformation function. - typedef BOOL (WINAPI *LPFN_GLPI)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, + typedef BOOL (WINAPI *LPFN_GLPI)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD); LPFN_GLPI glpi; glpi = (LPFN_GLPI)GetProcAddress(GetModuleHandle(TEXT("kernel32")), @@ -801,11 +679,8 @@ count_number_of_cpus(DisplayInformation *display_information) { //////////////////////////////////////////////////////////////////// WinGraphicsPipe:: WinGraphicsPipe() { - - bool state; char string [512]; - state = false; _supported_types = OT_window | OT_fullscreen_window; // these fns arent defined on win95, so get dynamic ptrs to them @@ -819,15 +694,38 @@ WinGraphicsPipe() { } #ifdef HAVE_DX9 - if (request_dxdisplay_information){ + // Use D3D to get display info. This is disabled by default as it is slow. + if (request_dxdisplay_information) { DisplaySearchParameters display_search_parameters_dx9; int dx9_display_information (DisplaySearchParameters &display_search_parameters_dx9, DisplayInformation *display_information); + dx9_display_information(display_search_parameters_dx9, _display_information); + } else +#endif + { + // Use the Win32 API to query the available display modes. + pvector display_modes; + DEVMODE dm = {0}; + dm.dmSize = sizeof(dm); + for (int i = 0; EnumDisplaySettings(NULL, i, &dm) != 0; ++i) { + DisplayMode mode; + mode.width = dm.dmPelsWidth; + mode.height = dm.dmPelsHeight; + mode.bits_per_pixel = dm.dmBitsPerPel; + mode.refresh_rate = dm.dmDisplayFrequency; + mode.fullscreen_only = 0; + if (i == 0 || mode != display_modes.back()) { + display_modes.push_back(mode); + } + } - if (state == false && dx9_display_information (display_search_parameters_dx9, _display_information)) { - state = true; + // Copy this information to the DisplayInformation object. + _display_information->_total_display_modes = display_modes.size(); + if (!display_modes.empty()) { + _display_information->_display_mode_array = new DisplayMode[display_modes.size()]; + std::copy(display_modes.begin(), display_modes.end(), + _display_information->_display_mode_array); } } -#endif if (auto_cpu_data) { lookup_cpu_data(); @@ -836,15 +734,17 @@ WinGraphicsPipe() { OSVERSIONINFO version_info; version_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - if (GetVersionEx (&version_info)) { - sprintf (string, "OS version: %d.%d.%d.%d \n", version_info.dwMajorVersion, version_info.dwMinorVersion, version_info.dwPlatformId, version_info.dwBuildNumber); - windisplay_cat.info() << string; - windisplay_cat.info() << " " << version_info.szCSDVersion << "\n"; + if (GetVersionEx(&version_info)) { + if (windisplay_cat.is_info()) { + sprintf(string, "OS version: %d.%d.%d.%d\n", version_info.dwMajorVersion, version_info.dwMinorVersion, version_info.dwPlatformId, version_info.dwBuildNumber); + windisplay_cat.info() << string; + windisplay_cat.info() << " " << version_info.szCSDVersion << "\n"; + } - _display_information -> _os_version_major = version_info.dwMajorVersion; - _display_information -> _os_version_minor = version_info.dwMinorVersion; - _display_information -> _os_version_build = version_info.dwBuildNumber; - _display_information -> _os_platform_id = version_info.dwPlatformId; + _display_information->_os_version_major = version_info.dwMajorVersion; + _display_information->_os_version_minor = version_info.dwMinorVersion; + _display_information->_os_version_build = version_info.dwBuildNumber; + _display_information->_os_platform_id = version_info.dwPlatformId; } // Screen size _display_width = GetSystemMetrics(SM_CXSCREEN); @@ -852,23 +752,19 @@ WinGraphicsPipe() { HMODULE power_dll; - power_dll = LoadLibrary ("PowrProf.dll"); + power_dll = LoadLibrary("PowrProf.dll"); if (power_dll) { - CallNtPowerInformationFunction = (CallNtPowerInformationType) GetProcAddress (power_dll, "CallNtPowerInformation"); + CallNtPowerInformationFunction = (CallNtPowerInformationType) GetProcAddress(power_dll, "CallNtPowerInformation"); if (CallNtPowerInformationFunction) { - _display_information -> _update_cpu_frequency_function = update_cpu_frequency_function; + _display_information->_update_cpu_frequency_function = update_cpu_frequency_function; update_cpu_frequency_function(0, _display_information); - sprintf (string, "max Mhz %I64d, current Mhz %I64d \n", _display_information -> _maximum_cpu_frequency, _display_information -> _current_cpu_frequency); + sprintf(string, "max Mhz %I64d, current Mhz %I64d\n", _display_information->_maximum_cpu_frequency, _display_information->_current_cpu_frequency); windisplay_cat.info() << string; } } - - if (state) { - - } } //////////////////////////////////////////////////////////////////// @@ -883,10 +779,10 @@ lookup_cpu_data() { char string [512]; // set callback for memory function - _display_information -> _get_memory_information_function = get_memory_information; + _display_information->_get_memory_information_function = get_memory_information; // set callback for cpu time function - _display_information -> _cpu_time_function = cpu_time_function; + _display_information->_cpu_time_function = cpu_time_function; // determine CPU frequency PN_uint64 time; @@ -900,7 +796,7 @@ lookup_cpu_data() { counter.QuadPart = 0; end.QuadPart = 0; frequency.QuadPart = 0; - + int priority; HANDLE thread; @@ -908,8 +804,8 @@ lookup_cpu_data() { thread = GetCurrentThread(); priority = GetThreadPriority (thread); SetThreadPriority(thread, THREAD_PRIORITY_TIME_CRITICAL); - - if (QueryPerformanceFrequency(&frequency)) { + + if (QueryPerformanceFrequency(&frequency)) { if (frequency.QuadPart > 0) { if (QueryPerformanceCounter (&counter)) { time = cpu_time_function(); @@ -919,15 +815,15 @@ lookup_cpu_data() { } end_time = cpu_time_function(); - _display_information -> _cpu_frequency = end_time - time; + _display_information->_cpu_frequency = end_time - time; } } } SetThreadPriority(thread, priority); - sprintf (string, "QueryPerformanceFrequency: %I64d\n", frequency.QuadPart); + sprintf(string, "QueryPerformanceFrequency: %I64d\n", frequency.QuadPart); windisplay_cat.info() << string; - sprintf (string, "CPU frequency: %I64d\n", _display_information -> _cpu_frequency); + sprintf(string, "CPU frequency: %I64d\n", _display_information->_cpu_frequency); windisplay_cat.info() << string; @@ -935,34 +831,33 @@ lookup_cpu_data() { CPU_ID cpu_id; windisplay_cat.info() << "start CPU ID\n"; - - if (initialize_cpu_id (&cpu_id)) { - CPU_ID_BINARY_DATA *cpu_id_binary_data; - - cpu_id_binary_data = new (CPU_ID_BINARY_DATA); - if (cpu_id_binary_data) { - cpu_id_to_cpu_id_binary_data (&cpu_id, cpu_id_binary_data); - _display_information -> _cpu_id_size = sizeof (CPU_ID_BINARY_DATA) / sizeof (unsigned int); - _display_information -> _cpu_id_data = (unsigned int *) cpu_id_binary_data; - _display_information -> _cpu_vendor_string = strdup(cpu_id.cpu_vendor); - _display_information -> _cpu_brand_string = strdup(cpu_id.cpu_brand_string); - _display_information -> _cpu_version_information = cpu_id.version_information; - _display_information -> _cpu_brand_index = cpu_id.brand_index; + if (initialize_cpu_id(&cpu_id)) { + CPU_ID_BINARY_DATA *cpu_id_binary_data; + + cpu_id_binary_data = new (CPU_ID_BINARY_DATA); + if (cpu_id_binary_data) { + cpu_id_to_cpu_id_binary_data(&cpu_id, cpu_id_binary_data); + _display_information->_cpu_id_size = sizeof(CPU_ID_BINARY_DATA) / sizeof(unsigned int); + _display_information->_cpu_id_data = (unsigned int *) cpu_id_binary_data; + + _display_information->_cpu_vendor_string = strdup(cpu_id.cpu_vendor); + _display_information->_cpu_brand_string = strdup(cpu_id.cpu_brand_string); + _display_information->_cpu_version_information = cpu_id.version_information; + _display_information->_cpu_brand_index = cpu_id.brand_index; if (windisplay_cat.is_debug()) { windisplay_cat.debug() - << hex << _display_information -> _cpu_id_version << dec << "|"; + << hex << _display_information->_cpu_id_version << dec << "|"; int index; - for (index = 0; index < _display_information -> _cpu_id_size; index++) { + for (index = 0; index < _display_information->_cpu_id_size; ++index) { unsigned int data; - - data = _display_information -> _cpu_id_data [index]; + data = _display_information->_cpu_id_data[index]; windisplay_cat.debug(false) << hex << data << dec; - if (index < (_display_information -> _cpu_id_size - 1)) { + if (index < _display_information->_cpu_id_size - 1) { windisplay_cat.debug(false) << "|"; } @@ -973,7 +868,7 @@ lookup_cpu_data() { } if (windisplay_cat.is_debug()) { - parse_cpu_id (&cpu_id); + parse_cpu_id(&cpu_id); } } @@ -986,7 +881,7 @@ lookup_cpu_data() { //////////////////////////////////////////////////////////////////// // Function: WinGraphicsPipe::Destructor // Access: Public, Virtual -// Description: +// Description: //////////////////////////////////////////////////////////////////// WinGraphicsPipe:: ~WinGraphicsPipe() { From 672a191d2a8e4a0d66ff6e88091238c2e83a5ef5 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 19 Jul 2015 21:23:46 +0200 Subject: [PATCH 11/12] Improve error message when Cg support is not enabled --- panda/src/glstuff/glGraphicsStateGuardian_src.cxx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index db342f423a..e05e1e2d8e 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -4828,8 +4828,8 @@ prepare_shader(Shader *se) { return NULL; } -#if defined(HAVE_CG) && !defined(OPENGLES) case Shader::SL_Cg: +#if defined(HAVE_CG) && !defined(OPENGLES) if (_supports_basic_shaders) { result = new CLP(CgShaderContext)(this, se); break; @@ -4838,6 +4838,10 @@ prepare_shader(Shader *se) { << "Tried to load Cg shader, but basic shaders not supported.\n"; return NULL; } +#elif defined(OPENGLES) + GLCAT.error() + << "Tried to load Cg shader, but Cg support is not available for OpenGL ES.\n"; + return NULL; #else GLCAT.error() << "Tried to load Cg shader, but Cg support not compiled in.\n"; From 87b23dfeb20778bd43160e94c561b3909f7d4b6d Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 19 Jul 2015 21:31:24 +0200 Subject: [PATCH 12/12] Improve shader model detection mechanism --- panda/src/cocoadisplay/cocoaGraphicsPipe.mm | 1 + panda/src/display/displayInformation.cxx | 10 +- panda/src/display/displayInformation.h | 7 +- panda/src/display/graphicsPipe.cxx | 1 + panda/src/display/graphicsPipe.h | 2 +- panda/src/display/graphicsStateGuardian.I | 4 +- panda/src/display/graphicsStateGuardian.cxx | 8 ++ panda/src/display/graphicsStateGuardian.h | 11 +- .../glstuff/glGraphicsStateGuardian_src.cxx | 132 ++++++++---------- panda/src/osxdisplay/osxGraphicsPipe.cxx | 1 + panda/src/windisplay/winDetectDx.h | 3 +- panda/src/x11display/x11GraphicsPipe.cxx | 1 + 12 files changed, 91 insertions(+), 90 deletions(-) diff --git a/panda/src/cocoadisplay/cocoaGraphicsPipe.mm b/panda/src/cocoadisplay/cocoaGraphicsPipe.mm index 1969ac4116..7883bad834 100644 --- a/panda/src/cocoadisplay/cocoaGraphicsPipe.mm +++ b/panda/src/cocoadisplay/cocoaGraphicsPipe.mm @@ -19,6 +19,7 @@ #include "cocoaPandaApp.h" #include "config_cocoadisplay.h" #include "frameBufferProperties.h" +#include "displayInformation.h" #import #import diff --git a/panda/src/display/displayInformation.cxx b/panda/src/display/displayInformation.cxx index 41eab9d020..3cdcd067ec 100644 --- a/panda/src/display/displayInformation.cxx +++ b/panda/src/display/displayInformation.cxx @@ -90,13 +90,12 @@ DisplayInformation() { int window_bits_per_pixel; int total_display_modes; DisplayMode *display_mode_array; - int shader_model; int video_memory; int texture_memory; PN_uint64 physical_memory; PN_uint64 available_physical_memory; - state = DisplayInformation::DS_unknown; + state = DisplayInformation::DS_unknown; get_adapter_display_mode_state = false; get_device_caps_state = false; window_width = 0; @@ -104,7 +103,6 @@ DisplayInformation() { window_bits_per_pixel = 0; total_display_modes = 0; display_mode_array = NULL; - shader_model = GraphicsStateGuardian::SM_00; video_memory = 0; texture_memory = 0; physical_memory = 0; @@ -118,7 +116,7 @@ DisplayInformation() { _window_bits_per_pixel = window_bits_per_pixel; _total_display_modes = total_display_modes; _display_mode_array = display_mode_array; - _shader_model = shader_model; + _shader_model = GraphicsStateGuardian::SM_00; _video_memory = video_memory; _texture_memory = texture_memory; @@ -328,8 +326,8 @@ get_display_mode_fullscreen_only (int display_index) { // Access: Published // Description: //////////////////////////////////////////////////////////////////// -int DisplayInformation:: -get_shader_model ( ) { +GraphicsStateGuardian::ShaderModel DisplayInformation:: +get_shader_model() { return _shader_model; } diff --git a/panda/src/display/displayInformation.h b/panda/src/display/displayInformation.h index 32ee8c687e..c4d624097e 100644 --- a/panda/src/display/displayInformation.h +++ b/panda/src/display/displayInformation.h @@ -16,6 +16,7 @@ #define DISPLAYINFORMATION_H #include "typedef.h" +#include "graphicsStateGuardian.h" struct EXPCL_PANDA_DISPLAY DisplayMode { PUBLISHED: @@ -65,7 +66,7 @@ PUBLISHED: int get_display_mode_refresh_rate(int display_index); int get_display_mode_fullscreen_only(int display_index); - int get_shader_model(); + GraphicsStateGuardian::ShaderModel get_shader_model(); int get_video_memory(); int get_texture_memory(); @@ -126,9 +127,9 @@ public: int _maximum_window_width; int _maximum_window_height; int _window_bits_per_pixel; - int _total_display_modes; + int _total_display_modes; DisplayMode *_display_mode_array; - int _shader_model; + GraphicsStateGuardian::ShaderModel _shader_model; int _video_memory; int _texture_memory; diff --git a/panda/src/display/graphicsPipe.cxx b/panda/src/display/graphicsPipe.cxx index 4865e3da9f..0a6978db78 100644 --- a/panda/src/display/graphicsPipe.cxx +++ b/panda/src/display/graphicsPipe.cxx @@ -17,6 +17,7 @@ #include "graphicsBuffer.h" #include "config_display.h" #include "mutexHolder.h" +#include "displayInformation.h" TypeHandle GraphicsPipe::_type_handle; diff --git a/panda/src/display/graphicsPipe.h b/panda/src/display/graphicsPipe.h index 134a3baddd..d505af7a1e 100644 --- a/panda/src/display/graphicsPipe.h +++ b/panda/src/display/graphicsPipe.h @@ -21,7 +21,6 @@ #include "typedReferenceCount.h" #include "pointerTo.h" #include "lightMutex.h" -#include "displayInformation.h" class GraphicsEngine; class GraphicsOutput; @@ -32,6 +31,7 @@ class FrameBufferProperties; class WindowProperties; class Texture; class WindowHandle; +class DisplayInformation; //////////////////////////////////////////////////////////////////// // Class : GraphicsPipe diff --git a/panda/src/display/graphicsStateGuardian.I b/panda/src/display/graphicsStateGuardian.I index 9cfa0e3fed..15b2b89b78 100644 --- a/panda/src/display/graphicsStateGuardian.I +++ b/panda/src/display/graphicsStateGuardian.I @@ -876,7 +876,7 @@ get_maximum_simultaneous_render_targets() const { // Access: Published // Description: Returns the ShaderModel //////////////////////////////////////////////////////////////////// -INLINE int GraphicsStateGuardian:: +INLINE GraphicsStateGuardian::ShaderModel GraphicsStateGuardian:: get_shader_model() const { return _shader_model; } @@ -889,7 +889,7 @@ get_shader_model() const { // testing lower-end shaders. //////////////////////////////////////////////////////////////////// INLINE void GraphicsStateGuardian:: -set_shader_model(int shader_model) { +set_shader_model(ShaderModel shader_model) { if (shader_model <= _auto_detect_shader_model) { _shader_model = shader_model; } diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index 15ebcd9dc2..b2fef6f469 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -3344,3 +3344,11 @@ int GraphicsStateGuardian:: get_driver_shader_version_minor() { return -1; } + +ostream & +operator << (ostream &out, GraphicsStateGuardian::ShaderModel sm) { + static const char *sm_strings[] = {"none", "1.1", "2.0", "2.x", "3.0", "4.0", "5.0", "5.1"}; + nassertr(sm >= 0 && sm <= GraphicsStateGuardian::SM_51, out); + out << sm_strings[sm]; + return out; +} diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index 7e9d8b6f47..cc3c78a1bc 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/panda/src/display/graphicsStateGuardian.h @@ -83,6 +83,7 @@ PUBLISHED: SM_30, SM_40, SM_50, + SM_51, }; INLINE void release_all(); @@ -166,8 +167,8 @@ PUBLISHED: INLINE int get_max_color_targets() const; INLINE int get_maximum_simultaneous_render_targets() const; - INLINE int get_shader_model() const; - INLINE void set_shader_model(int shader_model); + INLINE ShaderModel get_shader_model() const; + INLINE void set_shader_model(ShaderModel shader_model); virtual int get_supported_geom_rendering() const; virtual bool get_supports_cg_profile(const string &name) const; @@ -545,8 +546,8 @@ protected: int _stereo_buffer_mask; - int _auto_detect_shader_model; - int _shader_model; + ShaderModel _auto_detect_shader_model; + ShaderModel _shader_model; static PT(TextureStage) _alpha_scale_texture_stage; @@ -664,6 +665,8 @@ private: friend class GraphicsEngine; }; +EXPCL_PANDA_DISPLAY ostream &operator << (ostream &out, GraphicsStateGuardian::ShaderModel sm); + #include "graphicsStateGuardian.I" #endif diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 02d03b0b66..2fc02f6eb0 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -64,6 +64,7 @@ #include "graphicsEngine.h" #include "shaderGenerator.h" #include "samplerState.h" +#include "displayInformation.h" #if defined(HAVE_CG) && !defined(OPENGLES) #include "Cg/cgGL.h" @@ -2450,58 +2451,39 @@ reset() { report_my_gl_errors(); -#if defined(HAVE_CG) && !defined(OPENGLES) - - typedef struct { - CGprofile cg_profile; - int shader_model; - } CG_PROFILE_TO_SHADER_MODEL; - - static CG_PROFILE_TO_SHADER_MODEL cg_profile_to_shader_model_array[] = { +#ifndef OPENGLES + if (_gl_shadlang_ver_major >= 4 || has_extension("GL_NV_gpu_program5")) { // gp5fp - OpenGL fragment profile for GeForce 400 Series and up - (CGprofile)7017, /*CG_PROFILE_GP5FP,*/ - SM_50, + _shader_model = SM_50; + } else if (_gl_shadlang_ver_major >= 3 || + has_extension("GL_NV_gpu_program4")) { // gp4fp - OpenGL fragment profile for G8x (GeForce 8xxx and up) - (CGprofile)7010, /*CG_PROFILE_GP4FP,*/ - SM_40, + _shader_model = SM_40; + } else if (has_extension("GL_NV_fragment_program2")) { // fp40 - OpenGL fragment profile for NV4x (GeForce 6xxx and 7xxx // Series, NV4x-based Quadro FX, etc.) - CG_PROFILE_FP40, - SM_30, + _shader_model = SM_30; + } else if (has_extension("GL_NV_fragment_program")) { // fp30 - OpenGL fragment profile for NV3x (GeForce FX, Quadro FX, etc.) - CG_PROFILE_FP30, - SM_2X, + _shader_model = SM_2X; + } else if (_gl_shadlang_ver_major >= 1 || + has_extension("GL_ARB_fragment_program")) { // This OpenGL profile corresponds to the per-fragment - // functionality introduced by GeForce FX and other DirectX 9 - // GPUs. - CG_PROFILE_ARBFP1, - SM_20, + // functionality introduced by GeForce FX and other DirectX 9 GPUs. + _shader_model = SM_20; + } else if (has_extension("GL_NV_texture_shader2")) { // fp20 - OpenGL fragment profile for NV2x (GeForce3, GeForce4 Ti, // Quadro DCC, etc.) - CG_PROFILE_FP20, - SM_11, + _shader_model = SM_11; - // no shader support - CG_PROFILE_UNKNOWN, - SM_00, - }; - - int index; - CG_PROFILE_TO_SHADER_MODEL *cg_profile_to_shader_model; - - index = 0; - cg_profile_to_shader_model = cg_profile_to_shader_model_array; - while (cg_profile_to_shader_model->shader_model != SM_00) { - if (cgGLIsProfileSupported(cg_profile_to_shader_model->cg_profile)) { - _shader_model = cg_profile_to_shader_model->shader_model; - break; - } - cg_profile_to_shader_model++; + } else { + // No shader support + _shader_model = SM_00; } // DisplayInformation may have better shader model detection @@ -2521,12 +2503,8 @@ reset() { } _auto_detect_shader_model = _shader_model; - CGprofile vertex_profile; - CGprofile pixel_profile; - - vertex_profile = cgGLGetLatestProfile(CG_GL_VERTEX); - pixel_profile = cgGLGetLatestProfile(CG_GL_FRAGMENT); if (GLCAT.is_debug()) { +#ifdef HAVE_CG #if CG_VERSION_NUM >= 2200 GLCAT.debug() << "Supported Cg profiles:\n"; int num_profiles = cgGetNumSupportedProfiles(); @@ -2539,22 +2517,25 @@ reset() { #endif // CG_VERSION_NUM >= 2200 #if CG_VERSION_NUM >= 3100 - if (GLCAT.is_debug()) { - CGGLglslversion ver = cgGLGetContextGLSLVersion(_cg_context); - GLCAT.debug() - << "Cg GLSL version: " << cgGLGetGLSLVersionString(ver) << "\n"; - } -#endif - + CGGLglslversion ver = cgGLGetContextGLSLVersion(_cg_context); GLCAT.debug() - << "\nCg latest vertex profile = " << cgGetProfileString(vertex_profile) << " id = " << vertex_profile - << "\nCg latest pixel profile = " << cgGetProfileString(pixel_profile) << " id = " << pixel_profile - << "\nshader model = " << _shader_model - << "\n"; - } - + << "Cg GLSL version: " << cgGLGetGLSLVersionString(ver) << "\n"; #endif + CGprofile vertex_profile = cgGLGetLatestProfile(CG_GL_VERTEX); + CGprofile pixel_profile = cgGLGetLatestProfile(CG_GL_FRAGMENT); + GLCAT.debug() + << "Cg latest vertex profile = " << cgGetProfileString(vertex_profile) + << " (" << vertex_profile << ")\n"; + GLCAT.debug() + << "Cg latest pixel profile = " << cgGetProfileString(pixel_profile) + << " (" << pixel_profile << ")\n"; +#endif // HAVE_CG + + GLCAT.debug() << "shader model = " << _shader_model << "\n"; + } +#endif // !OPENGLES + // OpenGL core profile requires a VAO to be bound. It's a bit silly, // because we can just bind a VAO and then forget about it. #if !defined(OPENGLES) @@ -6872,7 +6853,6 @@ query_gl_version() { return; } } -#endif // If we asked for a GL 3 context, let's first try and see if we // can use the OpenGL 3 way to query version. @@ -6890,6 +6870,7 @@ query_gl_version() { return; } } +#endif // !OPENGLES // Otherwise, parse the GL_VERSION string. if (_gl_version.empty()) { @@ -6946,31 +6927,36 @@ query_glsl_version() { _gl_shadlang_ver_minor = 0; #ifndef OPENGLES - if (_gl_version_major == 1) { - if (has_extension("GL_ARB_shading_language_100")) { - _gl_shadlang_ver_major = 1; - _gl_shadlang_ver_minor = 0; - } - } else if (_gl_version_major >= 2) { + // OpenGL 2.0 introduces GLSL in the core. In 1.x, it is an extension. + if (_gl_version_major >= 2 || has_extension("GL_ARB_shading_language_100")) { + string ver = show_gl_string("GL_SHADING_LANGUAGE_VERSION", GL_SHADING_LANGUAGE_VERSION); _gl_shadlang_ver_major = 1; - _gl_shadlang_ver_minor = 1; - const char *verstr = (const char *) glGetString(GL_SHADING_LANGUAGE_VERSION); - if (verstr == NULL || - sscanf(verstr, "%d.%d", &_gl_shadlang_ver_major, - &_gl_shadlang_ver_minor) != 2) { + _gl_shadlang_ver_minor = (_gl_version_major >= 2) ? 1 : 0; + if (ver.empty() || + sscanf(ver.c_str(), "%d.%d", &_gl_shadlang_ver_major, + &_gl_shadlang_ver_minor) != 2) { GLCAT.warning() << "Invalid GL_SHADING_LANGUAGE_VERSION format.\n"; } } -#elif defined(OPENGLES_2) +#elif !defined(OPENGLES_1) + // OpenGL ES 2.0 and above has shader support built-in. + string ver = show_gl_string("GL_SHADING_LANGUAGE_VERSION", GL_SHADING_LANGUAGE_VERSION); _gl_shadlang_ver_major = 1; _gl_shadlang_ver_minor = 0; - const char *verstr = (const char *) glGetString(GL_SHADING_LANGUAGE_VERSION); - if (verstr == NULL || - sscanf(verstr, "OpenGL ES GLSL %d.%d", &_gl_shadlang_ver_major, - &_gl_shadlang_ver_minor) != 2) { + if (ver.empty() || + sscanf(ver.c_str(), "OpenGL ES GLSL %d.%d", &_gl_shadlang_ver_major, + &_gl_shadlang_ver_minor) != 2) { GLCAT.warning() << "Invalid GL_SHADING_LANGUAGE_VERSION format.\n"; } #endif + +#ifndef OPENGLES_1 + if (GLCAT.is_debug()) { + GLCAT.debug() + << "Detected GLSL version: " + << _gl_shadlang_ver_major << "." << _gl_shadlang_ver_minor << "\n"; + } +#endif } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/osxdisplay/osxGraphicsPipe.cxx b/panda/src/osxdisplay/osxGraphicsPipe.cxx index 79e4d9c3c3..5c85bd018e 100644 --- a/panda/src/osxdisplay/osxGraphicsPipe.cxx +++ b/panda/src/osxdisplay/osxGraphicsPipe.cxx @@ -17,6 +17,7 @@ #include "pnmImage.h" #include "subprocessWindow.h" #include "nativeWindowHandle.h" +#include "displayInformation.h" #import // some macros to make code more readable. diff --git a/panda/src/windisplay/winDetectDx.h b/panda/src/windisplay/winDetectDx.h index f04d468090..b88901143d 100644 --- a/panda/src/windisplay/winDetectDx.h +++ b/panda/src/windisplay/winDetectDx.h @@ -13,6 +13,7 @@ //////////////////////////////////////////////////////////////////// #include +#include "displayInformation.h" typedef struct { D3DFORMAT d3d_format; @@ -116,7 +117,7 @@ static int get_display_information (DisplaySearchParameters &display_search_para int get_adapter_display_mode_state; int get_device_caps_state; - int shader_model; + GraphicsStateGuardian::ShaderModel shader_model; UINT minimum_width; UINT maximum_width; UINT minimum_height; diff --git a/panda/src/x11display/x11GraphicsPipe.cxx b/panda/src/x11display/x11GraphicsPipe.cxx index 83ba8de3d4..e6fc85a3e3 100644 --- a/panda/src/x11display/x11GraphicsPipe.cxx +++ b/panda/src/x11display/x11GraphicsPipe.cxx @@ -16,6 +16,7 @@ #include "x11GraphicsWindow.h" #include "config_x11display.h" #include "frameBufferProperties.h" +#include "displayInformation.h" TypeHandle x11GraphicsPipe::_type_handle;