Fix MaterialParams sync bug

This commit is contained in:
Wojtek Figat
2021-02-21 17:40:37 +01:00
parent 279d168b35
commit 1ead4b1649
3 changed files with 82 additions and 75 deletions

View File

@@ -23,17 +23,25 @@ void MaterialInstance::OnBaseSet()
_baseMaterial->OnUnloaded.Bind<MaterialInstance, &MaterialInstance::OnBaseUnloaded>(this); _baseMaterial->OnUnloaded.Bind<MaterialInstance, &MaterialInstance::OnBaseUnloaded>(this);
_baseMaterial->ParamsChanged.Bind<MaterialInstance, &MaterialInstance::OnBaseParamsChanged>(this); _baseMaterial->ParamsChanged.Bind<MaterialInstance, &MaterialInstance::OnBaseParamsChanged>(this);
// Sync parameters with the base parameters to ensure all data is valid for rendering (constants offset and resource register)
MaterialParams& baseParams = _baseMaterial->Params; MaterialParams& baseParams = _baseMaterial->Params;
bool validParams = Params.Count() == baseParams.Count(); Params._versionHash = 0;
for (int32 i = 0; validParams && i < Params.Count(); i++) if (Params.Count() != baseParams.Count())
{
// Params changed
OnBaseParamsChanged();
return;
}
for (int32 i = 0; i < Params.Count(); i++)
{ {
MaterialParameter& param = Params[i]; MaterialParameter& param = Params[i];
MaterialParameter& baseParam = baseParams[i]; MaterialParameter& baseParam = baseParams[i];
if (param.GetID() != baseParam.GetID() || param.GetParameterType() != baseParam.GetParameterType()) if (param.GetID() != baseParam.GetID() || param.GetParameterType() != baseParam.GetParameterType())
{ {
validParams = false; // Params changed
break; OnBaseParamsChanged();
return;
} }
param._isPublic = baseParam._isPublic; param._isPublic = baseParam._isPublic;
@@ -41,21 +49,14 @@ void MaterialInstance::OnBaseSet()
param._offset = baseParam._offset; param._offset = baseParam._offset;
param._name = baseParam._name; param._name = baseParam._name;
} }
if (validParams)
{ // Params are valid
Params._versionHash = baseParams._versionHash; Params._versionHash = baseParams._versionHash;
ParamsChanged(); ParamsChanged();
}
else
{
OnBaseParamsChanged();
}
} }
void MaterialInstance::OnBaseUnset() void MaterialInstance::OnBaseUnset()
{ {
ScopeLock lock(_baseMaterial->Locker);
_baseMaterial->RemoveReference(); _baseMaterial->RemoveReference();
_baseMaterial->OnUnloaded.Unbind<MaterialInstance, &MaterialInstance::OnBaseUnloaded>(this); _baseMaterial->OnUnloaded.Unbind<MaterialInstance, &MaterialInstance::OnBaseUnloaded>(this);
_baseMaterial->ParamsChanged.Unbind<MaterialInstance, &MaterialInstance::OnBaseParamsChanged>(this); _baseMaterial->ParamsChanged.Unbind<MaterialInstance, &MaterialInstance::OnBaseParamsChanged>(this);

View File

@@ -440,6 +440,67 @@ String MaterialParameter::ToString() const
return String::Format(TEXT("\'{0}\' ({1}:{2}:{3})"), _name, ::ToString(_type), _paramId, _isPublic); return String::Format(TEXT("\'{0}\' ({1}:{2}:{3})"), _name, ::ToString(_type), _paramId, _isPublic);
} }
MaterialParameter* MaterialParams::Get(const Guid& id)
{
MaterialParameter* result = nullptr;
for (int32 i = 0; i < Count(); i++)
{
if (At(i).GetParameterID() == id)
{
result = &At(i);
break;
}
}
return result;
}
MaterialParameter* MaterialParams::Get(const StringView& name)
{
MaterialParameter* result = nullptr;
for (int32 i = 0; i < Count(); i++)
{
if (At(i).GetName() == name)
{
result = &At(i);
break;
}
}
return result;
}
int32 MaterialParams::Find(const Guid& id)
{
int32 result = -1;
for (int32 i = 0; i < Count(); i++)
{
if (At(i).GetParameterID() == id)
{
result = i;
break;
}
}
return result;
}
int32 MaterialParams::Find(const StringView& name)
{
int32 result = -1;
for (int32 i = 0; i < Count(); i++)
{
if (At(i).GetName() == name)
{
result = i;
break;
}
}
return result;
}
int32 MaterialParams::GetVersionHash() const
{
return _versionHash;
}
void MaterialParams::Bind(MaterialParamsLink* link, MaterialParameter::BindMeta& meta) void MaterialParams::Bind(MaterialParamsLink* link, MaterialParameter::BindMeta& meta)
{ {
ASSERT(link && link->This); ASSERT(link && link->This);

View File

@@ -366,72 +366,17 @@ private:
public: public:
MaterialParameter* Get(const Guid& id) MaterialParameter* Get(const Guid& id);
{ MaterialParameter* Get(const StringView& name);
MaterialParameter* result = nullptr; int32 Find(const Guid& id);
for (int32 i = 0; i < Count(); i++) int32 Find(const StringView& name);
{
if (At(i).GetParameterID() == id)
{
result = &At(i);
break;
}
}
return result;
}
MaterialParameter* Get(const StringView& name)
{
MaterialParameter* result = nullptr;
for (int32 i = 0; i < Count(); i++)
{
if (At(i).GetName() == name)
{
result = &At(i);
break;
}
}
return result;
}
int32 Find(const Guid& id)
{
int32 result = -1;
for (int32 i = 0; i < Count(); i++)
{
if (At(i).GetParameterID() == id)
{
result = i;
break;
}
}
return result;
}
int32 Find(const StringView& name)
{
int32 result = -1;
for (int32 i = 0; i < Count(); i++)
{
if (At(i).GetName() == name)
{
result = i;
break;
}
}
return result;
}
public: public:
/// <summary> /// <summary>
/// Gets the parameters version hash. Every time the parameters are modified (loaded, edited, etc.) the hash changes. Can be used to sync instanced parameters collection. /// Gets the parameters version hash. Every time the parameters are modified (loaded, edited, etc.) the hash changes. Can be used to sync instanced parameters collection.
/// </summary> /// </summary>
/// <returns>The hash.</returns> int32 GetVersionHash() const;
FORCE_INLINE int32 GetVersionHash() const
{
return _versionHash;
}
public: public: