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

This commit is contained in:
rdb 2024-08-22 15:53:08 +02:00
parent dfc85b8a68
commit 99f4034701
8 changed files with 36 additions and 30 deletions

View File

@ -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 * 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 * matrix. In this way, we avoid the need for a separate routine to fetch
* these values. * 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:: 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; LVecBase3f v;
const LVecBase4f *cache0 = cache + spec._cache_offset[0]; const LVecBase4f *cache0 = cache + spec._cache_offset[0];
@ -941,42 +936,42 @@ fetch_specified_value(Shader::ShaderMatSpec &spec, const LVecBase4f *cache, int
return cache0; return cache0;
case Shader::SMF_compose: case Shader::SMF_compose:
spec._value.multiply(*(LMatrix4f *)cache0, *(LMatrix4f *)cache1); scratch->multiply(*(LMatrix4f *)cache0, *(LMatrix4f *)cache1);
return (LVecBase4f *)&spec._value; return (LVecBase4f *)scratch;
case Shader::SMF_transform_dlight: case Shader::SMF_transform_dlight:
spec._value = *(LMatrix4f *)cache0; *scratch = *(LMatrix4f *)cache0;
v = (*(LMatrix4f *)cache1).xform_vec(cache0[2].get_xyz()); v = (*(LMatrix4f *)cache1).xform_vec(cache0[2].get_xyz());
v.normalize(); v.normalize();
spec._value.set_row(2, v); scratch->set_row(2, v);
v = (*(LMatrix4f *)cache1).xform_vec(cache0[3].get_xyz()); v = (*(LMatrix4f *)cache1).xform_vec(cache0[3].get_xyz());
v.normalize(); v.normalize();
spec._value.set_row(3, v); scratch->set_row(3, v);
return (LVecBase4f *)&spec._value; return (LVecBase4f *)scratch;
case Shader::SMF_transform_plight: case Shader::SMF_transform_plight:
{ {
// Careful not to touch the w component, which contains the near value. // 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()); LPoint3f point = (*(LMatrix4f *)cache1).xform_point(cache0[2].get_xyz());
spec._value(2, 0) = point[0]; (*scratch)(2, 0) = point[0];
spec._value(2, 1) = point[1]; (*scratch)(2, 1) = point[1];
spec._value(2, 2) = point[2]; (*scratch)(2, 2) = point[2];
return (LVecBase4f *)&spec._value; return (LVecBase4f *)scratch;
} }
case Shader::SMF_transform_slight: case Shader::SMF_transform_slight:
spec._value = *(LMatrix4f *)cache0; *scratch = *(LMatrix4f *)cache0;
spec._value.set_row(2, (*(LMatrix4f *)cache1).xform_point(cache0[2].get_xyz())); scratch->set_row(2, (*(LMatrix4f *)cache1).xform_point(cache0[2].get_xyz()));
v = (*(LMatrix4f *)cache1).xform_vec(cache0[3].get_xyz()); v = (*(LMatrix4f *)cache1).xform_vec(cache0[3].get_xyz());
v.normalize(); v.normalize();
spec._value.set_row(3, v); scratch->set_row(3, v);
return (LVecBase4f *)&spec._value; return (LVecBase4f *)scratch;
} }
// Should never get here // Should never get here
spec._value = LMatrix4f::ident_mat(); *scratch = LMatrix4f::ident_mat();
return (LVecBase4f *)&spec._value; return (LVecBase4f *)scratch;
} }
/** /**

View File

@ -337,7 +337,7 @@ public:
virtual void clear(DrawableRegion *clearable); virtual void clear(DrawableRegion *clearable);
void update_shader_matrix_cache(Shader *shader, LVecBase4f *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); const LVecBase4f *fetch_specified_value(Shader::ShaderMatSpec &spec, const LVecBase4f *cache, LMatrix4f *scratch);
void fetch_specified_part(Shader::ShaderMatInput input, InternalName *name, void fetch_specified_part(Shader::ShaderMatInput input, InternalName *name,
LVecBase4f *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,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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