Browse Source

ShaderGenerator: Respect max supported uniform vectors for skinning

Needed to get hw skinning to work in DX9, which is limited to 256 registers (ie. ~85 matrices)
rdb 5 years ago
parent
commit
6cfd4d2050

+ 2 - 4
panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx

@@ -143,8 +143,6 @@ DXGraphicsStateGuardian9(GraphicsEngine *engine, GraphicsPipe *pipe) :
   _vertex_shader_profile = 0;
   _pixel_shader_profile = 0;
 
-  _vertex_shader_maximum_constants = 0;
-
   _supports_stream_offset = false;
 
   get_gamma_table();
@@ -2313,7 +2311,7 @@ reset() {
   _vertex_shader_profile = (char *) D3DXGetVertexShaderProfile (_d3d_device);
   _pixel_shader_profile = (char *) D3DXGetPixelShaderProfile (_d3d_device);
 
-  _vertex_shader_maximum_constants = d3d_caps.MaxVertexShaderConst;
+  _max_vertex_shader_parameter_vectors = d3d_caps.MaxVertexShaderConst;
 
   switch (_pixel_shader_version_major)
   {
@@ -2417,7 +2415,7 @@ reset() {
       << "\nD3DPRASTERCAPS_SLOPESCALEDEPTHBIAS = " << ((d3d_caps.RasterCaps & D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS) != 0)
       << "\nVertexShaderVersion = " << _vertex_shader_version_major << "." << _vertex_shader_version_minor
       << "\nPixelShaderVersion = " << _pixel_shader_version_major << "." << _pixel_shader_version_minor
-      << "\nMaxVertexShaderConst = " << _vertex_shader_maximum_constants
+      << "\nMaxVertexShaderConst = " << _max_vertex_shader_parameter_vectors
       << "\nsupports_stream_offset = " << _supports_stream_offset
       << "\nsupports_dynamic_textures = " << _screen->_supports_dynamic_textures
       << "\nsupports_automatic_mipmap_generation = " << _screen->_supports_automatic_mipmap_generation

+ 0 - 2
panda/src/dxgsg9/dxGraphicsStateGuardian9.h

@@ -352,8 +352,6 @@ protected:
   char *_vertex_shader_profile;
   char *_pixel_shader_profile;
 
-  int _vertex_shader_maximum_constants;
-
   bool _supports_stream_offset;
 
   std::list <wdxGraphicsBuffer9 **> _graphics_buffer_list;

+ 26 - 0
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -3491,6 +3491,32 @@ reset() {
   }
 #endif
 
+  _max_vertex_shader_parameter_vectors = 0;
+#ifndef OPENGLES
+  if (is_at_least_gl_version(2, 0) || has_extension("GL_ARB_vertex_shader")) {
+    GLint max_vertex_uniform_components = 0;
+    glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, &max_vertex_uniform_components);
+    _max_vertex_shader_parameter_vectors = max_vertex_uniform_components / 4;
+
+    if (GLCAT.is_debug()) {
+      GLCAT.debug()
+        << "max vertex uniform components = " << max_vertex_uniform_components << "\n";
+    }
+  }
+#endif
+#ifdef OPENGLES_2
+  {
+    GLint max_vertex_uniform_vectors = 0;
+    glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &max_vertex_uniform_vectors);
+    _max_vertex_shader_parameter_vectors = max_vertex_uniform_vectors;
+
+    if (GLCAT.is_debug()) {
+      GLCAT.debug()
+        << "max vertex uniform vectors = " << max_vertex_uniform_vectors << "\n";
+    }
+  }
+#endif
+
   _current_vbuffer_index = 0;
   _current_ibuffer_index = 0;
   _current_vao_index = 0;

+ 1 - 0
panda/src/gsgbase/graphicsStateGuardianBase.h

@@ -254,6 +254,7 @@ public:
   static void remove_gsg(GraphicsStateGuardianBase *gsg);
 
   size_t _id;
+  size_t _max_vertex_shader_parameter_vectors = 0;
 
 private:
   struct GSGList {

+ 16 - 1
panda/src/pgraphnodes/shaderGenerator.cxx

@@ -80,6 +80,21 @@ ShaderGenerator(const GraphicsStateGuardianBase *gsg) {
   // Do we want to use the ARB_shadow extension?  This also allows us to use
   // hardware shadows PCF.
   _use_shadow_filter = gsg->get_supports_shadow_filter();
+
+  // How many joints can we pass to the shader?  On older hardware (and DX9)
+  // we are limited to 256 vectors, giving us only 85 3x4 matrices.
+  if (gsg->_max_vertex_shader_parameter_vectors >= 500) {
+    _num_indexed_transforms = 120;
+  }
+  else if (gsg->_max_vertex_shader_parameter_vectors >= 250) {
+    _num_indexed_transforms = 80;
+  }
+  else if (gsg->_max_vertex_shader_parameter_vectors >= 128) {
+    _num_indexed_transforms = 36;
+  }
+  else {
+    _num_indexed_transforms = 4;
+  }
 }
 
 /**
@@ -806,7 +821,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
       key._anim_spec.get_num_transforms() > 0) {
     int num_transforms;
     if (key._anim_spec.get_indexed_transforms()) {
-      num_transforms = 120;
+      num_transforms = _num_indexed_transforms;
     } else {
       num_transforms = key._anim_spec.get_num_transforms();
     }

+ 1 - 0
panda/src/pgraphnodes/shaderGenerator.h

@@ -78,6 +78,7 @@ protected:
   const char *alloc_freg();
 
   bool _use_shadow_filter;
+  int _num_indexed_transforms;
 
   // RenderState analysis information.  Created by analyze_renderstate: