Browse Source

shader: Work on phasing out ShaderMatPiece

This part is redundant with the type, other than having a flag for transposition. It's useful on the back-end, but there doesn't need to be code to deal with it in Shader. I intend to move this to the back-end entirely, just like most of ShaderMatSpec.
rdb 1 year ago
parent
commit
6830880392

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

@@ -922,6 +922,10 @@ fetch_specified_value(Shader::ShaderMatSpec &spec, const LVecBase4 *cache,
   const LVecBase4 *cache1 = cache + spec._cache_offset[1];
 
   switch (spec._func) {
+  case Shader::SMF_shader_input:
+    return _target_shader->get_shader_input_data(spec._id._name, scratch,
+      spec._scalar_type, spec._array_count, spec._num_rows, spec._num_cols, pad_rows);
+
   case Shader::SMF_first:
 #ifdef STDFLOAT_DOUBLE
     if (spec._scalar_type == ShaderType::ST_double) {
@@ -1033,10 +1037,6 @@ fetch_specified_value(Shader::ShaderMatSpec &spec, const LVecBase4 *cache,
     m.set_row(3, v);
     break;
 
-  case Shader::SMF_shader_input_ptr:
-    return _target_shader->get_shader_input_data(spec._id._name, scratch,
-      spec._scalar_type, spec._array_count, spec._num_rows, spec._num_cols, pad_rows);
-
   default:
     // Should never get here
     m = LMatrix4::ident_mat();

+ 22 - 42
panda/src/glstuff/glShaderContext_src.cxx

@@ -1412,19 +1412,13 @@ issue_parameters(int altered) {
         const float *data = (const float *)val;
 
         switch (spec._piece) {
-        case Shader::SMP_scalar: _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_scalar_array: _glgsg->_glUniform1fv(p, spec._array_count, data); continue;
-        case Shader::SMP_vec2_array: _glgsg->_glUniform2fv(p, spec._array_count, data); continue;
-        case Shader::SMP_vec3_array: _glgsg->_glUniform3fv(p, spec._array_count, data); continue;
-        case Shader::SMP_vec4_array: _glgsg->_glUniform4fv(p, spec._array_count, data); continue;
-        case Shader::SMP_mat3_whole: _glgsg->_glUniformMatrix3fv(p, 1, GL_FALSE, data); continue;
-        case Shader::SMP_mat3_array: _glgsg->_glUniformMatrix3fv(p, spec._array_count, GL_FALSE, data); continue;
-        case Shader::SMP_mat4_whole: _glgsg->_glUniformMatrix4fv(p, 1, GL_FALSE, data); continue;
-        case Shader::SMP_mat4_array: _glgsg->_glUniformMatrix4fv(p, spec._array_count, GL_FALSE, data); continue;
-        case Shader::SMP_mat4_transpose: _glgsg->_glUniformMatrix4fv(p, 1, GL_TRUE, data); continue;
+        case Shader::SMP_scalar: _glgsg->_glUniform1fv(p, spec._array_count, data); continue;
+        case Shader::SMP_vec2: _glgsg->_glUniform2fv(p, spec._array_count, data); continue;
+        case Shader::SMP_vec3: _glgsg->_glUniform3fv(p, spec._array_count, data); continue;
+        case Shader::SMP_vec4: _glgsg->_glUniform4fv(p, spec._array_count, data); continue;
+        case Shader::SMP_mat3_whole: _glgsg->_glUniformMatrix3fv(p, spec._array_count, GL_FALSE, data); continue;
+        case Shader::SMP_mat4_whole: _glgsg->_glUniformMatrix4fv(p, spec._array_count, GL_FALSE, data); continue;
+        case Shader::SMP_mat4_transpose: _glgsg->_glUniformMatrix4fv(p, spec._array_count, 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:
           {
@@ -1470,19 +1464,13 @@ issue_parameters(int altered) {
         set_uniform_location(spec._id._location, -1);
 #else
         switch (spec._piece) {
-        case Shader::SMP_scalar: _glgsg->_glUniform1dv(p, 1, data); continue;
-        case Shader::SMP_vec2: _glgsg->_glUniform2dv(p, 1, data); continue;
-        case Shader::SMP_vec3: _glgsg->_glUniform3dv(p, 1, data); continue;
-        case Shader::SMP_vec4: _glgsg->_glUniform4dv(p, 1, data); continue;
-        case Shader::SMP_scalar_array: _glgsg->_glUniform1dv(p, spec._array_count, data); continue;
-        case Shader::SMP_vec2_array: _glgsg->_glUniform2dv(p, spec._array_count, data); continue;
-        case Shader::SMP_vec3_array: _glgsg->_glUniform3dv(p, spec._array_count, data); continue;
-        case Shader::SMP_vec4_array: _glgsg->_glUniform4dv(p, spec._array_count, data); continue;
-        case Shader::SMP_mat3_whole: _glgsg->_glUniformMatrix3dv(p, 1, GL_FALSE, data); continue;
-        case Shader::SMP_mat3_array: _glgsg->_glUniformMatrix3dv(p, spec._array_count, GL_FALSE, data); continue;
-        case Shader::SMP_mat4_whole: _glgsg->_glUniformMatrix4dv(p, 1, GL_FALSE, data); continue;
-        case Shader::SMP_mat4_array: _glgsg->_glUniformMatrix4dv(p, spec._array_count, GL_FALSE, data); continue;
-        case Shader::SMP_mat4_transpose: _glgsg->_glUniformMatrix4dv(p, 1, GL_TRUE, data); continue;
+        case Shader::SMP_scalar: _glgsg->_glUniform1dv(p, spec._array_count, data); continue;
+        case Shader::SMP_vec2: _glgsg->_glUniform2dv(p, spec._array_count, data); continue;
+        case Shader::SMP_vec3: _glgsg->_glUniform3dv(p, spec._array_count, data); continue;
+        case Shader::SMP_vec4: _glgsg->_glUniform4dv(p, spec._array_count, data); continue;
+        case Shader::SMP_mat3_whole: _glgsg->_glUniformMatrix3dv(p, spec._array_count, GL_FALSE, data); continue;
+        case Shader::SMP_mat4_whole: _glgsg->_glUniformMatrix4dv(p, spec._array_count, GL_FALSE, data); continue;
+        case Shader::SMP_mat4_transpose: _glgsg->_glUniformMatrix4dv(p, spec._array_count, GL_TRUE, data); continue;
         case Shader::SMP_mat4_column: _glgsg->_glUniform4d(p, data[0], data[4], data[8], data[12]); continue;
         case Shader::SMP_mat4_upper3x3:
           {
@@ -1521,14 +1509,10 @@ issue_parameters(int altered) {
         const int *data = (const int *)val;
 
         switch (spec._piece) {
-        case Shader::SMP_scalar: _glgsg->_glUniform1i(p, ((int *)data)[0]);; continue;
-        case Shader::SMP_vec2: _glgsg->_glUniform2iv(p, 1, data); continue;
-        case Shader::SMP_vec3: _glgsg->_glUniform3iv(p, 1, data); continue;
-        case Shader::SMP_vec4: _glgsg->_glUniform4iv(p, 1, data); continue;
-        case Shader::SMP_scalar_array: _glgsg->_glUniform1iv(p, spec._array_count, data); continue;
-        case Shader::SMP_vec2_array: _glgsg->_glUniform2iv(p, spec._array_count, data); continue;
-        case Shader::SMP_vec3_array: _glgsg->_glUniform3iv(p, spec._array_count, data); continue;
-        case Shader::SMP_vec4_array: _glgsg->_glUniform4iv(p, spec._array_count, data); continue;
+        case Shader::SMP_scalar: _glgsg->_glUniform1iv(p, spec._array_count, data); continue;
+        case Shader::SMP_vec2: _glgsg->_glUniform2iv(p, spec._array_count, data); continue;
+        case Shader::SMP_vec3: _glgsg->_glUniform3iv(p, spec._array_count, data); continue;
+        case Shader::SMP_vec4: _glgsg->_glUniform4iv(p, spec._array_count, data); continue;
         default: nassert_raise("Invalid ShaderMatSpec piece with scalar type int");
         }
       }
@@ -1536,14 +1520,10 @@ issue_parameters(int altered) {
         const unsigned int *data = (const unsigned int *)val;
 
         switch (spec._piece) {
-        case Shader::SMP_scalar: _glgsg->_glUniform1uiv(p, 1, data); continue;
-        case Shader::SMP_vec2: _glgsg->_glUniform2uiv(p, 1, data); continue;
-        case Shader::SMP_vec3: _glgsg->_glUniform3uiv(p, 1, data); continue;
-        case Shader::SMP_vec4: _glgsg->_glUniform4uiv(p, 1, data); continue;
-        case Shader::SMP_scalar_array: _glgsg->_glUniform1uiv(p, spec._array_count, data); continue;
-        case Shader::SMP_vec2_array: _glgsg->_glUniform2uiv(p, spec._array_count, data); continue;
-        case Shader::SMP_vec3_array: _glgsg->_glUniform3uiv(p, spec._array_count, data); continue;
-        case Shader::SMP_vec4_array: _glgsg->_glUniform4uiv(p, spec._array_count, data); continue;
+        case Shader::SMP_scalar: _glgsg->_glUniform1uiv(p, spec._array_count, data); continue;
+        case Shader::SMP_vec2: _glgsg->_glUniform2uiv(p, spec._array_count, data); continue;
+        case Shader::SMP_vec3: _glgsg->_glUniform3uiv(p, spec._array_count, data); continue;
+        case Shader::SMP_vec4: _glgsg->_glUniform4uiv(p, spec._array_count, data); continue;
         default: nassert_raise("Invalid ShaderMatSpec piece with scalar type uint/bool");
         }
       }

+ 107 - 181
panda/src/gobj/shader.cxx

@@ -256,10 +256,10 @@ expect_coordinate_system(const InternalName *name, const ::ShaderType *type,
  *
  */
 bool Shader::
-check_light_struct_member(const string &name, const ShaderType *type,
-                          ShaderMatPiece &piece, int &offset) {
-
-  ShaderMatPiece expected = SMP_vec4;
+check_light_struct_member(const string &name, const ShaderType *type, int &offset) {
+  uint32_t num_rows = 1;
+  uint32_t min_cols = 3;
+  uint32_t max_cols = 4;
   if (name == "color") {
     offset = 4 * Shader::LA_color;
   }
@@ -283,39 +283,47 @@ check_light_struct_member(const string &name, const ShaderType *type,
   }
   else if (name == "spotCosCutoff") {
     offset = 4 * Shader::LA_spot_params;
-    expected = SMP_scalar;
+    min_cols = 1;
+    max_cols = 1;
   }
   else if (name == "spotCutoff") {
     offset = 4 * Shader::LA_spot_params + 1;
-    expected = SMP_scalar;
+    min_cols = 1;
+    max_cols = 1;
   }
   else if (name == "spotExponent") {
     offset = 4 * Shader::LA_spot_params + 2;
-    expected = SMP_scalar;
+    min_cols = 1;
+    max_cols = 1;
   }
   else if (name == "attenuation") {
     offset = 4 * Shader::LA_attenuation;
-    expected = SMP_vec3;
   }
   else if (name == "constantAttenuation") {
     offset = 4 * Shader::LA_attenuation;
-    expected = SMP_scalar;
+    min_cols = 1;
+    max_cols = 1;
   }
   else if (name == "linearAttenuation") {
     offset = 4 * Shader::LA_attenuation + 1;
-    expected = SMP_scalar;
+    min_cols = 1;
+    max_cols = 1;
   }
   else if (name == "quadraticAttenuation") {
     offset = 4 * Shader::LA_attenuation + 2;
-    expected = SMP_scalar;
+    min_cols = 1;
+    max_cols = 1;
   }
   else if (name == "radius") {
     offset = 4 * Shader::LA_attenuation + 3;
-    expected = SMP_scalar;
+    min_cols = 1;
+    max_cols = 1;
   }
   else if (name == "shadowViewMatrix") {
     offset = 4 * Shader::LA_shadow_view_matrix;
-    expected = SMP_mat4_whole;
+    num_rows = 4;
+    min_cols = 4;
+    max_cols = 4;
   }
   else {
     return false;
@@ -323,32 +331,28 @@ check_light_struct_member(const string &name, const ShaderType *type,
 
   const ::ShaderType::Matrix *matrix = type->as_matrix();
   if (matrix != nullptr) {
-    if (matrix->get_num_rows() != 4 || matrix->get_num_columns() != 4) {
+    if (matrix->get_num_rows() != num_rows ||
+        matrix->get_num_columns() < min_cols ||
+        matrix->get_num_columns() > max_cols) {
       return false;
     }
-    piece = SMP_mat4_whole;
+  }
+  else if (num_rows != 1) {
+    return false;
   }
   else {
-    const ::ShaderType::Vector *vector = type->as_vector();
-    if (vector == nullptr || vector->get_num_components() == 1) {
-      piece = SMP_scalar;
+    uint32_t num_components = 1;
+    if (const ::ShaderType::Vector *vector = type->as_vector()) {
+      num_components = vector->get_num_components();
     }
-    else if (vector->get_num_components() == 2) {
-      piece = SMP_vec2;
-    }
-    else if (vector->get_num_components() == 3) {
-      piece = SMP_vec3;
+    else if (type->as_scalar() == nullptr) {
+      return false;
     }
-    else {
-      piece = SMP_vec4;
+    if (num_components < min_cols || num_components > max_cols) {
+      return false;
     }
   }
 
-  // It's okay to declare as vec3 if we allow vec4.
-  if (piece != expected && (expected != SMP_vec4 || piece != SMP_vec3)) {
-    return false;
-  }
-
   return true;
 }
 
@@ -1670,9 +1674,8 @@ bind_parameter(const Parameter &param) {
               }
             }
 
-            ShaderMatPiece piece;
             int offset;
-            if (!check_light_struct_member(member.name, member.type, piece, offset)) {
+            if (!check_light_struct_member(member.name, member.type, offset)) {
               shader_cat.error()
                 << "Invalid light struct member "
                 << *member.type << " " << member.name << "\n";
@@ -2035,10 +2038,11 @@ bind_parameter(const Parameter &param) {
           "unexpected extra words after parameter name");
       }
 
-      return do_bind_parameter(param, func, SMP_mat4_whole, 0,
-        cp_dependency(part[0]) | cp_dependency(part[1]),
+      return do_bind_parameter(param, func,
         cp_add_mat_part(part[0], arg[0], type),
-        cp_add_mat_part(part[1], arg[1], type)
+        cp_add_mat_part(part[1], arg[1], type),
+        false, 0,
+        cp_dependency(part[0]) | cp_dependency(part[1])
       );
     }
 
@@ -2274,25 +2278,6 @@ bind_parameter(const Parameter &param) {
       return false;
     }
 
-    ShaderMatPiece piece;
-    if (arg_dim[1] >= 4) {
-      if (arg_dim[2] == 4) {
-        piece = type->as_array() ? SMP_mat4_array : SMP_mat4_whole;
-      } else {
-        piece = SMP_mat4_upper4x3;
-      }
-    } else if (arg_dim[1] > 1) {
-      if (arg_dim[2] == 4) {
-        piece = SMP_mat4_upper3x4;
-      } else {
-        piece = type->as_array() ? SMP_mat3_array : SMP_mat3_whole;
-      }
-    } else if (type->as_array()) {
-      piece = (ShaderMatPiece)(SMP_scalar_array + (arg_dim[2] - 1));
-    } else {
-      piece = (ShaderMatPiece)(SMP_scalar + (arg_dim[2] - 1));
-    }
-
     //if (k_prefix) {
     //  // Backward compatibility, disables certain checks.
     //  bind._dim[0] = -1;
@@ -2302,7 +2287,7 @@ bind_parameter(const Parameter &param) {
     // frame to frame, and we have no way to know.  So, we must respecify a
     // PTA at least once every frame.
     int dep = SSD_general | SSD_shaderinputs | SSD_frame;
-    return do_bind_parameter(param, SMF_shader_input_ptr, piece, 0, dep);
+    return do_bind_parameter(param, SMF_shader_input, 0, 0, false, 0, dep);
   }
 
   shader_cat.error()
@@ -2318,48 +2303,15 @@ bool Shader::
 bind_parameter(const Parameter &param, ShaderMatInput part,
                const InternalName *arg, int index, int offset) {
 
-  ScalarType scalar_type;
-  uint32_t array_count, num_rows, num_cols;
-  if (!param._type->as_scalar_type(scalar_type, array_count, num_rows, num_cols)) {
-    return report_parameter_error(param._name, param._type, "expected numeric type");
-  }
-
-  ShaderMatPiece piece;
-  bool transpose = (_language == SL_Cg);
-  if (num_rows >= 4 && num_cols >= 3) {
-    if (num_cols >= 4) {
-      piece = transpose ? SMP_mat4_transpose : SMP_mat4_whole;
-    } else {
-      piece = transpose ? SMP_mat4_transpose4x3 : SMP_mat4_upper4x3;
-    }
-  }
-  else if (num_rows >= 3 && num_cols >= 3) {
-    if (num_cols >= 4) {
-      piece = transpose ? SMP_mat4_transpose3x4 : SMP_mat4_upper3x4;
-    } else {
-      piece = transpose ? SMP_mat4_transpose3x3 : SMP_mat4_upper3x3;
-    }
-  }
-  else if (num_rows == 2 || num_cols == 2) {
-    return report_parameter_error(param._name, param._type, "mat2 not supported");
-  }
-  else if (num_cols == 1) {
-    piece = SMP_scalar;
-  }
-  else if (num_cols == 2) {
-    piece = SMP_vec2;
-  }
-  else if (num_cols == 3) {
-    piece = SMP_vec3;
-  }
-  else {
-    piece = SMP_vec4;
+  uint32_t array_count = 1;
+  if (const ::ShaderType::Array *array = param._type->as_array()) {
+    array_count = array->get_num_elements();
   }
 
   size_t cache_offset = cp_add_mat_part(part, arg, param._type, index, index + array_count);
-
+  bool transpose = (_language == SL_Cg);
   int dep = cp_dependency(part);
-  do_bind_parameter(param, SMF_first, piece, offset, dep, cache_offset);
+  do_bind_parameter(param, SMF_first, cache_offset, 0, transpose, offset, dep);
   return true;
 }
 
@@ -2393,41 +2345,8 @@ bind_parameter_xform(const Parameter &param,
     func = SMF_compose;
   }
 
-  ShaderMatPiece piece;
-  if (dim[1] >= 4 && dim[2] >= 3) {
-    if (dim[2] >= 4) {
-      piece = transpose ? SMP_mat4_transpose : SMP_mat4_whole;
-    } else {
-      piece = transpose ? SMP_mat4_transpose4x3 : SMP_mat4_upper4x3;
-    }
-  }
-  else if (dim[1] >= 3 && dim[2] >= 3) {
-    if (dim[2] >= 4) {
-      piece = transpose ? SMP_mat4_transpose3x4 : SMP_mat4_upper3x4;
-    } else {
-      piece = transpose ? SMP_mat4_upper3x3 : SMP_mat4_transpose3x3;
-    }
-  }
-  else if (dim[1] == 2 || dim[2] == 2) {
-    return report_parameter_error(param._name, param._type, "mat2 not supported");
-  }
-  else if (transpose) {
-    piece = SMP_mat4_column;
-    if (dim[2] != 4) {
-      return report_parameter_error(param._name, param._type, "expected mat4");
-    }
-  }
-  else if (dim[2] == 1) {
-    piece = SMP_scalar;
-  }
-  else if (dim[2] == 2) {
-    piece = SMP_vec2;
-  }
-  else if (dim[2] == 3) {
-    piece = SMP_vec3;
-  }
-  else {
-    piece = SMP_vec4;
+  if (dim[1] == 2 || (dim[1] > 1 && dim[2] == 2)) {
+    return report_parameter_error(param._name, param._type, "mat2 is not supported");
   }
 
   // More optimal combinations for common matrices.
@@ -2513,7 +2432,7 @@ bind_parameter_xform(const Parameter &param,
     dep |= cp_dependency(part1);
   }
 
-  do_bind_parameter(param, func, piece, offset, dep, cache_offset0, cache_offset1);
+  do_bind_parameter(param, func, cache_offset0, cache_offset1, transpose, offset, dep);
   return true;
 }
 
@@ -2522,61 +2441,71 @@ bind_parameter_xform(const Parameter &param,
  */
 bool Shader::
 do_bind_parameter(const Parameter &param, ShaderMatFunc func,
-                  ShaderMatPiece piece, int offset, int dep,
-                  size_t cache_offset0, size_t cache_offset1) {
-
-  // If we're compiling a Cg shader, transpose the matrices, to account for the
-  // differing matrix convention.
-  if (_language == SL_Cg) {
-    switch (piece) {
-    case SMP_mat4_whole: piece = SMP_mat4_transpose; break;
-    case SMP_mat4_transpose: piece = SMP_mat4_whole; break;
-    case SMP_mat4_upper3x3: piece = SMP_mat4_transpose3x3; break;
-    case SMP_mat4_transpose3x3: piece = SMP_mat4_upper3x3; break;
-    case SMP_mat4_upper3x4: piece = SMP_mat4_transpose3x4; break;
-    case SMP_mat4_transpose3x4: piece = SMP_mat4_upper3x4; break;
-    case SMP_mat4_upper4x3: piece = SMP_mat4_transpose4x3; break;
-    case SMP_mat4_transpose4x3: piece = SMP_mat4_upper4x3; break;
-    default: break;
-    }
-  }
+                  size_t cache_offset0, size_t cache_offset1,
+                  bool transpose, int offset, int dep) {
 
   ShaderMatSpec spec;
   spec._id = param;
   spec._func = func;
-  spec._piece = piece;
   spec._dep = dep;
   spec._cache_offset[0] = cache_offset0;
   spec._cache_offset[1] = cache_offset1;
   spec._offset = offset;
 
-  uint32_t dim[3];
-  param._type->as_scalar_type(spec._scalar_type, dim[0], dim[1], dim[2]);
-
-  spec._array_count = dim[0];
-
-  // Determine the number of elements that will be passed to the shader.
-  switch (spec._piece) {
-  case SMP_scalar: spec._num_rows = 1; spec._num_cols = 1; break;
-  case SMP_vec2: spec._num_rows = 1; spec._num_cols = 2; break;
-  case SMP_vec3: spec._num_rows = 1; spec._num_cols = 3; break;
-  case SMP_vec4: spec._num_rows = 1; spec._num_cols = 4; break;
-  case SMP_scalar_array: spec._num_rows = 1; spec._num_cols = 1; break;
-  case SMP_vec2_array: spec._num_rows = 1; spec._num_cols = 2; break;
-  case SMP_vec3_array: spec._num_rows = 1; spec._num_cols = 3; break;
-  case SMP_vec4_array: spec._num_rows = 1; spec._num_cols = 4; break;
-  case SMP_mat3_whole: spec._num_rows = 3; spec._num_cols = 3; break;
-  case SMP_mat3_array: spec._num_rows = 3; spec._num_cols = 3; break;
-  case SMP_mat4_whole: spec._num_rows = 4; spec._num_cols = 4; break;
-  case SMP_mat4_array: spec._num_rows = 4; spec._num_cols = 4; break;
-  case SMP_mat4_transpose: spec._num_rows = 4; spec._num_cols = 4; break;
-  case SMP_mat4_column: spec._num_rows = 4; spec._num_cols = 4; break;
-  case SMP_mat4_upper3x3: spec._num_rows = 4; spec._num_cols = 4; break;
-  case SMP_mat4_transpose3x3: spec._num_rows = 4; spec._num_cols = 4; break;
-  case SMP_mat4_upper3x4: spec._num_rows = 4; spec._num_cols = 4; break;
-  case SMP_mat4_transpose3x4: spec._num_rows = 4; spec._num_cols = 4; break;
-  case SMP_mat4_upper4x3: spec._num_rows = 4; spec._num_cols = 4; break;
-  case SMP_mat4_transpose4x3: spec._num_rows = 4; spec._num_cols = 4; break;
+  uint32_t array_count, num_rows, num_cols;
+  if (!param._type->as_scalar_type(spec._scalar_type, array_count, num_rows, num_cols)) {
+    return false;
+  }
+
+  spec._array_count = array_count;
+  spec._num_rows = num_rows;
+  spec._num_cols = num_cols;
+
+  if (num_rows >= 4 && num_cols >= 3) {
+    if (num_cols >= 4) {
+      spec._piece = transpose ? SMP_mat4_transpose : SMP_mat4_whole;
+    } else {
+      spec._piece = transpose ? SMP_mat4_transpose4x3 : SMP_mat4_upper4x3;
+    }
+    spec._num_rows = 4;
+    spec._num_cols = 4;
+  }
+  else if (num_rows >= 3 && num_cols >= 3) {
+    if (num_cols >= 4) {
+      spec._piece = transpose ? SMP_mat4_transpose3x4 : SMP_mat4_upper3x4;
+      spec._num_rows = 4;
+      spec._num_cols = 4;
+    }
+    else if (func == SMF_shader_input) {
+      // Not from cache, so pass whole as mat3
+      nassertr(!transpose, false);
+      spec._piece = SMP_mat3_whole;
+    }
+    else {
+      spec._piece = transpose ? SMP_mat4_transpose3x3 : SMP_mat4_upper3x3;
+      spec._num_rows = 4;
+      spec._num_cols = 4;
+    }
+  }
+  else if (num_rows == 2 || (num_rows > 1 && num_cols == 2)) {
+    return report_parameter_error(param._name, param._type, "mat2 is not supported");
+  }
+  else if (transpose) {
+    spec._piece = SMP_mat4_column;
+    spec._num_rows = 4;
+    spec._num_cols = 4;
+  }
+  else if (num_cols == 1) {
+    spec._piece = SMP_scalar;
+  }
+  else if (num_cols == 2) {
+    spec._piece = SMP_vec2;
+  }
+  else if (num_cols == 3) {
+    spec._piece = SMP_vec3;
+  }
+  else {
+    spec._piece = SMP_vec4;
   }
 
   _mat_spec.push_back(std::move(spec));
@@ -2610,9 +2539,8 @@ r_bind_struct_members(const Parameter &param, const InternalName *name,
         continue;
       }
 
-      ShaderMatPiece piece;
       int offset;
-      if (!check_light_struct_member(member.name, member.type, piece, offset)) {
+      if (!check_light_struct_member(member.name, member.type, offset)) {
         if (member.name != "shadowMatrix") {
           maybe_light_struct = false;
           break;
@@ -2665,12 +2593,10 @@ r_bind_struct_members(const Parameter &param, const InternalName *name,
         success = false;
       }
 
-      ShaderMatInput part;
-      ShaderMatPiece piece;
       int member_offset;
-      check_light_struct_member(member.name, member.type, piece, member_offset);
+      check_light_struct_member(member.name, member.type, member_offset);
 
-      if (!do_bind_parameter(member_param, SMF_first, piece, member_offset, dep, cache_offset)) {
+      if (!do_bind_parameter(member_param, SMF_first, cache_offset, 0, false, member_offset, dep)) {
         success = false;
       }
 

+ 3 - 16
panda/src/gobj/shader.h

@@ -256,14 +256,8 @@ public:
     SMP_vec2,
     SMP_vec3,
     SMP_vec4,
-    SMP_scalar_array,
-    SMP_vec2_array,
-    SMP_vec3_array,
-    SMP_vec4_array,
     SMP_mat3_whole,
-    SMP_mat3_array,
     SMP_mat4_whole,
-    SMP_mat4_array,
     SMP_mat4_transpose,
     SMP_mat4_column,
     SMP_mat4_upper3x3,
@@ -460,13 +454,6 @@ public:
     ScalarType        _scalar_type;
   };
 
-  struct ShaderPtrSpec {
-    Parameter         _id;
-    uint32_t          _dim[3]; //n_elements,rows,cols
-    CPT(InternalName) _arg;
-    ScalarType        _type;
-  };
-
   class ShaderFile : public ReferenceCount {
   public:
     INLINE ShaderFile() {};
@@ -513,7 +500,7 @@ protected:
                                 vector_string &pieces, int &next, bool fromflag,
                                 ShaderMatInput *part, CPT(InternalName) *arg);
   static bool check_light_struct_member(const std::string &name, const ::ShaderType *type,
-                                        ShaderMatPiece &piece, int &offset);
+                                        int &offset);
   int cp_dependency(ShaderMatInput inp);
   int cp_size(ShaderMatInput inp, const ::ShaderType *type);
 
@@ -614,8 +601,8 @@ public:
                             int index = 0, bool transpose = false,
                             int offset = 0);
   bool do_bind_parameter(const Parameter &parameter, ShaderMatFunc func,
-                         ShaderMatPiece piece, int offset = 0, int dep = 0,
-                         size_t cache_offset0 = 0, size_t cache_offset1 = 0);
+                         size_t cache_offset0 = 0, size_t cache_offset1 = 0,
+                         bool transpose = false, int offset = 0, int dep = 0);
   bool r_bind_struct_members(const Parameter &param, const InternalName *name,
                              const ::ShaderType::Struct *struct_type,
                              int &location, int &offset);