Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKévin Dietrich <kevin.dietrich@mailoo.org>2021-05-18 14:09:29 +0300
committerKévin Dietrich <kevin.dietrich@mailoo.org>2021-05-26 13:18:28 +0300
commit12a06292af8678c2371b36369a96c088f438c9dd (patch)
treeff03076123acdce53662fc3fe4f3c4f66b90a4a3 /intern/cycles/render/attribute.h
parent2a09634d4158747511de1be998052a820b173e9f (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.h33
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