Browse Source

shader: More efficient state-based shader input fetching

Previously every input was fetched as a matrix.  Now, every input is fetched as a vector, with matrices taking up multiple vectors.  This saves a lot of copying and a lot of space in the cache.

Furthermore, integer state-based inputs can be defined (for future use)

Naming still needs to be revised, since it's called the "mat part cache" etc.
rdb 2 years ago
parent
commit
ba388e2866

File diff suppressed because it is too large
+ 265 - 212
panda/src/display/graphicsStateGuardian.cxx


+ 4 - 4
panda/src/display/graphicsStateGuardian.h

@@ -336,12 +336,12 @@ public:
 
 
   virtual void clear(DrawableRegion *clearable);
   virtual void clear(DrawableRegion *clearable);
 
 
-  void update_shader_matrix_cache(Shader *shader, LMatrix4 *cache, int altered);
-  const LMatrix4 *fetch_specified_value(Shader::ShaderMatSpec &spec, const LMatrix4 *cache, int altered);
+  void update_shader_matrix_cache(Shader *shader, LVecBase4f *cache, int altered);
+  const LVecBase4f *fetch_specified_value(Shader::ShaderMatSpec &spec, const LVecBase4f *cache, int altered);
   void fetch_specified_part(Shader::ShaderMatInput input, InternalName *name,
   void fetch_specified_part(Shader::ShaderMatInput input, InternalName *name,
-                            LMatrix4 *into, int count = 1);
+                            LVecBase4f *into, int count = 1);
   void fetch_specified_member(const NodePath &np, CPT_InternalName member,
   void fetch_specified_member(const NodePath &np, CPT_InternalName member,
-                              LMatrix4 &t);
+                              LVecBase4f &v);
   PT(Texture) fetch_specified_texture(Shader::ShaderTexSpec &spec,
   PT(Texture) fetch_specified_texture(Shader::ShaderTexSpec &spec,
                                       SamplerState &sampler, int &view);
                                       SamplerState &sampler, int &view);
   const Shader::ShaderPtrData *fetch_ptr_parameter(const Shader::ShaderPtrSpec& spec);
   const Shader::ShaderPtrData *fetch_ptr_parameter(const Shader::ShaderPtrSpec& spec);

+ 15 - 87
panda/src/dxgsg9/dxShaderContext9.cxx

@@ -75,7 +75,7 @@ DXShaderContext9(Shader *s, GSG *gsg) : ShaderContext(s) {
   }
   }
 #endif
 #endif
 
 
-  _mat_part_cache = new LMatrix4[s->cp_get_mat_cache_size()];
+  _mat_part_cache = new LVecBase4f[s->cp_get_mat_cache_size()];
 }
 }
 
 
 /**
 /**
@@ -184,14 +184,6 @@ unbind(GSG *gsg) {
  * the parameters were issued, no part of the render state has changed except
  * the parameters were issued, no part of the render state has changed except
  * the external and internal transforms.
  * the external and internal transforms.
  */
  */
-
-#if DEBUG_SHADER
-PN_stdfloat *global_data = 0;
-ShaderContext::ShaderMatSpec *global_shader_mat_spec = 0;
-InternalName *global_internal_name_0 = 0;
-InternalName *global_internal_name_1 = 0;
-#endif
-
 void DXShaderContext9::
 void DXShaderContext9::
 issue_parameters(GSG *gsg, int altered) {
 issue_parameters(GSG *gsg, int altered) {
 #ifdef HAVE_CG
 #ifdef HAVE_CG
@@ -249,106 +241,42 @@ issue_parameters(GSG *gsg, int altered) {
           continue;
           continue;
         }
         }
 
 
-        const LMatrix4 *val = gsg->fetch_specified_value(spec, _mat_part_cache, altered);
+        const LVecBase4f *val = gsg->fetch_specified_value(spec, _mat_part_cache, altered);
         if (val) {
         if (val) {
-          HRESULT hr;
-          PN_stdfloat v [4];
-          LMatrix4f temp_matrix = LCAST(float, *val);
+          const float *data = (const float *)val + spec._offset;
+          LVecBase4f v;
+          LMatrix4f temp_matrix;
           LMatrix3f temp_matrix3;
           LMatrix3f temp_matrix3;
 
 
-          hr = D3D_OK;
-
-          const float *data;
-          data = temp_matrix.get_data();
-
-#if DEBUG_SHADER
-          // DEBUG
-          global_data = (PN_stdfloat *)data;
-          global_shader_mat_spec = &spec;
-          global_internal_name_0 = global_shader_mat_spec->_arg[0];
-          global_internal_name_1 = global_shader_mat_spec->_arg[1];
-#endif
-
           switch (spec._piece) {
           switch (spec._piece) {
-          case Shader::SMP_whole:
+          case Shader::SMP_mat4_whole:
             // TRANSPOSE REQUIRED
             // TRANSPOSE REQUIRED
-            temp_matrix.transpose_in_place();
+            temp_matrix.transpose_from(*(const LMatrix4f *)data);
             data = temp_matrix.get_data();
             data = temp_matrix.get_data();
-
-            hr = cgD3D9SetUniform(p, data);
             break;
             break;
 
 
-          case Shader::SMP_transpose:
-            // NO TRANSPOSE REQUIRED
-            hr = cgD3D9SetUniform(p, data);
+          case Shader::SMP_mat4_column:
+            v.set(data[0], data[4], data[8], data[12]);
+            data = v.get_data();
             break;
             break;
 
 
-          case Shader::SMP_row0:
-            hr = cgD3D9SetUniform(p, data + 0);
-            break;
-          case Shader::SMP_row1:
-            hr = cgD3D9SetUniform(p, data + 4);
-            break;
-          case Shader::SMP_row2:
-            hr = cgD3D9SetUniform(p, data + 8);
-            break;
-          case Shader::SMP_row3x1:
-          case Shader::SMP_row3x2:
-          case Shader::SMP_row3x3:
-          case Shader::SMP_row3:
-            hr = cgD3D9SetUniform(p, data + 12);
-            break;
-
-          case Shader::SMP_col0:
-            v[0] = data[0]; v[1] = data[4]; v[2] = data[8]; v[3] = data[12];
-            hr = cgD3D9SetUniform(p, v);
-            break;
-          case Shader::SMP_col1:
-            v[0] = data[1]; v[1] = data[5]; v[2] = data[9]; v[3] = data[13];
-            hr = cgD3D9SetUniform(p, v);
-            break;
-          case Shader::SMP_col2:
-            v[0] = data[2]; v[1] = data[6]; v[2] = data[10]; v[3] = data[14];
-            hr = cgD3D9SetUniform(p, v);
-            break;
-          case Shader::SMP_col3:
-            v[0] = data[3]; v[1] = data[7]; v[2] = data[11]; v[3] = data[15];
-            hr = cgD3D9SetUniform(p, v);
-            break;
-
-          case Shader::SMP_upper3x3:
+          case Shader::SMP_mat4_upper3x3:
             // TRANSPOSE REQUIRED
             // TRANSPOSE REQUIRED
-            temp_matrix3 = temp_matrix.get_upper_3();
-            temp_matrix3.transpose_in_place();
+            temp_matrix3.set(data[0], data[4], data[8], data[1], data[5], data[9], data[2], data[6], data[10]);
             data = temp_matrix3.get_data();
             data = temp_matrix3.get_data();
-
-            hr = cgD3D9SetUniform(p, data);
             break;
             break;
 
 
-          case Shader::SMP_transpose3x3:
+          case Shader::SMP_mat4_transpose3x3:
             // NO TRANSPOSE REQUIRED
             // NO TRANSPOSE REQUIRED
-            temp_matrix3 = temp_matrix.get_upper_3();
+            temp_matrix3.set(data[0], data[1], data[2], data[4], data[5], data[6], data[8], data[9], data[10]);
             data = temp_matrix3.get_data();
             data = temp_matrix3.get_data();
-
-            hr = cgD3D9SetUniform(p, data);
             break;
             break;
 
 
-          case Shader::SMP_cell15:
-            hr = cgD3D9SetUniform(p, data + 15);
-            continue;
-          case Shader::SMP_cell14:
-            hr = cgD3D9SetUniform(p, data + 14);
-            continue;
-          case Shader::SMP_cell13:
-            hr = cgD3D9SetUniform(p, data + 13);
-            continue;
-
           default:
           default:
-            dxgsg9_cat.error()
-              << "issue_parameters () SMP parameter type not implemented " << spec._piece << "\n";
             break;
             break;
           }
           }
 
 
+          HRESULT hr = cgD3D9SetUniform(p, data);
           if (FAILED(hr)) {
           if (FAILED(hr)) {
             std::string name = "unnamed";
             std::string name = "unnamed";
 
 

+ 1 - 1
panda/src/dxgsg9/dxShaderContext9.h

@@ -87,7 +87,7 @@ private:
   pvector <CGparameter> _cg_parameter_map;
   pvector <CGparameter> _cg_parameter_map;
 #endif
 #endif
 
 
-  LMatrix4 *_mat_part_cache = nullptr;
+  LVecBase4f *_mat_part_cache = nullptr;
 
 
 private:
 private:
   void release_resources(void);
   void release_resources(void);

+ 21 - 31
panda/src/glstuff/glCgShaderContext_src.cxx

@@ -329,7 +329,7 @@ CLP(CgShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderConte
     }
     }
   }
   }
 
 
-  _mat_part_cache = new LMatrix4[_shader->cp_get_mat_cache_size()];
+  _mat_part_cache = new LVecBase4f[_shader->cp_get_mat_cache_size()];
 
 
   _glgsg->report_my_gl_errors();
   _glgsg->report_my_gl_errors();
 }
 }
@@ -699,46 +699,36 @@ issue_parameters(int altered) {
         continue;
         continue;
       }
       }
 
 
-      const LMatrix4 *val = _glgsg->fetch_specified_value(spec, _mat_part_cache, altered);
+      const LVecBase4f *val = _glgsg->fetch_specified_value(spec, _mat_part_cache, altered);
       if (!val) continue;
       if (!val) continue;
-      const PN_stdfloat *data = val->get_data();
+      const float *data = val->get_data();
+      data += spec._offset;
 
 
       CGparameter p = _cg_parameter_map[spec._id._seqno];
       CGparameter p = _cg_parameter_map[spec._id._seqno];
       switch (spec._piece) {
       switch (spec._piece) {
-      case Shader::SMP_whole: GLfc(cgGLSetMatrixParameter)(p, data); continue;
-      case Shader::SMP_transpose: GLfr(cgGLSetMatrixParameter)(p, data); continue;
-      case Shader::SMP_col0: GLf(cgGLSetParameter4)(p, data[0], data[4], data[ 8], data[12]); continue;
-      case Shader::SMP_col1: GLf(cgGLSetParameter4)(p, data[1], data[5], data[ 9], data[13]); continue;
-      case Shader::SMP_col2: GLf(cgGLSetParameter4)(p, data[2], data[6], data[10], data[14]); continue;
-      case Shader::SMP_col3: GLf(cgGLSetParameter4)(p, data[3], data[7], data[11], data[15]); continue;
-      case Shader::SMP_row0: GLfv(cgGLSetParameter4)(p, data+ 0); continue;
-      case Shader::SMP_row1: GLfv(cgGLSetParameter4)(p, data+ 4); continue;
-      case Shader::SMP_row2: GLfv(cgGLSetParameter4)(p, data+ 8); continue;
-      case Shader::SMP_row3: GLfv(cgGLSetParameter4)(p, data+12); continue;
-      case Shader::SMP_row3x1: GLfv(cgGLSetParameter1)(p, data+12); continue;
-      case Shader::SMP_row3x2: GLfv(cgGLSetParameter2)(p, data+12); continue;
-      case Shader::SMP_row3x3: GLfv(cgGLSetParameter3)(p, data+12); continue;
-      case Shader::SMP_upper3x3:
+      case Shader::SMP_float: cgGLSetParameter1f(p, data[0]); continue;
+      case Shader::SMP_vec2: cgGLSetParameter2fv(p, data); continue;
+      case Shader::SMP_vec3: cgGLSetParameter3fv(p, data); continue;
+      case Shader::SMP_vec4: cgGLSetParameter4fv(p, data); continue;
+      case Shader::SMP_mat4_whole: cgGLSetMatrixParameterfc(p, data); continue;
+      case Shader::SMP_mat4_transpose: cgGLSetMatrixParameterfr(p, data); continue;
+      case Shader::SMP_mat4_column: cgGLSetParameter4f(p, data[0], data[4], data[ 8], data[12]); continue;
+      case Shader::SMP_mat4_upper3x3:
         {
         {
-          LMatrix3 upper3 = val->get_upper_3();
-          GLfc(cgGLSetMatrixParameter)(p, upper3.get_data());
+          LMatrix3f upper3(data[0], data[1], data[2], data[4], data[5], data[6], data[8], data[9], data[10]);
+          cgGLSetMatrixParameterfc(p, upper3.get_data());
           continue;
           continue;
         }
         }
-      case Shader::SMP_transpose3x3:
+      case Shader::SMP_mat4_transpose3x3:
         {
         {
-          LMatrix3 upper3 = val->get_upper_3();
-          GLfr(cgGLSetMatrixParameter)(p, upper3.get_data());
+          LMatrix3f upper3(data[0], data[1], data[2], data[4], data[5], data[6], data[8], data[9], data[10]);
+          cgGLSetMatrixParameterfr(p, upper3.get_data());
           continue;
           continue;
         }
         }
-      case Shader::SMP_cell15:
-        GLf(cgGLSetParameter1)(p, data[15]);
-        continue;
-      case Shader::SMP_cell14:
-        GLf(cgGLSetParameter1)(p, data[14]);
-        continue;
-      case Shader::SMP_cell13:
-        GLf(cgGLSetParameter1)(p, data[13]);
-        continue;
+      case Shader::SMP_int: cgSetParameter1i(p, ((const int *)data)[0]); continue;
+      case Shader::SMP_ivec2: cgSetParameter2iv(p, (const int *)data); continue;
+      case Shader::SMP_ivec3: cgSetParameter3iv(p, (const int *)data); continue;
+      case Shader::SMP_ivec4: cgSetParameter4iv(p, (const int *)data); continue;
       }
       }
     }
     }
   }
   }

+ 1 - 1
panda/src/glstuff/glCgShaderContext_src.h

@@ -75,7 +75,7 @@ private:
   long _transform_table_size;
   long _transform_table_size;
   long _slider_table_size;
   long _slider_table_size;
 
 
-  LMatrix4 *_mat_part_cache = nullptr;
+  LVecBase4f *_mat_part_cache = nullptr;
   pvector<CGparameter> _cg_parameter_map;
   pvector<CGparameter> _cg_parameter_map;
 
 
   WCPT(RenderState) _state_rs;
   WCPT(RenderState) _state_rs;

+ 123 - 112
panda/src/glstuff/glShaderContext_src.cxx

@@ -152,30 +152,54 @@ parse_and_set_short_hand_shader_vars(Shader::ShaderArgId &arg_id, GLenum param_t
 
 
     // Decide whether this is a matrix or vector.
     // Decide whether this is a matrix or vector.
     if (param_type == GL_FLOAT_MAT4) {
     if (param_type == GL_FLOAT_MAT4) {
-      if      (pieces[0] == "trans") bind._piece = Shader::SMP_whole;
-      else if (pieces[0] == "tpose") bind._piece = Shader::SMP_transpose;
+      if      (pieces[0] == "trans") bind._piece = Shader::SMP_mat4_whole;
+      else if (pieces[0] == "tpose") bind._piece = Shader::SMP_mat4_transpose;
       else {
       else {
         GLCAT.error() << basename << " should be vec4, not mat3\n";
         GLCAT.error() << basename << " should be vec4, not mat3\n";
         return false;
         return false;
       }
       }
     } else if (param_type == GL_FLOAT_MAT3) {
     } else if (param_type == GL_FLOAT_MAT3) {
-      if      (pieces[0] == "trans") bind._piece = Shader::SMP_upper3x3;
-      else if (pieces[0] == "tpose") bind._piece = Shader::SMP_transpose3x3;
+      if      (pieces[0] == "trans") bind._piece = Shader::SMP_mat4_upper3x3;
+      else if (pieces[0] == "tpose") bind._piece = Shader::SMP_mat4_transpose3x3;
       else {
       else {
         GLCAT.error() << basename << " should be vec4, not mat3\n";
         GLCAT.error() << basename << " should be vec4, not mat3\n";
         return false;
         return false;
       }
       }
     } else if (param_type == GL_FLOAT_VEC4) {
     } else if (param_type == GL_FLOAT_VEC4) {
-      if      (pieces[0] == "trans") bind._piece = Shader::SMP_col0;
-      else if (pieces[0] == "tpose") bind._piece = Shader::SMP_row0;
-      else if (pieces[0] == "row0")  bind._piece = Shader::SMP_row0;
-      else if (pieces[0] == "row1")  bind._piece = Shader::SMP_row1;
-      else if (pieces[0] == "row2")  bind._piece = Shader::SMP_row2;
-      else if (pieces[0] == "row3")  bind._piece = Shader::SMP_row3;
-      else if (pieces[0] == "col0")  bind._piece = Shader::SMP_col0;
-      else if (pieces[0] == "col1")  bind._piece = Shader::SMP_col1;
-      else if (pieces[0] == "col2")  bind._piece = Shader::SMP_col2;
-      else if (pieces[0] == "col3")  bind._piece = Shader::SMP_col3;
+      if      (pieces[0] == "trans") bind._piece = Shader::SMP_mat4_column;
+      else if (pieces[0] == "tpose") bind._piece = Shader::SMP_vec4;
+      else if (pieces[0] == "row0") {
+        bind._piece = Shader::SMP_vec4;
+        bind._offset = 0;
+      }
+      else if (pieces[0] == "row1") {
+        bind._piece = Shader::SMP_vec4;
+        bind._offset = 4;
+      }
+      else if (pieces[0] == "row2") {
+        bind._piece = Shader::SMP_vec4;
+        bind._offset = 8;
+      }
+      else if (pieces[0] == "row3") {
+        bind._piece = Shader::SMP_vec4;
+        bind._offset = 12;
+      }
+      else if (pieces[0] == "col0") {
+        bind._piece = Shader::SMP_mat4_column;
+        bind._offset = 0;
+      }
+      else if (pieces[0] == "col1") {
+        bind._piece = Shader::SMP_mat4_column;
+        bind._offset = 1;
+      }
+      else if (pieces[0] == "col2") {
+        bind._piece = Shader::SMP_mat4_column;
+        bind._offset = 2;
+      }
+      else if (pieces[0] == "col3") {
+        bind._piece = Shader::SMP_mat4_column;
+        bind._offset = 3;
+      }
       else {
       else {
         GLCAT.error() << basename << " should be mat4, not vec4\n";
         GLCAT.error() << basename << " should be mat4, not vec4\n";
         return false;
         return false;
@@ -184,13 +208,13 @@ parse_and_set_short_hand_shader_vars(Shader::ShaderArgId &arg_id, GLenum param_t
       // We'll permit this too, simply because we can support it.
       // We'll permit this too, simply because we can support it.
       switch (param_type) {
       switch (param_type) {
       case GL_FLOAT:
       case GL_FLOAT:
-        bind._piece = Shader::SMP_row3x1;
+        bind._piece = Shader::SMP_float;
         break;
         break;
       case GL_FLOAT_VEC2:
       case GL_FLOAT_VEC2:
-        bind._piece = Shader::SMP_row3x2;
+        bind._piece = Shader::SMP_vec2;
         break;
         break;
       case GL_FLOAT_VEC3:
       case GL_FLOAT_VEC3:
-        bind._piece = Shader::SMP_row3x3;
+        bind._piece = Shader::SMP_vec3;
         break;
         break;
       default:
       default:
         GLCAT.error() << basename << " should be vec4\n";
         GLCAT.error() << basename << " should be vec4\n";
@@ -234,7 +258,7 @@ parse_and_set_short_hand_shader_vars(Shader::ShaderArgId &arg_id, GLenum param_t
     if (param_size > 1) {
     if (param_size > 1) {
       // We support arrays of rows and arrays of columns, so we can run the
       // We support arrays of rows and arrays of columns, so we can run the
       // GLSL shaders that cgc spits out.
       // GLSL shaders that cgc spits out.
-      if (bind._piece == Shader::SMP_row0 || bind._piece == Shader::SMP_col0) {
+      if (bind._piece == Shader::SMP_vec4 || bind._piece == Shader::SMP_mat4_column) {
         if (param_size > 4) {
         if (param_size > 4) {
           GLCAT.warning() << basename << "[" << param_size << "] is too large, only the first four elements will be defined\n";
           GLCAT.warning() << basename << "[" << param_size << "] is too large, only the first four elements will be defined\n";
           param_size = 4;
           param_size = 4;
@@ -396,7 +420,7 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
     _glgsg->_current_shader_context->bind();
     _glgsg->_current_shader_context->bind();
   }
   }
 
 
-  _mat_part_cache = new LMatrix4[_shader->cp_get_mat_cache_size()];
+  _mat_part_cache = new LVecBase4f[_shader->cp_get_mat_cache_size()];
 }
 }
 
 
 /**
 /**
@@ -827,15 +851,15 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
       bind._func = Shader::SMF_compose;
       bind._func = Shader::SMF_compose;
       if (param_type == GL_FLOAT_MAT3) {
       if (param_type == GL_FLOAT_MAT3) {
         if (transpose) {
         if (transpose) {
-          bind._piece = Shader::SMP_upper3x3;
+          bind._piece = Shader::SMP_mat4_upper3x3;
         } else {
         } else {
-          bind._piece = Shader::SMP_transpose3x3;
+          bind._piece = Shader::SMP_mat4_transpose3x3;
         }
         }
       } else if (param_type == GL_FLOAT_MAT4) {
       } else if (param_type == GL_FLOAT_MAT4) {
         if (transpose) {
         if (transpose) {
-          bind._piece = Shader::SMP_transpose;
+          bind._piece = Shader::SMP_mat4_transpose;
         } else {
         } else {
-          bind._piece = Shader::SMP_whole;
+          bind._piece = Shader::SMP_mat4_whole;
         }
         }
       } else {
       } else {
         GLCAT.error()
         GLCAT.error()
@@ -941,13 +965,15 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
         // A matrix member of a p3d_LightSource struct.
         // A matrix member of a p3d_LightSource struct.
         if (strncmp(name_buffer, "shadowViewMatrix", 127) == 0) {
         if (strncmp(name_buffer, "shadowViewMatrix", 127) == 0) {
           if (inverse) {
           if (inverse) {
-            // Tack inverse back onto the end.
-            strcpy(name_buffer + strlen(name_buffer), "Inverse");
+            GLCAT.error()
+              << "p3d_LightSource struct does not provide a matrix named "
+              << name_buffer << "Inverse!\n";
+            return;
           }
           }
 
 
           bind._func = Shader::SMF_first;
           bind._func = Shader::SMF_first;
-          bind._part[0] = Shader::SMO_light_source_i_attrib;
-          bind._arg[0] = InternalName::make(name_buffer);
+          bind._part[0] = Shader::SMO_apiview_to_apiclip_light_source_i;
+          bind._arg[0] = nullptr;
           bind._part[1] = Shader::SMO_identity;
           bind._part[1] = Shader::SMO_identity;
           bind._arg[1] = nullptr;
           bind._arg[1] = nullptr;
 
 
@@ -957,8 +983,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
           bind._func = Shader::SMF_compose;
           bind._func = Shader::SMF_compose;
           bind._part[0] = Shader::SMO_model_to_apiview;
           bind._part[0] = Shader::SMO_model_to_apiview;
           bind._arg[0] = nullptr;
           bind._arg[0] = nullptr;
-          bind._part[1] = Shader::SMO_light_source_i_attrib;
-          bind._arg[1] = InternalName::make("shadowViewMatrix");
+          bind._part[1] = Shader::SMO_apiview_to_apiclip_light_source_i;
+          bind._arg[1] = nullptr;
 
 
           static bool warned = false;
           static bool warned = false;
           if (!warned) {
           if (!warned) {
@@ -1061,7 +1087,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
             << "p3d_Material.baseColor should be vec4\n";
             << "p3d_Material.baseColor should be vec4\n";
         }
         }
         bind._part[0] = Shader::SMO_attr_material2;
         bind._part[0] = Shader::SMO_attr_material2;
-        bind._piece = Shader::SMP_row0;
+        bind._piece = Shader::SMP_vec4;
         _shader->cp_add_mat_spec(bind);
         _shader->cp_add_mat_spec(bind);
         return;
         return;
 
 
@@ -1070,7 +1096,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
           GLCAT.error()
           GLCAT.error()
             << "p3d_Material.ambient should be vec4\n";
             << "p3d_Material.ambient should be vec4\n";
         }
         }
-        bind._piece = Shader::SMP_row0;
+        bind._piece = Shader::SMP_vec4;
         _shader->cp_add_mat_spec(bind);
         _shader->cp_add_mat_spec(bind);
         return;
         return;
 
 
@@ -1079,7 +1105,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
           GLCAT.error()
           GLCAT.error()
             << "p3d_Material.diffuse should be vec4\n";
             << "p3d_Material.diffuse should be vec4\n";
         }
         }
-        bind._piece = Shader::SMP_row1;
+        bind._piece = Shader::SMP_vec4;
+        bind._offset = 4;
         _shader->cp_add_mat_spec(bind);
         _shader->cp_add_mat_spec(bind);
         return;
         return;
 
 
@@ -1088,7 +1115,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
           GLCAT.error()
           GLCAT.error()
             << "p3d_Material.emission should be vec4\n";
             << "p3d_Material.emission should be vec4\n";
         }
         }
-        bind._piece = Shader::SMP_row2;
+        bind._piece = Shader::SMP_vec4;
+        bind._offset = 8;
         _shader->cp_add_mat_spec(bind);
         _shader->cp_add_mat_spec(bind);
         return;
         return;
 
 
@@ -1097,7 +1125,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
           GLCAT.error()
           GLCAT.error()
             << "p3d_Material.specular should be vec3\n";
             << "p3d_Material.specular should be vec3\n";
         }
         }
-        bind._piece = Shader::SMP_row3x3;
+        bind._piece = Shader::SMP_vec3;
+        bind._offset = 12;
         _shader->cp_add_mat_spec(bind);
         _shader->cp_add_mat_spec(bind);
         return;
         return;
 
 
@@ -1106,7 +1135,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
           GLCAT.error()
           GLCAT.error()
             << "p3d_Material.shininess should be float\n";
             << "p3d_Material.shininess should be float\n";
         }
         }
-        bind._piece = Shader::SMP_cell15;
+        bind._piece = Shader::SMP_float;
+        bind._offset = 15;
         _shader->cp_add_mat_spec(bind);
         _shader->cp_add_mat_spec(bind);
         return;
         return;
 
 
@@ -1116,7 +1146,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
             << "p3d_Material.roughness should be float\n";
             << "p3d_Material.roughness should be float\n";
         }
         }
         bind._part[0] = Shader::SMO_attr_material2;
         bind._part[0] = Shader::SMO_attr_material2;
-        bind._piece = Shader::SMP_cell15;
+        bind._piece = Shader::SMP_float;
+        bind._offset = 7;
         _shader->cp_add_mat_spec(bind);
         _shader->cp_add_mat_spec(bind);
         return;
         return;
 
 
@@ -1126,7 +1157,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
             << "p3d_Material.metallic should be bool or float\n";
             << "p3d_Material.metallic should be bool or float\n";
         }
         }
         bind._part[0] = Shader::SMO_attr_material2;
         bind._part[0] = Shader::SMO_attr_material2;
-        bind._piece = Shader::SMP_row3x1;
+        bind._piece = Shader::SMP_float;
+        bind._offset = 4;
         _shader->cp_add_mat_spec(bind);
         _shader->cp_add_mat_spec(bind);
         return;
         return;
 
 
@@ -1136,7 +1168,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
             << "p3d_Material.refractiveIndex should be float\n";
             << "p3d_Material.refractiveIndex should be float\n";
         }
         }
         bind._part[0] = Shader::SMO_attr_material2;
         bind._part[0] = Shader::SMO_attr_material2;
-        bind._piece = Shader::SMP_cell13;
+        bind._piece = Shader::SMP_float;
+        bind._offset = 5;
         _shader->cp_add_mat_spec(bind);
         _shader->cp_add_mat_spec(bind);
         return;
         return;
       }
       }
@@ -1151,9 +1184,9 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
       bind._arg[1] = nullptr;
       bind._arg[1] = nullptr;
 
 
       if (param_type == GL_FLOAT_VEC3) {
       if (param_type == GL_FLOAT_VEC3) {
-        bind._piece = Shader::SMP_row3x3;
+        bind._piece = Shader::SMP_vec3;
       } else if (param_type == GL_FLOAT_VEC4) {
       } else if (param_type == GL_FLOAT_VEC4) {
-        bind._piece = Shader::SMP_row3;
+        bind._piece = Shader::SMP_vec4;
       } else {
       } else {
         GLCAT.error()
         GLCAT.error()
           << "p3d_ColorScale should be vec3 or vec4\n";
           << "p3d_ColorScale should be vec3 or vec4\n";
@@ -1172,9 +1205,9 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
       bind._arg[1] = nullptr;
       bind._arg[1] = nullptr;
 
 
       if (param_type == GL_FLOAT_VEC3) {
       if (param_type == GL_FLOAT_VEC3) {
-        bind._piece = Shader::SMP_row3x3;
+        bind._piece = Shader::SMP_vec3;
       } else if (param_type == GL_FLOAT_VEC4) {
       } else if (param_type == GL_FLOAT_VEC4) {
-        bind._piece = Shader::SMP_row3;
+        bind._piece = Shader::SMP_vec3;
       } else {
       } else {
         GLCAT.error()
         GLCAT.error()
           << "p3d_Color should be vec3 or vec4\n";
           << "p3d_Color should be vec3 or vec4\n";
@@ -1193,7 +1226,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
         Shader::ShaderMatSpec bind;
         Shader::ShaderMatSpec bind;
         bind._id = arg_id;
         bind._id = arg_id;
         bind._id._seqno = p + i;
         bind._id._seqno = p + i;
-        bind._piece = Shader::SMP_row3;
+        bind._piece = Shader::SMP_vec4;
         bind._func = Shader::SMF_first;
         bind._func = Shader::SMF_first;
         bind._index = i;
         bind._index = i;
         bind._part[0] = Shader::SMO_apiview_clipplane_i;
         bind._part[0] = Shader::SMO_apiview_clipplane_i;
@@ -1216,9 +1249,9 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
         bind._part[0] = Shader::SMO_attr_fogcolor;
         bind._part[0] = Shader::SMO_attr_fogcolor;
 
 
         if (param_type == GL_FLOAT_VEC3) {
         if (param_type == GL_FLOAT_VEC3) {
-          bind._piece = Shader::SMP_row3x3;
+          bind._piece = Shader::SMP_vec4;
         } else if (param_type == GL_FLOAT_VEC4) {
         } else if (param_type == GL_FLOAT_VEC4) {
-          bind._piece = Shader::SMP_row3;
+          bind._piece = Shader::SMP_vec4;
         } else {
         } else {
           GLCAT.error()
           GLCAT.error()
             << "p3d_Fog.color should be vec3 or vec4\n";
             << "p3d_Fog.color should be vec3 or vec4\n";
@@ -1229,7 +1262,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
         bind._part[0] = Shader::SMO_attr_fog;
         bind._part[0] = Shader::SMO_attr_fog;
 
 
         if (param_type == GL_FLOAT) {
         if (param_type == GL_FLOAT) {
-          bind._piece = Shader::SMP_row3x1;
+          bind._piece = Shader::SMP_float;
         } else {
         } else {
           GLCAT.error()
           GLCAT.error()
             << "p3d_Fog.density should be float\n";
             << "p3d_Fog.density should be float\n";
@@ -1240,7 +1273,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
         bind._part[0] = Shader::SMO_attr_fog;
         bind._part[0] = Shader::SMO_attr_fog;
 
 
         if (param_type == GL_FLOAT) {
         if (param_type == GL_FLOAT) {
-          bind._piece = Shader::SMP_cell13;
+          bind._piece = Shader::SMP_float;
+          bind._offset = 13;
         } else {
         } else {
           GLCAT.error()
           GLCAT.error()
             << "p3d_Fog.start should be float\n";
             << "p3d_Fog.start should be float\n";
@@ -1251,7 +1285,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
         bind._part[0] = Shader::SMO_attr_fog;
         bind._part[0] = Shader::SMO_attr_fog;
 
 
         if (param_type == GL_FLOAT) {
         if (param_type == GL_FLOAT) {
-          bind._piece = Shader::SMP_cell14;
+          bind._piece = Shader::SMP_float;
+          bind._offset = 14;
         } else {
         } else {
           GLCAT.error()
           GLCAT.error()
             << "p3d_Fog.end should be float\n";
             << "p3d_Fog.end should be float\n";
@@ -1262,7 +1297,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
         bind._part[0] = Shader::SMO_attr_fog;
         bind._part[0] = Shader::SMO_attr_fog;
 
 
         if (param_type == GL_FLOAT) {
         if (param_type == GL_FLOAT) {
-          bind._piece = Shader::SMP_cell15;
+          bind._piece = Shader::SMP_float;
+          bind._offset = 15;
         } else {
         } else {
           GLCAT.error()
           GLCAT.error()
             << "p3d_Fog.scale should be float\n";
             << "p3d_Fog.scale should be float\n";
@@ -1283,9 +1319,9 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
       bind._arg[1] = nullptr;
       bind._arg[1] = nullptr;
 
 
       if (param_type == GL_FLOAT_VEC3) {
       if (param_type == GL_FLOAT_VEC3) {
-        bind._piece = Shader::SMP_row3x3;
+        bind._piece = Shader::SMP_vec3;
       } else if (param_type == GL_FLOAT_VEC4) {
       } else if (param_type == GL_FLOAT_VEC4) {
-        bind._piece = Shader::SMP_row3;
+        bind._piece = Shader::SMP_vec4;
       } else {
       } else {
         GLCAT.error()
         GLCAT.error()
           << "p3d_LightModel.ambient should be vec3 or vec4\n";
           << "p3d_LightModel.ambient should be vec3 or vec4\n";
@@ -1329,26 +1365,26 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
           bind._id = arg_id;
           bind._id = arg_id;
           bind._func = Shader::SMF_first;
           bind._func = Shader::SMF_first;
           bind._index = index;
           bind._index = index;
-          bind._part[0] = Shader::SMO_light_source_i_attrib;
+          bind._part[0] = Shader::SMO_light_source_i_vec_attrib;
           bind._arg[0] = InternalName::make(member_name);
           bind._arg[0] = InternalName::make(member_name);
           bind._part[1] = Shader::SMO_identity;
           bind._part[1] = Shader::SMO_identity;
           bind._arg[1] = nullptr;
           bind._arg[1] = nullptr;
 
 
           switch (param_type) {
           switch (param_type) {
           case GL_FLOAT:
           case GL_FLOAT:
-            bind._piece = Shader::SMP_row3x1;
+            bind._piece = Shader::SMP_float;
             break;
             break;
 
 
           case GL_FLOAT_VEC2:
           case GL_FLOAT_VEC2:
-            bind._piece = Shader::SMP_row3x2;
+            bind._piece = Shader::SMP_vec2;
             break;
             break;
 
 
           case GL_FLOAT_VEC3:
           case GL_FLOAT_VEC3:
-            bind._piece = Shader::SMP_row3x3;
+            bind._piece = Shader::SMP_vec3;
             break;
             break;
 
 
           case GL_FLOAT_VEC4:
           case GL_FLOAT_VEC4:
-            bind._piece = Shader::SMP_row3;
+            bind._piece = Shader::SMP_vec4;
             break;
             break;
 
 
           default:
           default:
@@ -1390,7 +1426,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
       bind._arg[0] = nullptr;
       bind._arg[0] = nullptr;
       bind._part[1] = Shader::SMO_identity;
       bind._part[1] = Shader::SMO_identity;
       bind._arg[1] = nullptr;
       bind._arg[1] = nullptr;
-      bind._piece = Shader::SMP_row3;
+      bind._piece = Shader::SMP_vec4;
       _shader->cp_add_mat_spec(bind);
       _shader->cp_add_mat_spec(bind);
       return;
       return;
     }
     }
@@ -1408,7 +1444,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
     bind._arg[1] = nullptr;
     bind._arg[1] = nullptr;
 
 
     if (noprefix == "ViewMatrix") {
     if (noprefix == "ViewMatrix") {
-      bind._piece = Shader::SMP_whole;
+      bind._piece = Shader::SMP_mat4_whole;
       bind._func = Shader::SMF_compose;
       bind._func = Shader::SMF_compose;
       bind._part[0] = Shader::SMO_world_to_view;
       bind._part[0] = Shader::SMO_world_to_view;
       bind._part[1] = Shader::SMO_view_to_apiview;
       bind._part[1] = Shader::SMO_view_to_apiview;
@@ -1416,7 +1452,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
       return;
       return;
 
 
     } else if (noprefix == "InverseViewMatrix" || noprefix == "ViewMatrixInverse") {
     } else if (noprefix == "InverseViewMatrix" || noprefix == "ViewMatrixInverse") {
-      bind._piece = Shader::SMP_whole;
+      bind._piece = Shader::SMP_mat4_whole;
       bind._func = Shader::SMF_compose;
       bind._func = Shader::SMF_compose;
       bind._part[0] = Shader::SMO_apiview_to_view;
       bind._part[0] = Shader::SMO_apiview_to_view;
       bind._part[1] = Shader::SMO_view_to_world;
       bind._part[1] = Shader::SMO_view_to_world;
@@ -1424,7 +1460,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
       return;
       return;
 
 
     } else if (noprefix == "FrameTime") {
     } else if (noprefix == "FrameTime") {
-      bind._piece = Shader::SMP_row3x1;
+      bind._piece = Shader::SMP_float;
       bind._func = Shader::SMF_first;
       bind._func = Shader::SMF_first;
       bind._part[0] = Shader::SMO_frame_time;
       bind._part[0] = Shader::SMO_frame_time;
       bind._part[1] = Shader::SMO_identity;
       bind._part[1] = Shader::SMO_identity;
@@ -1432,7 +1468,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
       return;
       return;
 
 
     } else if (noprefix == "DeltaFrameTime") {
     } else if (noprefix == "DeltaFrameTime") {
-      bind._piece = Shader::SMP_row3x1;
+      bind._piece = Shader::SMP_float;
       bind._func = Shader::SMF_first;
       bind._func = Shader::SMF_first;
       bind._part[0] = Shader::SMO_frame_delta;
       bind._part[0] = Shader::SMO_frame_delta;
       bind._part[1] = Shader::SMO_identity;
       bind._part[1] = Shader::SMO_identity;
@@ -1516,7 +1552,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
       case GL_FLOAT_MAT3: {
       case GL_FLOAT_MAT3: {
         Shader::ShaderMatSpec bind;
         Shader::ShaderMatSpec bind;
         bind._id = arg_id;
         bind._id = arg_id;
-        bind._piece = Shader::SMP_upper3x3;
+        bind._piece = Shader::SMP_mat4_upper3x3;
         bind._func = Shader::SMF_first;
         bind._func = Shader::SMF_first;
         bind._part[0] = Shader::SMO_mat_constant_x;
         bind._part[0] = Shader::SMO_mat_constant_x;
         bind._arg[0] = InternalName::make(param_name);
         bind._arg[0] = InternalName::make(param_name);
@@ -1528,7 +1564,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
       case GL_FLOAT_MAT4: {
       case GL_FLOAT_MAT4: {
         Shader::ShaderMatSpec bind;
         Shader::ShaderMatSpec bind;
         bind._id = arg_id;
         bind._id = arg_id;
-        bind._piece = Shader::SMP_whole;
+        bind._piece = Shader::SMP_mat4_whole;
         bind._func = Shader::SMF_first;
         bind._func = Shader::SMF_first;
         bind._part[1] = Shader::SMO_identity;
         bind._part[1] = Shader::SMO_identity;
         bind._arg[1] = nullptr;
         bind._arg[1] = nullptr;
@@ -1552,8 +1588,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
             bind._func = Shader::SMF_compose;
             bind._func = Shader::SMF_compose;
             bind._part[0] = Shader::SMO_model_to_apiview;
             bind._part[0] = Shader::SMO_model_to_apiview;
             bind._arg[0] = nullptr;
             bind._arg[0] = nullptr;
-            bind._part[1] = Shader::SMO_mat_constant_x_attrib;
-            bind._arg[1] = iname->get_parent()->append("shadowViewMatrix");
+            bind._part[1] = Shader::SMO_apiview_to_apiclip_light_source_i;
+            bind._arg[1] = nullptr;
           } else {
           } else {
             bind._part[0] = Shader::SMO_mat_constant_x_attrib;
             bind._part[0] = Shader::SMO_mat_constant_x_attrib;
             bind._arg[0] = InternalName::make(param_name);
             bind._arg[0] = InternalName::make(param_name);
@@ -1578,16 +1614,16 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
           bind._id = arg_id;
           bind._id = arg_id;
           switch (param_type) {
           switch (param_type) {
           case GL_FLOAT:
           case GL_FLOAT:
-            bind._piece = Shader::SMP_row3x1;
+            bind._piece = Shader::SMP_float;
             break;
             break;
           case GL_FLOAT_VEC2:
           case GL_FLOAT_VEC2:
-            bind._piece = Shader::SMP_row3x2;
+            bind._piece = Shader::SMP_vec2;
             break;
             break;
           case GL_FLOAT_VEC3:
           case GL_FLOAT_VEC3:
-            bind._piece = Shader::SMP_row3x3;
+            bind._piece = Shader::SMP_vec3;
             break;
             break;
           default:
           default:
-            bind._piece = Shader::SMP_row3;
+            bind._piece = Shader::SMP_vec4;
           }
           }
           bind._func = Shader::SMF_first;
           bind._func = Shader::SMF_first;
           bind._part[0] = Shader::SMO_vec_constant_x_attrib;
           bind._part[0] = Shader::SMO_vec_constant_x_attrib;
@@ -2263,61 +2299,36 @@ issue_parameters(int altered) {
         continue;
         continue;
       }
       }
 
 
-      const LMatrix4 *val = _glgsg->fetch_specified_value(spec, _mat_part_cache, altered);
+      const LVecBase4f *val = _glgsg->fetch_specified_value(spec, _mat_part_cache, altered);
       if (!val) continue;
       if (!val) continue;
-#ifndef STDFLOAT_DOUBLE
-      // In this case, the data is already single-precision.
-      const PN_float32 *data = val->get_data();
-#else
-      // In this case, we have to convert it.
-      LMatrix4f valf = LCAST(PN_float32, *val);
-      const PN_float32 *data = valf.get_data();
-#endif
+      const float *data = val->get_data();
+      data += spec._offset;
 
 
       GLint p = spec._id._seqno;
       GLint p = spec._id._seqno;
       switch (spec._piece) {
       switch (spec._piece) {
-      case Shader::SMP_whole: _glgsg->_glUniformMatrix4fv(p, 1, GL_FALSE, data); continue;
-      case Shader::SMP_transpose: _glgsg->_glUniformMatrix4fv(p, 1, GL_TRUE, data); continue;
-      case Shader::SMP_col0: _glgsg->_glUniform4f(p, data[0], data[4], data[ 8], data[12]); continue;
-      case Shader::SMP_col1: _glgsg->_glUniform4f(p, data[1], data[5], data[ 9], data[13]); continue;
-      case Shader::SMP_col2: _glgsg->_glUniform4f(p, data[2], data[6], data[10], data[14]); continue;
-      case Shader::SMP_col3: _glgsg->_glUniform4f(p, data[3], data[7], data[11], data[15]); continue;
-      case Shader::SMP_row0: _glgsg->_glUniform4fv(p, 1, data+ 0); continue;
-      case Shader::SMP_row1: _glgsg->_glUniform4fv(p, 1, data+ 4); continue;
-      case Shader::SMP_row2: _glgsg->_glUniform4fv(p, 1, data+ 8); continue;
-      case Shader::SMP_row3: _glgsg->_glUniform4fv(p, 1, data+12); continue;
-      case Shader::SMP_row3x1: _glgsg->_glUniform1fv(p, 1, data+12); continue;
-      case Shader::SMP_row3x2: _glgsg->_glUniform2fv(p, 1, data+12); continue;
-      case Shader::SMP_row3x3: _glgsg->_glUniform3fv(p, 1, data+12); continue;
-      case Shader::SMP_upper3x3:
+      case Shader::SMP_float: _glgsg->_glUniform1fv(p, 1, data); continue;
+      case Shader::SMP_vec2: _glgsg->_glUniform2fv(p, 1, data); continue;
+      case Shader::SMP_vec3: _glgsg->_glUniform3fv(p, 1, data); continue;
+      case Shader::SMP_vec4: _glgsg->_glUniform4fv(p, 1, data); continue;
+      case Shader::SMP_mat4_whole: _glgsg->_glUniformMatrix4fv(p, 1, GL_FALSE, data); continue;
+      case Shader::SMP_mat4_transpose: _glgsg->_glUniformMatrix4fv(p, 1, GL_TRUE, data); continue;
+      case Shader::SMP_mat4_column: _glgsg->_glUniform4f(p, data[0], data[4], data[8], data[12]); continue;
+      case Shader::SMP_mat4_upper3x3:
         {
         {
-#ifndef STDFLOAT_DOUBLE
-          LMatrix3f upper3 = val->get_upper_3();
-#else
-          LMatrix3f upper3 = valf.get_upper_3();
-#endif
+          LMatrix3f upper3(data[0], data[1], data[2], data[4], data[5], data[6], data[8], data[9], data[10]);
           _glgsg->_glUniformMatrix3fv(p, 1, false, upper3.get_data());
           _glgsg->_glUniformMatrix3fv(p, 1, false, upper3.get_data());
           continue;
           continue;
         }
         }
-      case Shader::SMP_transpose3x3:
+      case Shader::SMP_mat4_transpose3x3:
         {
         {
-#ifndef STDFLOAT_DOUBLE
-          LMatrix3f upper3 = val->get_upper_3();
-#else
-          LMatrix3f upper3 = valf.get_upper_3();
-#endif
+          LMatrix3f upper3(data[0], data[1], data[2], data[4], data[5], data[6], data[8], data[9], data[10]);
           _glgsg->_glUniformMatrix3fv(p, 1, true, upper3.get_data());
           _glgsg->_glUniformMatrix3fv(p, 1, true, upper3.get_data());
           continue;
           continue;
         }
         }
-      case Shader::SMP_cell15:
-        _glgsg->_glUniform1fv(p, 1, data+15);
-        continue;
-      case Shader::SMP_cell14:
-        _glgsg->_glUniform1fv(p, 1, data+14);
-        continue;
-      case Shader::SMP_cell13:
-        _glgsg->_glUniform1fv(p, 1, data+13);
-        continue;
+        case Shader::SMP_int: _glgsg->_glUniform1i(p, ((int *)data)[0]);
+        case Shader::SMP_ivec2: _glgsg->_glUniform2iv(p, 1, (int *)data);
+        case Shader::SMP_ivec3: _glgsg->_glUniform3iv(p, 1, (int *)data);
+        case Shader::SMP_ivec4: _glgsg->_glUniform4iv(p, 1, (int *)data);
       }
       }
     }
     }
   }
   }

+ 1 - 1
panda/src/glstuff/glShaderContext_src.h

@@ -112,7 +112,7 @@ private:
   };
   };
   pvector<ImageInput> _glsl_img_inputs;
   pvector<ImageInput> _glsl_img_inputs;
 
 
-  LMatrix4 *_mat_part_cache = nullptr;
+  LVecBase4f *_mat_part_cache = nullptr;
 
 
   CLP(GraphicsStateGuardian) *_glgsg;
   CLP(GraphicsStateGuardian) *_glgsg;
 
 

+ 0 - 8
panda/src/glstuff/glmisc_src.h

@@ -24,16 +24,8 @@
 
 
 #ifndef STDFLOAT_DOUBLE
 #ifndef STDFLOAT_DOUBLE
 #define GLf(name) name ## f
 #define GLf(name) name ## f
-#define GLfv(name) name ## fv
-#define GLfc(name) name ## fc
-#define GLfr(name) name ## fr
-#define GLf_str "f"
 #else  // STDFLOAT_DOUBLE
 #else  // STDFLOAT_DOUBLE
 #define GLf(name) name ## d
 #define GLf(name) name ## d
-#define GLfv(name) name ## dv
-#define GLfc(name) name ## dc
-#define GLfr(name) name ## dr
-#define GLf_str "d"
 #endif  // STDFLOAT_DOUBLE
 #endif  // STDFLOAT_DOUBLE
 
 
 #endif  // GLf
 #endif  // GLf

+ 152 - 61
panda/src/gobj/shader.cxx

@@ -459,11 +459,13 @@ cp_dependency(ShaderMatInput inp) {
     }
     }
   }
   }
   if ((inp == SMO_light_ambient) ||
   if ((inp == SMO_light_ambient) ||
-      (inp == SMO_light_source_i_attrib) ||
+      (inp == SMO_light_source_i_vec_attrib) ||
+      (inp == SMO_apiview_to_apiclip_light_source_i) ||
       (inp == SMO_light_source_i_packed)) {
       (inp == SMO_light_source_i_packed)) {
     dep |= SSD_light | SSD_frame;
     dep |= SSD_light | SSD_frame;
   }
   }
-  if (inp == SMO_light_source_i_attrib ||
+  if (inp == SMO_light_source_i_vec_attrib ||
+      inp == SMO_apiview_to_apiclip_light_source_i ||
       inp == SMO_light_source_i_packed ||
       inp == SMO_light_source_i_packed ||
       inp == SMO_mat_constant_x_attrib ||
       inp == SMO_mat_constant_x_attrib ||
       inp == SMO_vec_constant_x_attrib) {
       inp == SMO_vec_constant_x_attrib) {
@@ -579,14 +581,13 @@ cp_add_mat_spec(ShaderMatSpec &spec) {
     for (int i = 0; i < 2; ++i) {
     for (int i = 0; i < 2; ++i) {
       if (spec._part[i] == SMO_texmat_i ||
       if (spec._part[i] == SMO_texmat_i ||
           spec._part[i] == SMO_inv_texmat_i ||
           spec._part[i] == SMO_inv_texmat_i ||
-          spec._part[i] == SMO_light_source_i_attrib ||
+          spec._part[i] == SMO_light_source_i_vec_attrib ||
+          spec._part[i] == SMO_apiview_to_apiclip_light_source_i ||
           spec._part[i] == SMO_light_product_i_ambient ||
           spec._part[i] == SMO_light_product_i_ambient ||
           spec._part[i] == SMO_light_product_i_diffuse ||
           spec._part[i] == SMO_light_product_i_diffuse ||
           spec._part[i] == SMO_light_product_i_specular ||
           spec._part[i] == SMO_light_product_i_specular ||
           spec._part[i] == SMO_apiview_clipplane_i ||
           spec._part[i] == SMO_apiview_clipplane_i ||
           spec._part[i] == SMO_tex_is_alpha_i ||
           spec._part[i] == SMO_tex_is_alpha_i ||
-          spec._part[i] == SMO_transform_i ||
-          spec._part[i] == SMO_slider_i ||
           spec._part[i] == SMO_light_source_i_packed ||
           spec._part[i] == SMO_light_source_i_packed ||
           spec._part[i] == SMO_texscale_i ||
           spec._part[i] == SMO_texscale_i ||
           spec._part[i] == SMO_texcolor_i) {
           spec._part[i] == SMO_texcolor_i) {
@@ -610,6 +611,9 @@ cp_add_mat_spec(ShaderMatSpec &spec) {
     for (i = 0; i < _mat_parts.size(); ++i) {
     for (i = 0; i < _mat_parts.size(); ++i) {
       ShaderMatPart &part = _mat_parts[i];
       ShaderMatPart &part = _mat_parts[i];
       if (part._part == spec._part[p] && part._arg == spec._arg[p]) {
       if (part._part == spec._part[p] && part._arg == spec._arg[p]) {
+        if (spec._func != SMF_first) {
+          assert(part._size == 4);
+        }
         int diff = end[p] - part._count;
         int diff = end[p] - part._count;
         if (diff <= 0) {
         if (diff <= 0) {
           // The existing cache entry is big enough.
           // The existing cache entry is big enough.
@@ -618,18 +622,18 @@ cp_add_mat_spec(ShaderMatSpec &spec) {
           // It's not big enough.  Enlarge it, which means we have to change the
           // It's not big enough.  Enlarge it, which means we have to change the
           // offset of some of the other spec entries.
           // offset of some of the other spec entries.
           for (ShaderMatSpec &spec : _mat_spec) {
           for (ShaderMatSpec &spec : _mat_spec) {
-            if (spec._cache_offset[0] >= offset + part._count) {
-              spec._cache_offset[0] += diff;
+            if (spec._cache_offset[0] >= offset + part._size * part._count) {
+              spec._cache_offset[0] += diff * part._size;
             }
             }
-            if (spec._cache_offset[1] >= offset + part._count) {
-              spec._cache_offset[1] += diff;
+            if (spec._cache_offset[1] >= offset + part._size * part._count) {
+              spec._cache_offset[1] += diff * part._size;
             }
             }
           }
           }
           part._count = end[p];
           part._count = end[p];
           break;
           break;
         }
         }
       }
       }
-      offset += part._count;
+      offset += part._count * part._size;
     }
     }
     if (i == _mat_parts.size()) {
     if (i == _mat_parts.size()) {
       // Didn't find this part yet, create a new one.
       // Didn't find this part yet, create a new one.
@@ -638,6 +642,88 @@ cp_add_mat_spec(ShaderMatSpec &spec) {
       part._count = end[p];
       part._count = end[p];
       part._arg = spec._arg[p];
       part._arg = spec._arg[p];
       part._dep = dep;
       part._dep = dep;
+
+      switch (part._part) {
+      case SMO_INVALID:
+        part._size = 0;
+        break;
+
+      case SMO_window_size:
+      case SMO_pixel_size:
+      case SMO_texpad_x:
+      case SMO_texpix_x:
+      case SMO_attr_material:
+      case SMO_attr_color:
+      case SMO_attr_colorscale:
+      case SMO_satten_x:
+      case SMO_plane_x:
+      case SMO_clipplane_x:
+      case SMO_vec_constant_x:
+      case SMO_attr_fog:
+      case SMO_attr_fogcolor:
+      case SMO_frame_number:
+      case SMO_frame_time:
+      case SMO_frame_delta:
+      case SMO_vec_constant_x_attrib:
+      case SMO_light_ambient:
+      case SMO_light_source_i_vec_attrib:
+      case SMO_light_product_i_ambient:
+      case SMO_light_product_i_diffuse:
+      case SMO_light_product_i_specular:
+      case SMO_apiview_clipplane_i:
+      case SMO_tex_is_alpha_i:
+      case SMO_texscale_i:
+      case SMO_texcolor_i:
+      case SMO_texconst_i:
+      case SMO_attr_pointparams:
+        part._size = 1;
+        break;
+
+      case SMO_attr_material2:
+        part._size = 2;
+        break;
+
+      case SMO_identity:
+      case SMO_alight_x:
+      case SMO_dlight_x:
+      case SMO_plight_x:
+      case SMO_slight_x:
+      case SMO_texmat_i:
+      case SMO_mat_constant_x:
+      case SMO_world_to_view:
+      case SMO_view_to_world:
+      case SMO_model_to_view:
+      case SMO_view_to_model:
+      case SMO_apiview_to_view:
+      case SMO_view_to_apiview:
+      case SMO_clip_to_view:
+      case SMO_view_to_clip:
+      case SMO_apiclip_to_view:
+      case SMO_view_to_apiclip:
+      case SMO_view_x_to_view:
+      case SMO_view_to_view_x:
+      case SMO_apiview_x_to_view:
+      case SMO_view_to_apiview_x:
+      case SMO_clip_x_to_view:
+      case SMO_view_to_clip_x:
+      case SMO_apiclip_x_to_view:
+      case SMO_view_to_apiclip_x:
+      case SMO_mat_constant_x_attrib:
+      case SMO_apiview_to_apiclip_light_source_i:
+      case SMO_model_to_apiview:
+      case SMO_apiview_to_model:
+      case SMO_apiview_to_apiclip:
+      case SMO_apiclip_to_apiview:
+      case SMO_inv_texmat_i:
+      case SMO_light_source_i_packed:
+        part._size = 4;
+        break;
+      }
+
+      if (spec._func != SMF_first) {
+        assert(part._size == 4);
+      }
+
       _mat_parts.push_back(std::move(part));
       _mat_parts.push_back(std::move(part));
     }
     }
     spec._cache_offset[p] = offset + begin[p];
     spec._cache_offset[p] = offset + begin[p];
@@ -648,13 +734,14 @@ cp_add_mat_spec(ShaderMatSpec &spec) {
 }
 }
 
 
 /**
 /**
- * Returns the total size of the matrix part cache.
+ * Returns the total size of the matrix part cache in terms of number of
+ * vectors.
  */
  */
 size_t Shader::
 size_t Shader::
 cp_get_mat_cache_size() const {
 cp_get_mat_cache_size() const {
   size_t size = 0;
   size_t size = 0;
   for (const ShaderMatPart &part : _mat_parts) {
   for (const ShaderMatPart &part : _mat_parts) {
-    size += part._count;
+    size += part._size * part._count;
   }
   }
   return size;
   return size;
 }
 }
@@ -858,12 +945,12 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
     }
     }
     ShaderMatSpec bind;
     ShaderMatSpec bind;
     bind._id = p._id;
     bind._id = p._id;
-    bind._piece = SMP_whole;
+    bind._piece = SMP_mat4_whole;
     bind._func = SMF_compose;
     bind._func = SMF_compose;
-    bind._part[1] = SMO_light_source_i_attrib;
-    bind._arg[1] = InternalName::make("shadowViewMatrix");
     bind._part[0] = SMO_view_to_apiview;
     bind._part[0] = SMO_view_to_apiview;
     bind._arg[0] = nullptr;
     bind._arg[0] = nullptr;
+    bind._part[1] = SMO_apiview_to_apiclip_light_source_i;
+    bind._arg[1] = nullptr;
     bind._index = atoi(pieces[2].c_str());
     bind._index = atoi(pieces[2].c_str());
 
 
     cp_add_mat_spec(bind);
     cp_add_mat_spec(bind);
@@ -969,42 +1056,46 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
 
 
     ShaderMatSpec bind;
     ShaderMatSpec bind;
     bind._id = p._id;
     bind._id = p._id;
-    bind._piece = SMP_whole;
+    bind._piece = SMP_mat4_whole;
     bind._func = SMF_compose;
     bind._func = SMF_compose;
-    bind._part[1] = SMO_light_source_i_attrib;
-    bind._arg[1] = InternalName::make("shadowViewMatrix");
     bind._part[0] = SMO_view_to_apiview;
     bind._part[0] = SMO_view_to_apiview;
     bind._arg[0] = nullptr;
     bind._arg[0] = nullptr;
+    bind._part[1] = SMO_apiview_to_apiclip_light_source_i;
+    bind._arg[1] = nullptr;
     bind._index = atoi(pieces[2].c_str());
     bind._index = atoi(pieces[2].c_str());
 
 
     int next = 1;
     int next = 1;
     pieces.push_back("");
     pieces.push_back("");
 
 
     // Decide whether this is a matrix or vector.
     // Decide whether this is a matrix or vector.
-    if      (pieces[0]=="trans")   bind._piece = SMP_whole;
-    else if (pieces[0]=="tpose")   bind._piece = SMP_transpose;
-    else if (pieces[0]=="row0")    bind._piece = SMP_row0;
-    else if (pieces[0]=="row1")    bind._piece = SMP_row1;
-    else if (pieces[0]=="row2")    bind._piece = SMP_row2;
-    else if (pieces[0]=="row3")    bind._piece = SMP_row3;
-    else if (pieces[0]=="col0")    bind._piece = SMP_col0;
-    else if (pieces[0]=="col1")    bind._piece = SMP_col1;
-    else if (pieces[0]=="col2")    bind._piece = SMP_col2;
-    else if (pieces[0]=="col3")    bind._piece = SMP_col3;
-    if ((bind._piece == SMP_whole)||(bind._piece == SMP_transpose)) {
+    if (pieces[0][0] == 't') { // trans or tpose
+      bool tpose = (pieces[0][1] == 'p');
       if (p._type == SAT_mat3x3) {
       if (p._type == SAT_mat3x3) {
-        if (!cp_errchk_parameter_float(p, 9, 9)) return false;
-
-        if (bind._piece == SMP_transpose) {
-          bind._piece = SMP_transpose3x3;
-        } else {
-          bind._piece = SMP_upper3x3;
+        if (!cp_errchk_parameter_float(p, 9, 9)) {
+          return false;
+        }
+        bind._piece = tpose ? SMP_mat4_transpose3x3 : SMP_mat4_upper3x3;
+      }
+      else {
+        if (!cp_errchk_parameter_float(p, 16, 16)) {
+          return false;
         }
         }
-      } else if (!cp_errchk_parameter_float(p, 16, 16)) {
+        bind._piece = tpose ? SMP_mat4_transpose : SMP_mat4_whole;
+      }
+    }
+    else if (pieces[0][0] == 'r') { // row0, row1, row2, row3
+      if (!cp_errchk_parameter_float(p, 4, 4)) {
         return false;
         return false;
       }
       }
-    } else {
-      if (!cp_errchk_parameter_float(p, 4, 4)) return false;
+      bind._piece = SMP_vec4;
+      bind._offset = (pieces[0][3] - '0') * 4;
+    }
+    else if (pieces[0][0] == 'c') { // col0, col1, col2, col3
+      if (!cp_errchk_parameter_float(p, 4, 4)) {
+        return false;
+      }
+      bind._piece = SMP_mat4_column;
+      bind._offset = pieces[0][3] - '0';
     }
     }
 
 
     if (!cp_parse_coord_sys(p, pieces, next, bind, true)) {
     if (!cp_parse_coord_sys(p, pieces, next, bind, true)) {
@@ -1037,7 +1128,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
         return false;
         return false;
       }
       }
       bind._id = p._id;
       bind._id = p._id;
-      bind._piece = SMP_transpose;
+      bind._piece = SMP_mat4_transpose;
       bind._func = SMF_first;
       bind._func = SMF_first;
       bind._part[0] = SMO_attr_material;
       bind._part[0] = SMO_attr_material;
       bind._arg[0] = nullptr;
       bind._arg[0] = nullptr;
@@ -1048,7 +1139,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
         return false;
         return false;
       }
       }
       bind._id = p._id;
       bind._id = p._id;
-      bind._piece = SMP_row3;
+      bind._piece = SMP_vec4;
       bind._func = SMF_first;
       bind._func = SMF_first;
       bind._part[0] = SMO_attr_color;
       bind._part[0] = SMO_attr_color;
       bind._arg[0] = nullptr;
       bind._arg[0] = nullptr;
@@ -1059,7 +1150,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
         return false;
         return false;
       }
       }
       bind._id = p._id;
       bind._id = p._id;
-      bind._piece = SMP_row3;
+      bind._piece = SMP_vec4;
       bind._func = SMF_first;
       bind._func = SMF_first;
       bind._part[0] = SMO_attr_colorscale;
       bind._part[0] = SMO_attr_colorscale;
       bind._arg[0] = nullptr;
       bind._arg[0] = nullptr;
@@ -1070,7 +1161,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
         return false;
         return false;
       }
       }
       bind._id = p._id;
       bind._id = p._id;
-      bind._piece = SMP_row3;
+      bind._piece = SMP_vec4;
       bind._func = SMF_first;
       bind._func = SMF_first;
       bind._part[0] = SMO_attr_fog;
       bind._part[0] = SMO_attr_fog;
       bind._arg[0] = nullptr;
       bind._arg[0] = nullptr;
@@ -1081,7 +1172,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
         return false;
         return false;
       }
       }
       bind._id = p._id;
       bind._id = p._id;
-      bind._piece = SMP_row3;
+      bind._piece = SMP_vec4;
       bind._func = SMF_first;
       bind._func = SMF_first;
       bind._part[0] = SMO_attr_fogcolor;
       bind._part[0] = SMO_attr_fogcolor;
       bind._arg[0] = nullptr;
       bind._arg[0] = nullptr;
@@ -1092,7 +1183,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
         return false;
         return false;
       }
       }
       bind._id = p._id;
       bind._id = p._id;
-      bind._piece = SMP_row3;
+      bind._piece = SMP_vec4;
       bind._func = SMF_first;
       bind._func = SMF_first;
       bind._part[0] = SMO_light_ambient;
       bind._part[0] = SMO_light_ambient;
       bind._arg[0] = nullptr;
       bind._arg[0] = nullptr;
@@ -1103,7 +1194,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
         return false;
         return false;
       }
       }
       bind._id = p._id;
       bind._id = p._id;
-      bind._piece = SMP_transpose;
+      bind._piece = SMP_mat4_transpose;
       bind._func = SMF_first;
       bind._func = SMF_first;
       bind._part[0] = SMO_light_source_i_packed;
       bind._part[0] = SMO_light_source_i_packed;
       bind._arg[0] = nullptr;
       bind._arg[0] = nullptr;
@@ -1115,9 +1206,9 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
         return false;
         return false;
       }
       }
       bind._id = p._id;
       bind._id = p._id;
-      bind._piece = SMP_row3;
+      bind._piece = SMP_vec4;
       bind._func = SMF_first;
       bind._func = SMF_first;
-      bind._part[0] = SMO_light_source_i_attrib;
+      bind._part[0] = SMO_light_source_i_vec_attrib;
       bind._arg[0] = InternalName::make("specular");
       bind._arg[0] = InternalName::make("specular");
       bind._part[1] = SMO_identity;
       bind._part[1] = SMO_identity;
       bind._arg[1] = nullptr;
       bind._arg[1] = nullptr;
@@ -1127,7 +1218,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
         return false;
         return false;
       }
       }
       bind._id = p._id;
       bind._id = p._id;
-      bind._piece = SMP_row3;
+      bind._piece = SMP_vec4;
       bind._func = SMF_first;
       bind._func = SMF_first;
       bind._part[0] = SMO_attr_pointparams;
       bind._part[0] = SMO_attr_pointparams;
       bind._arg[0] = nullptr;
       bind._arg[0] = nullptr;
@@ -1165,7 +1256,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
     }
     }
     ShaderMatSpec bind;
     ShaderMatSpec bind;
     bind._id = p._id;
     bind._id = p._id;
-    bind._piece = SMP_row3;
+    bind._piece = SMP_vec4;
     bind._func = SMF_first;
     bind._func = SMF_first;
     bind._part[0] = SMO_alight_x;
     bind._part[0] = SMO_alight_x;
     bind._arg[0] = InternalName::make(pieces[1]);
     bind._arg[0] = InternalName::make(pieces[1]);
@@ -1185,7 +1276,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
     }
     }
     ShaderMatSpec bind;
     ShaderMatSpec bind;
     bind._id = p._id;
     bind._id = p._id;
-    bind._piece = SMP_row3;
+    bind._piece = SMP_vec4;
     bind._func = SMF_first;
     bind._func = SMF_first;
     bind._part[0] = SMO_satten_x;
     bind._part[0] = SMO_satten_x;
     bind._arg[0] = InternalName::make(pieces[1]);
     bind._arg[0] = InternalName::make(pieces[1]);
@@ -1204,7 +1295,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
     }
     }
     ShaderMatSpec bind;
     ShaderMatSpec bind;
     bind._id = p._id;
     bind._id = p._id;
-    bind._piece = SMP_transpose;
+    bind._piece = SMP_mat4_transpose;
     int next = 1;
     int next = 1;
     pieces.push_back("");
     pieces.push_back("");
     if (pieces[next] == "") {
     if (pieces[next] == "") {
@@ -1245,7 +1336,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
     }
     }
     ShaderMatSpec bind;
     ShaderMatSpec bind;
     bind._id = p._id;
     bind._id = p._id;
-    bind._piece = SMP_whole;
+    bind._piece = SMP_mat4_whole;
     bind._func = SMF_first;
     bind._func = SMF_first;
     bind._part[0] = SMO_texmat_i;
     bind._part[0] = SMO_texmat_i;
     bind._arg[0] = nullptr;
     bind._arg[0] = nullptr;
@@ -1266,7 +1357,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
     }
     }
     ShaderMatSpec bind;
     ShaderMatSpec bind;
     bind._id = p._id;
     bind._id = p._id;
-    bind._piece = SMP_row3;
+    bind._piece = SMP_vec4;
     bind._func = SMF_first;
     bind._func = SMF_first;
     bind._part[0] = SMO_texscale_i;
     bind._part[0] = SMO_texscale_i;
     bind._arg[0] = nullptr;
     bind._arg[0] = nullptr;
@@ -1287,7 +1378,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
     }
     }
     ShaderMatSpec bind;
     ShaderMatSpec bind;
     bind._id = p._id;
     bind._id = p._id;
-    bind._piece = SMP_row3;
+    bind._piece = SMP_vec4;
     bind._func = SMF_first;
     bind._func = SMF_first;
     bind._part[0] = SMO_texcolor_i;
     bind._part[0] = SMO_texcolor_i;
     bind._arg[0] = nullptr;
     bind._arg[0] = nullptr;
@@ -1308,7 +1399,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
     }
     }
     ShaderMatSpec bind;
     ShaderMatSpec bind;
     bind._id = p._id;
     bind._id = p._id;
-    bind._piece = SMP_row3;
+    bind._piece = SMP_vec4;
     bind._func = SMF_first;
     bind._func = SMF_first;
     bind._part[0] = SMO_texconst_i;
     bind._part[0] = SMO_texconst_i;
     bind._arg[0] = nullptr;
     bind._arg[0] = nullptr;
@@ -1329,7 +1420,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
     }
     }
     ShaderMatSpec bind;
     ShaderMatSpec bind;
     bind._id = p._id;
     bind._id = p._id;
-    bind._piece = SMP_row3;
+    bind._piece = SMP_vec4;
     bind._func = SMF_first;
     bind._func = SMF_first;
     bind._part[0] = SMO_plane_x;
     bind._part[0] = SMO_plane_x;
     bind._arg[0] = InternalName::make(pieces[1]);
     bind._arg[0] = InternalName::make(pieces[1]);
@@ -1349,7 +1440,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
     }
     }
     ShaderMatSpec bind;
     ShaderMatSpec bind;
     bind._id = p._id;
     bind._id = p._id;
-    bind._piece = SMP_row3;
+    bind._piece = SMP_vec4;
     bind._func = SMF_first;
     bind._func = SMF_first;
     bind._part[0] = SMO_clipplane_x;
     bind._part[0] = SMO_clipplane_x;
     bind._arg[0] = InternalName::make(pieces[1]);
     bind._arg[0] = InternalName::make(pieces[1]);
@@ -1370,7 +1461,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
     }
     }
     ShaderMatSpec bind;
     ShaderMatSpec bind;
     bind._id = p._id;
     bind._id = p._id;
-    bind._piece = SMP_row3;
+    bind._piece = SMP_vec4;
     bind._func = SMF_first;
     bind._func = SMF_first;
     bind._part[1] = SMO_identity;
     bind._part[1] = SMO_identity;
     bind._arg[1] = nullptr;
     bind._arg[1] = nullptr;
@@ -1392,7 +1483,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
       if (!cp_errchk_parameter_float(p, 1, 1)) {
       if (!cp_errchk_parameter_float(p, 1, 1)) {
         return false;
         return false;
       }
       }
-      bind._piece = SMP_row3x1;
+      bind._piece = SMP_float;
       bind._part[0] = SMO_frame_time;
       bind._part[0] = SMO_frame_time;
       bind._arg[0] = nullptr;
       bind._arg[0] = nullptr;
 
 
@@ -1479,7 +1570,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
     }
     }
     ShaderMatSpec bind;
     ShaderMatSpec bind;
     bind._id = p._id;
     bind._id = p._id;
-    bind._piece = SMP_row3;
+    bind._piece = SMP_vec4;
     bind._func = SMF_first;
     bind._func = SMF_first;
     bind._part[0] = SMO_texpad_x;
     bind._part[0] = SMO_texpad_x;
     bind._arg[0] = InternalName::make(pieces[1]);
     bind._arg[0] = InternalName::make(pieces[1]);
@@ -1498,7 +1589,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
     }
     }
     ShaderMatSpec bind;
     ShaderMatSpec bind;
     bind._id = p._id;
     bind._id = p._id;
-    bind._piece = SMP_row3;
+    bind._piece = SMP_vec4;
     bind._func = SMF_first;
     bind._func = SMF_first;
     bind._part[0] = SMO_texpix_x;
     bind._part[0] = SMO_texpix_x;
     bind._arg[0] = InternalName::make(pieces[1]);
     bind._arg[0] = InternalName::make(pieces[1]);

+ 22 - 26
panda/src/gobj/shader.h

@@ -183,7 +183,8 @@ public:
     SMO_vec_constant_x_attrib,
     SMO_vec_constant_x_attrib,
 
 
     SMO_light_ambient,
     SMO_light_ambient,
-    SMO_light_source_i_attrib,
+    SMO_light_source_i_vec_attrib,
+    SMO_apiview_to_apiclip_light_source_i,
 
 
     SMO_light_product_i_ambient,
     SMO_light_product_i_ambient,
     SMO_light_product_i_diffuse,
     SMO_light_product_i_diffuse,
@@ -205,9 +206,6 @@ public:
     // Hack for text rendering.  Don't use in user shaders.
     // Hack for text rendering.  Don't use in user shaders.
     SMO_tex_is_alpha_i,
     SMO_tex_is_alpha_i,
 
 
-    SMO_transform_i,
-    SMO_slider_i,
-
     SMO_light_source_i_packed,
     SMO_light_source_i_packed,
 
 
     // Texture scale component of texture matrix.
     // Texture scale component of texture matrix.
@@ -294,24 +292,19 @@ public:
   };
   };
 
 
   enum ShaderMatPiece {
   enum ShaderMatPiece {
-    SMP_whole,
-    SMP_transpose,
-    SMP_row0,
-    SMP_row1,
-    SMP_row2,
-    SMP_row3,
-    SMP_col0,
-    SMP_col1,
-    SMP_col2,
-    SMP_col3,
-    SMP_row3x1,
-    SMP_row3x2,
-    SMP_row3x3,
-    SMP_upper3x3,
-    SMP_transpose3x3,
-    SMP_cell15,
-    SMP_cell14,
-    SMP_cell13,
+    SMP_float,
+    SMP_vec2,
+    SMP_vec3,
+    SMP_vec4,
+    SMP_mat4_whole,
+    SMP_mat4_transpose,
+    SMP_mat4_column,
+    SMP_mat4_upper3x3,
+    SMP_mat4_transpose3x3,
+    SMP_int,
+    SMP_ivec2,
+    SMP_ivec3,
+    SMP_ivec4,
   };
   };
 
 
   enum ShaderStateDep {
   enum ShaderStateDep {
@@ -339,11 +332,11 @@ public:
   };
   };
 
 
   enum ShaderMatFunc {
   enum ShaderMatFunc {
+    SMF_first,
     SMF_compose,
     SMF_compose,
     SMF_transform_dlight,
     SMF_transform_dlight,
     SMF_transform_plight,
     SMF_transform_plight,
     SMF_transform_slight,
     SMF_transform_slight,
-    SMF_first,
   };
   };
 
 
   struct ShaderArgId {
   struct ShaderArgId {
@@ -422,12 +415,14 @@ public:
 
 
   /**
   /**
    * Describes a matrix making up a single part of the ShaderMatInput cache.
    * Describes a matrix making up a single part of the ShaderMatInput cache.
-   * The cache is made up of a continuous array of matrices, as described by
-   * a successive list of ShaderMatPart (each of which takes up _count matrices)
+   * The cache is made up of a continuous array of vectors, as described by
+   * a successive list of ShaderMatPart (each of which takes up _count times
+   * _size vectors)
    */
    */
   struct ShaderMatPart {
   struct ShaderMatPart {
     ShaderMatInput _part;
     ShaderMatInput _part;
     PT(InternalName) _arg;
     PT(InternalName) _arg;
+    int _size = 1;
     int _count = 1;
     int _count = 1;
     int _dep = SSD_NONE;
     int _dep = SSD_NONE;
   };
   };
@@ -441,10 +436,11 @@ public:
     ShaderMatFunc     _func;
     ShaderMatFunc     _func;
     ShaderMatInput    _part[2];
     ShaderMatInput    _part[2];
     PT(InternalName)  _arg[2];
     PT(InternalName)  _arg[2];
-    LMatrix4          _value;
+    LMatrix4f         _value;
     int               _dep = SSD_NONE;
     int               _dep = SSD_NONE;
     int               _index = 0;
     int               _index = 0;
     ShaderMatPiece    _piece;
     ShaderMatPiece    _piece;
+    int               _offset = 0;
   };
   };
 
 
   struct ShaderTexSpec {
   struct ShaderTexSpec {

Some files were not shown because too many files changed in this diff