diff options
author | Kévin Dietrich <kevin.dietrich@mailoo.org> | 2021-05-18 14:09:29 +0300 |
---|---|---|
committer | Kévin Dietrich <kevin.dietrich@mailoo.org> | 2021-05-26 13:18:28 +0300 |
commit | 12a06292af8678c2371b36369a96c088f438c9dd (patch) | |
tree | ff03076123acdce53662fc3fe4f3c4f66b90a4a3 /intern/cycles/render/attribute.h | |
parent | 2a09634d4158747511de1be998052a820b173e9f (diff) |
Cycles: optimize attributes device updates
When an `AttributeSet` is tagged as modified, which happens after the addition or
removal of an `Attribute` from the set, during the following GeometryManager device
update, we update and repack the kernel data for all attribute types. However, if we
only add or remove a `float` attribute, `float2` or `float3` attributes should not
be repacked for efficiency.
This patch adds some mechanisms to detect which attribute types are modified from
the AttributeSet.
Firstly, this adds an `AttrKernelDataType` to map the data type of the Attribute to
the one used in the kernel as there is no one to one match between the two since e.g.
`Transform` or `float4` data are stored as `float3s` in the kernel.
Then, this replaces the `AttributeSet.modified` boolean with a set of flags to detect
which types have been modified. There is no specific flag type (e.g.
`enum ModifiedType`), rather the flags used derive simply from the
`AttrKernelDataType` enumeration, to keep things synchronized.
The logic to remove an `Attribute` from the `AttributeSet` and tag the latter as modified
is centralized in a new `AttributeSet.remove` method taking an iterator as input.
Lastly, as some attributes like standard normals are not stored in the various
kernel attribute arrays (`DeviceScene::attribute_*`), the modified flags are only
set if the associated standard corresponds to an attribute which will be stored
in the kernel's attribute arrays. This makes it so adding or removing such attributes
does not trigger an unnecessary update of other type-related attributes.
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D11373
Diffstat (limited to 'intern/cycles/render/attribute.h')
-rw-r--r-- | intern/cycles/render/attribute.h | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/intern/cycles/render/attribute.h b/intern/cycles/render/attribute.h index 18c9e5ab83a..004c267cabc 100644 --- a/intern/cycles/render/attribute.h +++ b/intern/cycles/render/attribute.h @@ -39,6 +39,21 @@ class Hair; class Mesh; struct Transform; +/* AttrKernelDataType. + * + * The data type of the device arrays storing the attribute's data. Those data types are different + * than the ones for attributes as some attribute types are stored in the same array, e.g. Point, + * Vector, and Transform are all stored as float3 in the kernel. + * + * The values of this enumeration are also used as flags to detect changes in AttributeSet. */ + +enum AttrKernelDataType { + FLOAT = 0, + FLOAT2 = 1, + FLOAT3 = 2, + UCHAR4 = 3, +}; + /* Attribute * * Arbitrary data layers on meshes. @@ -167,6 +182,8 @@ class Attribute { static const char *standard_name(AttributeStandard std); static AttributeStandard name_standard(const char *name); + static AttrKernelDataType kernel_type(const Attribute &attr); + void get_uv_tiles(Geometry *geom, AttributePrimitive prim, unordered_set<int> &tiles) const; }; @@ -175,11 +192,12 @@ class Attribute { * Set of attributes on a mesh. */ class AttributeSet { + uint32_t modified_flag; + public: Geometry *geometry; AttributePrimitive prim; list<Attribute> attributes; - bool modified = true; AttributeSet(Geometry *geometry, AttributePrimitive prim); AttributeSet(AttributeSet &&) = default; @@ -197,6 +215,8 @@ class AttributeSet { void remove(Attribute *attribute); + void remove(list<Attribute>::iterator it); + void resize(bool reserve_only = false); void clear(bool preserve_voxel_data = false); @@ -204,7 +224,18 @@ class AttributeSet { * and remove any attribute not found on the new set from this. */ void update(AttributeSet &&new_attributes); + /* Return whether the attributes of the given kernel_type are modified, where "modified" means + * that some attributes of the given type were added or removed from this AttributeSet. This does + * not mean that the data of the remaining attributes in this AttributeSet were also modified. To + * check this, use Attribute.modified. */ + bool modified(AttrKernelDataType kernel_type) const; + void clear_modified(); + + private: + /* Set the relevant modified flag for the attribute. Only attributes that are stored in device + * arrays will be considered for tagging this AttributeSet as modified. */ + void tag_modified(const Attribute &attr); }; /* AttributeRequest |