Browse Source

shader: Don't store on ShaderMatSpec, use scratch matrix instead

rdb 1 year ago
parent
commit
99f4034701

+ 18 - 23
panda/src/display/graphicsStateGuardian.cxx

@@ -923,14 +923,9 @@ update_shader_matrix_cache(Shader *shader, LVecBase4f *cache, int altered) {
  * This routine can fetch these values as well, by shoehorning them into a
  * matrix.  In this way, we avoid the need for a separate routine to fetch
  * these values.
- *
- * The "altered" bits indicate what parts of the state_and_transform have
- * changed since the last time this particular ShaderMatSpec was evaluated.
- * This may allow data to be cached and not reevaluated.
- *
  */
 const LVecBase4f *GraphicsStateGuardian::
-fetch_specified_value(Shader::ShaderMatSpec &spec, const LVecBase4f *cache, int altered) {
+fetch_specified_value(Shader::ShaderMatSpec &spec, const LVecBase4f *cache, LMatrix4f *scratch) {
   LVecBase3f v;
 
   const LVecBase4f *cache0 = cache + spec._cache_offset[0];
@@ -941,42 +936,42 @@ fetch_specified_value(Shader::ShaderMatSpec &spec, const LVecBase4f *cache, int
     return cache0;
 
   case Shader::SMF_compose:
-    spec._value.multiply(*(LMatrix4f *)cache0, *(LMatrix4f *)cache1);
-    return (LVecBase4f *)&spec._value;
+    scratch->multiply(*(LMatrix4f *)cache0, *(LMatrix4f *)cache1);
+    return (LVecBase4f *)scratch;
 
   case Shader::SMF_transform_dlight:
-    spec._value = *(LMatrix4f *)cache0;
+    *scratch = *(LMatrix4f *)cache0;
     v = (*(LMatrix4f *)cache1).xform_vec(cache0[2].get_xyz());
     v.normalize();
-    spec._value.set_row(2, v);
+    scratch->set_row(2, v);
     v = (*(LMatrix4f *)cache1).xform_vec(cache0[3].get_xyz());
     v.normalize();
-    spec._value.set_row(3, v);
-    return (LVecBase4f *)&spec._value;
+    scratch->set_row(3, v);
+    return (LVecBase4f *)scratch;
 
   case Shader::SMF_transform_plight:
     {
       // Careful not to touch the w component, which contains the near value.
-      spec._value = *(LMatrix4f *)cache0;
+      *scratch = *(LMatrix4f *)cache0;
       LPoint3f point = (*(LMatrix4f *)cache1).xform_point(cache0[2].get_xyz());
-      spec._value(2, 0) = point[0];
-      spec._value(2, 1) = point[1];
-      spec._value(2, 2) = point[2];
-      return (LVecBase4f *)&spec._value;
+      (*scratch)(2, 0) = point[0];
+      (*scratch)(2, 1) = point[1];
+      (*scratch)(2, 2) = point[2];
+      return (LVecBase4f *)scratch;
     }
 
   case Shader::SMF_transform_slight:
-    spec._value = *(LMatrix4f *)cache0;
-    spec._value.set_row(2, (*(LMatrix4f *)cache1).xform_point(cache0[2].get_xyz()));
+    *scratch = *(LMatrix4f *)cache0;
+    scratch->set_row(2, (*(LMatrix4f *)cache1).xform_point(cache0[2].get_xyz()));
     v = (*(LMatrix4f *)cache1).xform_vec(cache0[3].get_xyz());
     v.normalize();
-    spec._value.set_row(3, v);
-    return (LVecBase4f *)&spec._value;
+    scratch->set_row(3, v);
+    return (LVecBase4f *)scratch;
   }
 
   // Should never get here
-  spec._value = LMatrix4f::ident_mat();
-  return (LVecBase4f *)&spec._value;
+  *scratch = LMatrix4f::ident_mat();
+  return (LVecBase4f *)scratch;
 }
 
 /**

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

@@ -337,7 +337,7 @@ public:
   virtual void clear(DrawableRegion *clearable);
 
   void update_shader_matrix_cache(Shader *shader, LVecBase4f *cache, int altered);
-  const LVecBase4f *fetch_specified_value(Shader::ShaderMatSpec &spec, const LVecBase4f *cache, int altered);
+  const LVecBase4f *fetch_specified_value(Shader::ShaderMatSpec &spec, const LVecBase4f *cache, LMatrix4f *scratch);
   void fetch_specified_part(Shader::ShaderMatInput input, InternalName *name,
                             LVecBase4f *into, int count = 1);
   void fetch_specified_member(const NodePath &np, CPT_InternalName member,

+ 5 - 1
panda/src/dxgsg9/dxShaderContext9.cxx

@@ -76,6 +76,7 @@ DXShaderContext9(Shader *s, GSG *gsg) : ShaderContext(s) {
 #endif
 
   _mat_part_cache = new LVecBase4f[s->cp_get_mat_cache_size()];
+  _mat_scratch_space = new LVecBase4f[_shader->cp_get_mat_scratch_size()];
 }
 
 /**
@@ -96,6 +97,7 @@ DXShaderContext9::
   }
 
   delete[] _mat_part_cache;
+  delete[] _mat_scratch_space;
 }
 
 /**
@@ -231,6 +233,8 @@ issue_parameters(GSG *gsg, int altered) {
     if (altered & _shader->_mat_deps) {
       gsg->update_shader_matrix_cache(_shader, _mat_part_cache, altered);
 
+      LMatrix4f scratch;
+
       for (Shader::ShaderMatSpec &spec : _shader->_mat_spec) {
         if ((altered & spec._dep) == 0) {
           continue;
@@ -241,7 +245,7 @@ issue_parameters(GSG *gsg, int altered) {
           continue;
         }
 
-        const LVecBase4f *val = gsg->fetch_specified_value(spec, _mat_part_cache, altered);
+        const LVecBase4f *val = gsg->fetch_specified_value(spec, _mat_part_cache, _mat_scratch_space);
         if (val) {
           const float *data = (const float *)val + spec._offset;
           LVecBase4f v;

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

@@ -88,6 +88,7 @@ private:
 #endif
 
   LVecBase4f *_mat_part_cache = nullptr;
+  LVecBase4f *_mat_scratch_space = nullptr;
 
 private:
   void release_resources(void);

+ 5 - 1
panda/src/glstuff/glCgShaderContext_src.cxx

@@ -330,6 +330,7 @@ CLP(CgShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderConte
   }
 
   _mat_part_cache = new LVecBase4f[_shader->cp_get_mat_cache_size()];
+  _mat_scratch_space = new LVecBase4f[_shader->cp_get_mat_scratch_size()];
 
   _glgsg->report_my_gl_errors();
 }
@@ -341,6 +342,7 @@ CLP(CgShaderContext)::
 ~CLP(CgShaderContext)() {
   // Don't call release_resources; we may not have an active context.
   delete[] _mat_part_cache;
+  delete[] _mat_scratch_space;
 }
 
 /**
@@ -694,12 +696,14 @@ issue_parameters(int altered) {
   if (altered & _shader->_mat_deps) {
     _glgsg->update_shader_matrix_cache(_shader, _mat_part_cache, altered);
 
+    LMatrix4f scratch;
+
     for (Shader::ShaderMatSpec &spec : _shader->_mat_spec) {
       if ((altered & spec._dep) == 0) {
         continue;
       }
 
-      const LVecBase4f *val = _glgsg->fetch_specified_value(spec, _mat_part_cache, altered);
+      const LVecBase4f *val = _glgsg->fetch_specified_value(spec, _mat_part_cache, _mat_scratch_space);
       if (!val) continue;
       const float *data = val->get_data();
       data += spec._offset;

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

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

+ 3 - 1
panda/src/glstuff/glShaderContext_src.cxx

@@ -2299,12 +2299,14 @@ issue_parameters(int altered) {
   if (altered & _shader->_mat_deps) {
     _glgsg->update_shader_matrix_cache(_shader, _mat_part_cache, altered);
 
+    LMatrix4f scratch;
+
     for (Shader::ShaderMatSpec &spec : _shader->_mat_spec) {
       if ((altered & spec._dep) == 0) {
         continue;
       }
 
-      const LVecBase4f *val = _glgsg->fetch_specified_value(spec, _mat_part_cache, altered);
+      const LVecBase4f *val = _glgsg->fetch_specified_value(spec, _mat_part_cache, &scratch);
       if (!val) continue;
       const float *data = val->get_data();
       data += spec._offset;

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

@@ -33,7 +33,7 @@
 #include "pta_LVecBase3.h"
 #include "pta_LVecBase2.h"
 #include "pStatCollector.h"
-#include "epvector.h"
+#include "pvector.h"
 #include "asyncFuture.h"
 #include "bamCacheRecord.h"
 
@@ -438,7 +438,6 @@ public:
     ShaderMatFunc     _func;
     ShaderMatInput    _part[2];
     PT(InternalName)  _arg[2];
-    LMatrix4f         _value;
     int               _dep = SSD_NONE;
     int               _index = 0;
     ShaderMatPiece    _piece;
@@ -608,7 +607,7 @@ public:
 
 public:
   pvector<ShaderPtrSpec> _ptr_spec;
-  epvector<ShaderMatSpec> _mat_spec;
+  pvector<ShaderMatSpec> _mat_spec;
   pvector<ShaderTexSpec> _tex_spec;
   pvector<ShaderVarSpec> _var_spec;
   pvector<ShaderMatPart> _mat_parts;