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:
authorPatrick Mours <pmours@nvidia.com>2022-09-09 12:55:35 +0300
committerPatrick Mours <pmours@nvidia.com>2022-09-09 16:35:44 +0300
commitef7c9e793ec5331ac694eec9336565bd2254c406 (patch)
treeca30908bae0bac8c58d18b964af7dc388f9de463
parent291c313f80b4cccc8fcce3035584caeaa654844f (diff)
Cycles: Remove separate OSL attribute map and instead always use SVM attribute map
The SVM attribute map is always generated and uses a simple linear search to lookup by an opaque ID, so can reuse that for OSL as well and simply use the attribute name hash as ID instead of generating a unique value separately. This works for both object and geometry attributes since the SVM attribute map already stores both. Simplifies code somewhat and reduces memory usage slightly. This patch was split from D15902. Differential Revision: https://developer.blender.org/D15918
-rw-r--r--intern/cycles/kernel/geom/attribute.h32
-rw-r--r--intern/cycles/kernel/geom/primitive.h10
-rw-r--r--intern/cycles/kernel/geom/subd_triangle.h8
-rw-r--r--intern/cycles/kernel/geom/volume.h2
-rw-r--r--intern/cycles/kernel/osl/globals.h8
-rw-r--r--intern/cycles/kernel/osl/services.cpp160
-rw-r--r--intern/cycles/kernel/osl/shader.cpp38
-rw-r--r--intern/cycles/kernel/osl/shader.h6
-rw-r--r--intern/cycles/kernel/types.h11
-rw-r--r--intern/cycles/scene/geometry.cpp152
-rw-r--r--intern/cycles/scene/geometry.h4
-rw-r--r--intern/cycles/scene/osl.cpp12
-rw-r--r--intern/cycles/scene/osl.h3
-rw-r--r--intern/cycles/scene/shader.cpp8
-rw-r--r--intern/cycles/scene/shader.h6
15 files changed, 155 insertions, 305 deletions
diff --git a/intern/cycles/kernel/geom/attribute.h b/intern/cycles/kernel/geom/attribute.h
index 31a9e39d528..3a0ee1b09d1 100644
--- a/intern/cycles/kernel/geom/attribute.h
+++ b/intern/cycles/kernel/geom/attribute.h
@@ -16,14 +16,14 @@ CCL_NAMESPACE_BEGIN
/* Patch index for triangle, -1 if not subdivision triangle */
-ccl_device_inline uint subd_triangle_patch(KernelGlobals kg, ccl_private const ShaderData *sd)
+ccl_device_inline uint subd_triangle_patch(KernelGlobals kg, int prim)
{
- return (sd->prim != PRIM_NONE) ? kernel_data_fetch(tri_patch, sd->prim) : ~0;
+ return (prim != PRIM_NONE) ? kernel_data_fetch(tri_patch, prim) : ~0;
}
-ccl_device_inline uint attribute_primitive_type(KernelGlobals kg, ccl_private const ShaderData *sd)
+ccl_device_inline uint attribute_primitive_type(KernelGlobals kg, int prim, int type)
{
- if ((sd->type & PRIMITIVE_TRIANGLE) && subd_triangle_patch(kg, sd) != ~0) {
+ if ((type & PRIMITIVE_TRIANGLE) && subd_triangle_patch(kg, prim) != ~0) {
return ATTR_PRIM_SUBD;
}
else {
@@ -45,17 +45,16 @@ ccl_device_inline uint object_attribute_map_offset(KernelGlobals kg, int object)
return kernel_data_fetch(objects, object).attribute_map_offset;
}
-ccl_device_inline AttributeDescriptor find_attribute(KernelGlobals kg,
- ccl_private const ShaderData *sd,
- uint id)
+ccl_device_inline AttributeDescriptor
+find_attribute(KernelGlobals kg, int object, int prim, int type, uint64_t id)
{
- if (sd->object == OBJECT_NONE) {
+ if (object == OBJECT_NONE) {
return attribute_not_found();
}
/* for SVM, find attribute by unique id */
- uint attr_offset = object_attribute_map_offset(kg, sd->object);
- attr_offset += attribute_primitive_type(kg, sd);
+ uint attr_offset = object_attribute_map_offset(kg, object);
+ attr_offset += attribute_primitive_type(kg, prim, type);
AttributeMap attr_map = kernel_data_fetch(attributes_map, attr_offset);
while (attr_map.id != id) {
@@ -77,7 +76,7 @@ ccl_device_inline AttributeDescriptor find_attribute(KernelGlobals kg,
AttributeDescriptor desc;
desc.element = (AttributeElement)attr_map.element;
- if (sd->prim == PRIM_NONE && desc.element != ATTR_ELEMENT_MESH &&
+ if (prim == PRIM_NONE && desc.element != ATTR_ELEMENT_MESH &&
desc.element != ATTR_ELEMENT_VOXEL && desc.element != ATTR_ELEMENT_OBJECT) {
return attribute_not_found();
}
@@ -91,11 +90,16 @@ ccl_device_inline AttributeDescriptor find_attribute(KernelGlobals kg,
return desc;
}
+ccl_device_inline AttributeDescriptor find_attribute(KernelGlobals kg,
+ ccl_private const ShaderData *sd,
+ uint64_t id)
+{
+ return find_attribute(kg, sd->object, sd->prim, sd->type, id);
+}
+
/* Transform matrix attribute on meshes */
-ccl_device Transform primitive_attribute_matrix(KernelGlobals kg,
- ccl_private const ShaderData *sd,
- const AttributeDescriptor desc)
+ccl_device Transform primitive_attribute_matrix(KernelGlobals kg, const AttributeDescriptor desc)
{
Transform tfm;
diff --git a/intern/cycles/kernel/geom/primitive.h b/intern/cycles/kernel/geom/primitive.h
index 0f1a3fc11bc..04b04ff5985 100644
--- a/intern/cycles/kernel/geom/primitive.h
+++ b/intern/cycles/kernel/geom/primitive.h
@@ -25,7 +25,7 @@ ccl_device_forceinline float primitive_surface_attribute_float(KernelGlobals kg,
ccl_private float *dy)
{
if (sd->type & PRIMITIVE_TRIANGLE) {
- if (subd_triangle_patch(kg, sd) == ~0)
+ if (subd_triangle_patch(kg, sd->prim) == ~0)
return triangle_attribute_float(kg, sd, desc, dx, dy);
else
return subd_triangle_attribute_float(kg, sd, desc, dx, dy);
@@ -56,7 +56,7 @@ ccl_device_forceinline float2 primitive_surface_attribute_float2(KernelGlobals k
ccl_private float2 *dy)
{
if (sd->type & PRIMITIVE_TRIANGLE) {
- if (subd_triangle_patch(kg, sd) == ~0)
+ if (subd_triangle_patch(kg, sd->prim) == ~0)
return triangle_attribute_float2(kg, sd, desc, dx, dy);
else
return subd_triangle_attribute_float2(kg, sd, desc, dx, dy);
@@ -87,7 +87,7 @@ ccl_device_forceinline float3 primitive_surface_attribute_float3(KernelGlobals k
ccl_private float3 *dy)
{
if (sd->type & PRIMITIVE_TRIANGLE) {
- if (subd_triangle_patch(kg, sd) == ~0)
+ if (subd_triangle_patch(kg, sd->prim) == ~0)
return triangle_attribute_float3(kg, sd, desc, dx, dy);
else
return subd_triangle_attribute_float3(kg, sd, desc, dx, dy);
@@ -118,7 +118,7 @@ ccl_device_forceinline float4 primitive_surface_attribute_float4(KernelGlobals k
ccl_private float4 *dy)
{
if (sd->type & PRIMITIVE_TRIANGLE) {
- if (subd_triangle_patch(kg, sd) == ~0)
+ if (subd_triangle_patch(kg, sd->prim) == ~0)
return triangle_attribute_float4(kg, sd, desc, dx, dy);
else
return subd_triangle_attribute_float4(kg, sd, desc, dx, dy);
@@ -320,7 +320,7 @@ ccl_device_forceinline float4 primitive_motion_vector(KernelGlobals kg,
#endif
if (sd->type & PRIMITIVE_TRIANGLE) {
/* Triangle */
- if (subd_triangle_patch(kg, sd) == ~0) {
+ if (subd_triangle_patch(kg, sd->prim) == ~0) {
motion_pre = triangle_attribute_float3(kg, sd, desc, NULL, NULL);
desc.offset += numverts;
motion_post = triangle_attribute_float3(kg, sd, desc, NULL, NULL);
diff --git a/intern/cycles/kernel/geom/subd_triangle.h b/intern/cycles/kernel/geom/subd_triangle.h
index c6f883461bd..784ba377318 100644
--- a/intern/cycles/kernel/geom/subd_triangle.h
+++ b/intern/cycles/kernel/geom/subd_triangle.h
@@ -87,7 +87,7 @@ ccl_device_noinline float subd_triangle_attribute_float(KernelGlobals kg,
ccl_private float *dx,
ccl_private float *dy)
{
- int patch = subd_triangle_patch(kg, sd);
+ int patch = subd_triangle_patch(kg, sd->prim);
#ifdef __PATCH_EVAL__
if (desc.flags & ATTR_SUBDIVIDED) {
@@ -226,7 +226,7 @@ ccl_device_noinline float2 subd_triangle_attribute_float2(KernelGlobals kg,
ccl_private float2 *dx,
ccl_private float2 *dy)
{
- int patch = subd_triangle_patch(kg, sd);
+ int patch = subd_triangle_patch(kg, sd->prim);
#ifdef __PATCH_EVAL__
if (desc.flags & ATTR_SUBDIVIDED) {
@@ -368,7 +368,7 @@ ccl_device_noinline float3 subd_triangle_attribute_float3(KernelGlobals kg,
ccl_private float3 *dx,
ccl_private float3 *dy)
{
- int patch = subd_triangle_patch(kg, sd);
+ int patch = subd_triangle_patch(kg, sd->prim);
#ifdef __PATCH_EVAL__
if (desc.flags & ATTR_SUBDIVIDED) {
@@ -509,7 +509,7 @@ ccl_device_noinline float4 subd_triangle_attribute_float4(KernelGlobals kg,
ccl_private float4 *dx,
ccl_private float4 *dy)
{
- int patch = subd_triangle_patch(kg, sd);
+ int patch = subd_triangle_patch(kg, sd->prim);
#ifdef __PATCH_EVAL__
if (desc.flags & ATTR_SUBDIVIDED) {
diff --git a/intern/cycles/kernel/geom/volume.h b/intern/cycles/kernel/geom/volume.h
index 3510a905def..885a420c97f 100644
--- a/intern/cycles/kernel/geom/volume.h
+++ b/intern/cycles/kernel/geom/volume.h
@@ -29,7 +29,7 @@ ccl_device_inline float3 volume_normalized_position(KernelGlobals kg,
object_inverse_position_transform(kg, sd, &P);
if (desc.offset != ATTR_STD_NOT_FOUND) {
- Transform tfm = primitive_attribute_matrix(kg, sd, desc);
+ Transform tfm = primitive_attribute_matrix(kg, desc);
P = transform_point(&tfm, P);
}
diff --git a/intern/cycles/kernel/osl/globals.h b/intern/cycles/kernel/osl/globals.h
index 172091c55f5..496965a50ec 100644
--- a/intern/cycles/kernel/osl/globals.h
+++ b/intern/cycles/kernel/osl/globals.h
@@ -56,16 +56,8 @@ struct OSLGlobals {
OSL::ShaderGroupRef background_state;
/* attributes */
- struct Attribute {
- TypeDesc type;
- AttributeDescriptor desc;
- ParamValue value;
- };
-
- typedef unordered_map<ustring, Attribute, ustringHash> AttributeMap;
typedef unordered_map<ustring, int, ustringHash> ObjectNameMap;
- vector<AttributeMap> attribute_map;
ObjectNameMap object_name_map;
vector<ustring> object_names;
};
diff --git a/intern/cycles/kernel/osl/services.cpp b/intern/cycles/kernel/osl/services.cpp
index faa027f4e1e..eef661c203e 100644
--- a/intern/cycles/kernel/osl/services.cpp
+++ b/intern/cycles/kernel/osl/services.cpp
@@ -740,76 +740,75 @@ static bool set_attribute_matrix(const Transform &tfm, TypeDesc type, void *val)
return false;
}
-static bool get_primitive_attribute(const KernelGlobalsCPU *kg,
- const ShaderData *sd,
- const OSLGlobals::Attribute &attr,
- const TypeDesc &type,
- bool derivatives,
- void *val)
+static bool get_object_attribute(const KernelGlobalsCPU *kg,
+ ShaderData *sd,
+ const AttributeDescriptor &desc,
+ const TypeDesc &type,
+ bool derivatives,
+ void *val)
{
- if (attr.type == TypeDesc::TypePoint || attr.type == TypeDesc::TypeVector ||
- attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor) {
+ if (desc.type == NODE_ATTR_FLOAT3) {
float3 fval[3];
- if (primitive_is_volume_attribute(sd, attr.desc)) {
- fval[0] = primitive_volume_attribute_float3(kg, sd, attr.desc);
+#ifdef __VOLUME__
+ if (primitive_is_volume_attribute(sd, desc)) {
+ fval[0] = primitive_volume_attribute_float3(kg, sd, desc);
}
- else {
+ else
+#endif
+ {
memset(fval, 0, sizeof(fval));
fval[0] = primitive_surface_attribute_float3(
- kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
+ kg, sd, desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
}
return set_attribute_float3(fval, type, derivatives, val);
}
- else if (attr.type == TypeFloat2) {
- if (primitive_is_volume_attribute(sd, attr.desc)) {
+ else if (desc.type == NODE_ATTR_FLOAT2) {
+#ifdef __VOLUME__
+ if (primitive_is_volume_attribute(sd, desc)) {
assert(!"Float2 attribute not support for volumes");
return false;
}
- else {
+ else
+#endif
+ {
float2 fval[3];
fval[0] = primitive_surface_attribute_float2(
- kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
+ kg, sd, desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
return set_attribute_float2(fval, type, derivatives, val);
}
}
- else if (attr.type == TypeDesc::TypeFloat) {
+ else if (desc.type == NODE_ATTR_FLOAT) {
float fval[3];
- if (primitive_is_volume_attribute(sd, attr.desc)) {
+#ifdef __VOLUME__
+ if (primitive_is_volume_attribute(sd, desc)) {
memset(fval, 0, sizeof(fval));
- fval[0] = primitive_volume_attribute_float(kg, sd, attr.desc);
+ fval[0] = primitive_volume_attribute_float(kg, sd, desc);
}
- else {
+ else
+#endif
+ {
fval[0] = primitive_surface_attribute_float(
- kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
+ kg, sd, desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
}
return set_attribute_float(fval, type, derivatives, val);
}
- else if (attr.type == TypeDesc::TypeFloat4 || attr.type == TypeRGBA) {
+ else if (desc.type == NODE_ATTR_FLOAT4 || desc.type == NODE_ATTR_RGBA) {
float4 fval[3];
- if (primitive_is_volume_attribute(sd, attr.desc)) {
+#ifdef __VOLUME__
+ if (primitive_is_volume_attribute(sd, desc)) {
memset(fval, 0, sizeof(fval));
- fval[0] = primitive_volume_attribute_float4(kg, sd, attr.desc);
+ fval[0] = primitive_volume_attribute_float4(kg, sd, desc);
}
- else {
+ else
+#endif
+ {
fval[0] = primitive_surface_attribute_float4(
- kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
+ kg, sd, desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
}
return set_attribute_float4(fval, type, derivatives, val);
}
- else {
- return false;
- }
-}
-
-static bool get_mesh_attribute(const KernelGlobalsCPU *kg,
- const ShaderData *sd,
- const OSLGlobals::Attribute &attr,
- const TypeDesc &type,
- bool derivatives,
- void *val)
-{
- if (attr.type == TypeDesc::TypeMatrix) {
- Transform tfm = primitive_attribute_matrix(kg, sd, attr.desc);
+ else if (desc.type == NODE_ATTR_MATRIX) {
+ Transform tfm = primitive_attribute_matrix(kg, desc);
return set_attribute_matrix(tfm, type, val);
}
else {
@@ -817,44 +816,6 @@ static bool get_mesh_attribute(const KernelGlobalsCPU *kg,
}
}
-static bool get_object_attribute(const OSLGlobals::Attribute &attr,
- TypeDesc type,
- bool derivatives,
- void *val)
-{
- if (attr.type == TypeDesc::TypePoint || attr.type == TypeDesc::TypeVector ||
- attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor) {
- const float *data = (const float *)attr.value.data();
- return set_attribute_float3(make_float3(data[0], data[1], data[2]), type, derivatives, val);
- }
- else if (attr.type == TypeFloat2) {
- const float *data = (const float *)attr.value.data();
- return set_attribute_float2(make_float2(data[0], data[1]), type, derivatives, val);
- }
- else if (attr.type == TypeDesc::TypeFloat) {
- const float *data = (const float *)attr.value.data();
- return set_attribute_float(data[0], type, derivatives, val);
- }
- else if (attr.type == TypeRGBA || attr.type == TypeDesc::TypeFloat4) {
- const float *data = (const float *)attr.value.data();
- return set_attribute_float4(
- make_float4(data[0], data[1], data[2], data[3]), type, derivatives, val);
- }
- else if (attr.type == type) {
- size_t datasize = attr.value.datasize();
-
- memcpy(val, attr.value.data(), datasize);
- if (derivatives) {
- memset((char *)val + datasize, 0, datasize * 2);
- }
-
- return true;
- }
- else {
- return false;
- }
-}
-
bool OSLRenderServices::get_object_standard_attribute(const KernelGlobalsCPU *kg,
ShaderData *sd,
ustring name,
@@ -979,6 +940,7 @@ bool OSLRenderServices::get_object_standard_attribute(const KernelGlobalsCPU *kg
float f = ((sd->shader & SHADER_SMOOTH_NORMAL) != 0);
return set_attribute_float(f, type, derivatives, val);
}
+#ifdef __HAIR__
/* Hair Attributes */
else if (name == u_is_curve) {
float f = (sd->type & PRIMITIVE_CURVE) != 0;
@@ -996,6 +958,8 @@ bool OSLRenderServices::get_object_standard_attribute(const KernelGlobalsCPU *kg
float f = curve_random(kg, sd);
return set_attribute_float(f, type, derivatives, val);
}
+#endif
+#ifdef __POINTCLOUD__
/* point attributes */
else if (name == u_is_point) {
float f = (sd->type & PRIMITIVE_POINT) != 0;
@@ -1013,6 +977,7 @@ bool OSLRenderServices::get_object_standard_attribute(const KernelGlobalsCPU *kg
float f = point_random(kg, sd);
return set_attribute_float(f, type, derivatives, val);
}
+#endif
else if (name == u_normal_map_normal) {
if (sd->type & PRIMITIVE_TRIANGLE) {
float3 f = triangle_smooth_normal_unnormalized(kg, sd, sd->Ng, sd->prim, sd->u, sd->v);
@@ -1023,7 +988,7 @@ bool OSLRenderServices::get_object_standard_attribute(const KernelGlobalsCPU *kg
}
}
else {
- return false;
+ return get_background_attribute(kg, sd, name, type, derivatives, val);
}
}
@@ -1131,7 +1096,6 @@ bool OSLRenderServices::get_attribute(
ShaderData *sd, bool derivatives, ustring object_name, TypeDesc type, ustring name, void *val)
{
const KernelGlobalsCPU *kg = sd->osl_globals;
- int prim_type = 0;
int object;
/* lookup of attribute on another object */
@@ -1145,44 +1109,18 @@ bool OSLRenderServices::get_attribute(
}
else {
object = sd->object;
- prim_type = attribute_primitive_type(kg, sd);
-
- if (object == OBJECT_NONE)
- return get_background_attribute(kg, sd, name, type, derivatives, val);
}
/* find attribute on object */
- object = object * ATTR_PRIM_TYPES + prim_type;
- OSLGlobals::AttributeMap &attribute_map = kg->osl->attribute_map[object];
- OSLGlobals::AttributeMap::iterator it = attribute_map.find(name);
-
- if (it != attribute_map.end()) {
- const OSLGlobals::Attribute &attr = it->second;
-
- if (attr.desc.element != ATTR_ELEMENT_OBJECT) {
- /* triangle and vertex attributes */
- if (get_primitive_attribute(kg, sd, attr, type, derivatives, val))
- return true;
- else
- return get_mesh_attribute(kg, sd, attr, type, derivatives, val);
- }
- else {
- /* object attribute */
- return get_object_attribute(attr, type, derivatives, val);
- }
+ const AttributeDescriptor desc = find_attribute(
+ kg, object, sd->prim, object == sd->object ? sd->type : PRIMITIVE_NONE, name.hash());
+ if (desc.offset != ATTR_STD_NOT_FOUND) {
+ return get_object_attribute(kg, sd, desc, type, derivatives, val);
}
else {
/* not found in attribute, check standard object info */
- bool is_std_object_attribute = get_object_standard_attribute(
- kg, sd, name, type, derivatives, val);
-
- if (is_std_object_attribute)
- return true;
-
- return get_background_attribute(kg, sd, name, type, derivatives, val);
+ return get_object_standard_attribute(kg, sd, name, type, derivatives, val);
}
-
- return false;
}
bool OSLRenderServices::get_userdata(
diff --git a/intern/cycles/kernel/osl/shader.cpp b/intern/cycles/kernel/osl/shader.cpp
index 5862b6a8a2b..3355f5c869a 100644
--- a/intern/cycles/kernel/osl/shader.cpp
+++ b/intern/cycles/kernel/osl/shader.cpp
@@ -21,8 +21,6 @@
#include "kernel/util/differential.h"
// clang-format on
-#include "scene/attribute.h"
-
CCL_NAMESPACE_BEGIN
/* Threads */
@@ -386,40 +384,4 @@ void OSLShader::eval_displacement(const KernelGlobalsCPU *kg, const void *state,
sd->P = TO_FLOAT3(globals->P);
}
-/* Attributes */
-
-int OSLShader::find_attribute(const KernelGlobalsCPU *kg,
- const ShaderData *sd,
- uint id,
- AttributeDescriptor *desc)
-{
- /* for OSL, a hash map is used to lookup the attribute by name. */
- int object = sd->object * ATTR_PRIM_TYPES;
-
- OSLGlobals::AttributeMap &attr_map = kg->osl->attribute_map[object];
- ustring stdname(std::string("geom:") +
- std::string(Attribute::standard_name((AttributeStandard)id)));
- OSLGlobals::AttributeMap::const_iterator it = attr_map.find(stdname);
-
- if (it != attr_map.end()) {
- const OSLGlobals::Attribute &osl_attr = it->second;
- *desc = osl_attr.desc;
-
- if (sd->prim == PRIM_NONE && (AttributeElement)osl_attr.desc.element != ATTR_ELEMENT_MESH) {
- desc->offset = ATTR_STD_NOT_FOUND;
- return ATTR_STD_NOT_FOUND;
- }
-
- /* return result */
- if (osl_attr.desc.element == ATTR_ELEMENT_NONE) {
- desc->offset = ATTR_STD_NOT_FOUND;
- }
- return desc->offset;
- }
- else {
- desc->offset = ATTR_STD_NOT_FOUND;
- return (int)ATTR_STD_NOT_FOUND;
- }
-}
-
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/osl/shader.h b/intern/cycles/kernel/osl/shader.h
index f0ab49dd6a8..56c87d7c8ac 100644
--- a/intern/cycles/kernel/osl/shader.h
+++ b/intern/cycles/kernel/osl/shader.h
@@ -54,12 +54,6 @@ class OSLShader {
ShaderData *sd,
uint32_t path_flag);
static void eval_displacement(const KernelGlobalsCPU *kg, const void *state, ShaderData *sd);
-
- /* attributes */
- static int find_attribute(const KernelGlobalsCPU *kg,
- const ShaderData *sd,
- uint id,
- AttributeDescriptor *desc);
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/types.h b/intern/cycles/kernel/types.h
index 873d594f1f8..bd3791594e0 100644
--- a/intern/cycles/kernel/types.h
+++ b/intern/cycles/kernel/types.h
@@ -655,12 +655,11 @@ typedef struct AttributeDescriptor {
/* For looking up attributes on objects and geometry. */
typedef struct AttributeMap {
- uint id; /* Global unique identifier. */
- uint element; /* AttributeElement. */
- int offset; /* Offset into __attributes global arrays. */
- uint8_t type; /* NodeAttributeType. */
- uint8_t flags; /* AttributeFlag. */
- uint8_t pad[2];
+ uint64_t id; /* Global unique identifier. */
+ int offset; /* Offset into __attributes global arrays. */
+ uint16_t element; /* AttributeElement. */
+ uint8_t type; /* NodeAttributeType. */
+ uint8_t flags; /* AttributeFlag. */
} AttributeMap;
/* Closure data */
diff --git a/intern/cycles/scene/geometry.cpp b/intern/cycles/scene/geometry.cpp
index ae8dcaa43b6..d1a3df851c1 100644
--- a/intern/cycles/scene/geometry.cpp
+++ b/intern/cycles/scene/geometry.cpp
@@ -302,111 +302,32 @@ GeometryManager::~GeometryManager()
{
}
-void GeometryManager::update_osl_attributes(Device *device,
- Scene *scene,
- vector<AttributeRequestSet> &geom_attributes)
+void GeometryManager::update_osl_globals(Device *device, Scene *scene)
{
#ifdef WITH_OSL
- /* for OSL, a hash map is used to lookup the attribute by name. */
OSLGlobals *og = (OSLGlobals *)device->get_cpu_osl_memory();
og->object_name_map.clear();
- og->attribute_map.clear();
og->object_names.clear();
- og->attribute_map.resize(scene->objects.size() * ATTR_PRIM_TYPES);
-
for (size_t i = 0; i < scene->objects.size(); i++) {
/* set object name to object index map */
Object *object = scene->objects[i];
og->object_name_map[object->name] = i;
og->object_names.push_back(object->name);
-
- /* set object attributes */
- foreach (ParamValue &attr, object->attributes) {
- OSLGlobals::Attribute osl_attr;
-
- osl_attr.type = attr.type();
- osl_attr.desc.element = ATTR_ELEMENT_OBJECT;
- osl_attr.value = attr;
- osl_attr.desc.offset = 0;
- osl_attr.desc.flags = 0;
-
- og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_GEOMETRY][attr.name()] = osl_attr;
- og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][attr.name()] = osl_attr;
- }
-
- /* find geometry attributes */
- size_t j = object->geometry->index;
- assert(j < scene->geometry.size() && scene->geometry[j] == object->geometry);
-
- AttributeRequestSet &attributes = geom_attributes[j];
-
- /* set mesh attributes */
- foreach (AttributeRequest &req, attributes.requests) {
- OSLGlobals::Attribute osl_attr;
-
- if (req.desc.element != ATTR_ELEMENT_NONE) {
- osl_attr.desc = req.desc;
-
- if (req.type == TypeDesc::TypeFloat)
- osl_attr.type = TypeDesc::TypeFloat;
- else if (req.type == TypeDesc::TypeMatrix)
- osl_attr.type = TypeDesc::TypeMatrix;
- else if (req.type == TypeFloat2)
- osl_attr.type = TypeFloat2;
- else if (req.type == TypeRGBA)
- osl_attr.type = TypeRGBA;
- else
- osl_attr.type = TypeDesc::TypeColor;
-
- if (req.std != ATTR_STD_NONE) {
- /* if standard attribute, add lookup by geom: name convention */
- ustring stdname(string("geom:") + string(Attribute::standard_name(req.std)));
- og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_GEOMETRY][stdname] = osl_attr;
- }
- else if (req.name != ustring()) {
- /* add lookup by geometry attribute name */
- og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_GEOMETRY][req.name] = osl_attr;
- }
- }
-
- if (req.subd_desc.element != ATTR_ELEMENT_NONE) {
- osl_attr.desc = req.subd_desc;
-
- if (req.subd_type == TypeDesc::TypeFloat)
- osl_attr.type = TypeDesc::TypeFloat;
- else if (req.subd_type == TypeDesc::TypeMatrix)
- osl_attr.type = TypeDesc::TypeMatrix;
- else if (req.subd_type == TypeFloat2)
- osl_attr.type = TypeFloat2;
- else if (req.subd_type == TypeRGBA)
- osl_attr.type = TypeRGBA;
- else
- osl_attr.type = TypeDesc::TypeColor;
-
- if (req.std != ATTR_STD_NONE) {
- /* if standard attribute, add lookup by geom: name convention */
- ustring stdname(string("geom:") + string(Attribute::standard_name(req.std)));
- og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][stdname] = osl_attr;
- }
- else if (req.name != ustring()) {
- /* add lookup by geometry attribute name */
- og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][req.name] = osl_attr;
- }
- }
- }
}
#else
(void)device;
(void)scene;
- (void)geom_attributes;
#endif
}
/* Generate a normal attribute map entry from an attribute descriptor. */
-static void emit_attribute_map_entry(
- AttributeMap *attr_map, int index, uint id, TypeDesc type, const AttributeDescriptor &desc)
+static void emit_attribute_map_entry(AttributeMap *attr_map,
+ size_t index,
+ uint64_t id,
+ TypeDesc type,
+ const AttributeDescriptor &desc)
{
attr_map[index].id = id;
attr_map[index].element = desc.element;
@@ -431,7 +352,7 @@ static void emit_attribute_map_entry(
/* Generate an attribute map end marker, optionally including a link to another map.
* Links are used to connect object attribute maps to mesh attribute maps. */
static void emit_attribute_map_terminator(AttributeMap *attr_map,
- int index,
+ size_t index,
bool chain,
uint chain_link)
{
@@ -446,15 +367,8 @@ static void emit_attribute_map_terminator(AttributeMap *attr_map,
/* Generate all necessary attribute map entries from the attribute request. */
static void emit_attribute_mapping(
- AttributeMap *attr_map, int index, Scene *scene, AttributeRequest &req, Geometry *geom)
+ AttributeMap *attr_map, size_t index, uint64_t id, AttributeRequest &req, Geometry *geom)
{
- uint id;
-
- if (req.std == ATTR_STD_NONE)
- id = scene->shader_manager->get_attribute_id(req.name);
- else
- id = scene->shader_manager->get_attribute_id(req.std);
-
emit_attribute_map_entry(attr_map, index, id, req.type, req.desc);
if (geom->is_mesh()) {
@@ -475,12 +389,26 @@ void GeometryManager::update_svm_attributes(Device *,
* attribute, based on a unique shader attribute id. */
/* compute array stride */
- int attr_map_size = 0;
+ size_t attr_map_size = 0;
for (size_t i = 0; i < scene->geometry.size(); i++) {
Geometry *geom = scene->geometry[i];
geom->attr_map_offset = attr_map_size;
- attr_map_size += (geom_attributes[i].size() + 1) * ATTR_PRIM_TYPES;
+
+#ifdef WITH_OSL
+ size_t attr_count = 0;
+ foreach (AttributeRequest &req, geom_attributes[i].requests) {
+ if (req.std != ATTR_STD_NONE &&
+ scene->shader_manager->get_attribute_id(req.std) != (uint64_t)req.std)
+ attr_count += 2;
+ else
+ attr_count += 1;
+ }
+#else
+ const size_t attr_count = geom_attributes[i].size();
+#endif
+
+ attr_map_size += (attr_count + 1) * ATTR_PRIM_TYPES;
}
for (size_t i = 0; i < scene->objects.size(); i++) {
@@ -512,11 +440,26 @@ void GeometryManager::update_svm_attributes(Device *,
AttributeRequestSet &attributes = geom_attributes[i];
/* set geometry attributes */
- int index = geom->attr_map_offset;
+ size_t index = geom->attr_map_offset;
foreach (AttributeRequest &req, attributes.requests) {
- emit_attribute_mapping(attr_map, index, scene, req, geom);
+ uint64_t id;
+ if (req.std == ATTR_STD_NONE)
+ id = scene->shader_manager->get_attribute_id(req.name);
+ else
+ id = scene->shader_manager->get_attribute_id(req.std);
+
+ emit_attribute_mapping(attr_map, index, id, req, geom);
index += ATTR_PRIM_TYPES;
+
+#ifdef WITH_OSL
+ /* Some standard attributes are explicitly referenced via their standard ID, so add those
+ * again in case they were added under a different attribute ID. */
+ if (req.std != ATTR_STD_NONE && id != (uint64_t)req.std) {
+ emit_attribute_mapping(attr_map, index, (uint64_t)req.std, req, geom);
+ index += ATTR_PRIM_TYPES;
+ }
+#endif
}
emit_attribute_map_terminator(attr_map, index, false, 0);
@@ -528,10 +471,16 @@ void GeometryManager::update_svm_attributes(Device *,
/* set object attributes */
if (attributes.size() > 0) {
- int index = object->attr_map_offset;
+ size_t index = object->attr_map_offset;
foreach (AttributeRequest &req, attributes.requests) {
- emit_attribute_mapping(attr_map, index, scene, req, object->geometry);
+ uint64_t id;
+ if (req.std == ATTR_STD_NONE)
+ id = scene->shader_manager->get_attribute_id(req.name);
+ else
+ id = scene->shader_manager->get_attribute_id(req.std);
+
+ emit_attribute_mapping(attr_map, index, id, req, object->geometry);
index += ATTR_PRIM_TYPES;
}
@@ -982,7 +931,7 @@ void GeometryManager::device_update_attributes(Device *device,
/* create attribute lookup maps */
if (scene->shader_manager->use_osl())
- update_osl_attributes(device, scene, geom_attributes);
+ update_osl_globals(device, scene);
update_svm_attributes(device, dscene, scene, geom_attributes, object_attributes);
@@ -2188,7 +2137,6 @@ void GeometryManager::device_free(Device *device, DeviceScene *dscene, bool forc
if (og) {
og->object_name_map.clear();
- og->attribute_map.clear();
og->object_names.clear();
}
#else
diff --git a/intern/cycles/scene/geometry.h b/intern/cycles/scene/geometry.h
index 6210a64509a..8a1bdc33a6f 100644
--- a/intern/cycles/scene/geometry.h
+++ b/intern/cycles/scene/geometry.h
@@ -219,9 +219,7 @@ class GeometryManager {
void create_volume_mesh(const Scene *scene, Volume *volume, Progress &progress);
/* Attributes */
- void update_osl_attributes(Device *device,
- Scene *scene,
- vector<AttributeRequestSet> &geom_attributes);
+ void update_osl_globals(Device *device, Scene *scene);
void update_svm_attributes(Device *device,
DeviceScene *dscene,
Scene *scene,
diff --git a/intern/cycles/scene/osl.cpp b/intern/cycles/scene/osl.cpp
index f5ee0c0f1d3..7c8d9bcd3e2 100644
--- a/intern/cycles/scene/osl.cpp
+++ b/intern/cycles/scene/osl.cpp
@@ -78,6 +78,18 @@ void OSLShaderManager::reset(Scene * /*scene*/)
shading_system_init();
}
+uint64_t OSLShaderManager::get_attribute_id(ustring name)
+{
+ return name.hash();
+}
+
+uint64_t OSLShaderManager::get_attribute_id(AttributeStandard std)
+{
+ /* if standard attribute, use geom: name convention */
+ ustring stdname(string("geom:") + string(Attribute::standard_name(std)));
+ return stdname.hash();
+}
+
void OSLShaderManager::device_update_specific(Device *device,
DeviceScene *dscene,
Scene *scene,
diff --git a/intern/cycles/scene/osl.h b/intern/cycles/scene/osl.h
index bf27069b1b1..76c6bd96ce1 100644
--- a/intern/cycles/scene/osl.h
+++ b/intern/cycles/scene/osl.h
@@ -66,6 +66,9 @@ class OSLShaderManager : public ShaderManager {
return true;
}
+ uint64_t get_attribute_id(ustring name) override;
+ uint64_t get_attribute_id(AttributeStandard std) override;
+
void device_update_specific(Device *device,
DeviceScene *dscene,
Scene *scene,
diff --git a/intern/cycles/scene/shader.cpp b/intern/cycles/scene/shader.cpp
index bd647ab55e7..96a8f40bbad 100644
--- a/intern/cycles/scene/shader.cpp
+++ b/intern/cycles/scene/shader.cpp
@@ -414,7 +414,7 @@ ShaderManager *ShaderManager::create(int shadingsystem)
return manager;
}
-uint ShaderManager::get_attribute_id(ustring name)
+uint64_t ShaderManager::get_attribute_id(ustring name)
{
thread_scoped_spin_lock lock(attribute_lock_);
@@ -424,14 +424,14 @@ uint ShaderManager::get_attribute_id(ustring name)
if (it != unique_attribute_id.end())
return it->second;
- uint id = (uint)ATTR_STD_NUM + unique_attribute_id.size();
+ uint64_t id = ATTR_STD_NUM + unique_attribute_id.size();
unique_attribute_id[name] = id;
return id;
}
-uint ShaderManager::get_attribute_id(AttributeStandard std)
+uint64_t ShaderManager::get_attribute_id(AttributeStandard std)
{
- return (uint)std;
+ return (uint64_t)std;
}
int ShaderManager::get_shader_id(Shader *shader, bool smooth)
diff --git a/intern/cycles/scene/shader.h b/intern/cycles/scene/shader.h
index 274bb9b4fa1..2670776aca4 100644
--- a/intern/cycles/scene/shader.h
+++ b/intern/cycles/scene/shader.h
@@ -192,8 +192,8 @@ class ShaderManager {
void device_free_common(Device *device, DeviceScene *dscene, Scene *scene);
/* get globally unique id for a type of attribute */
- uint get_attribute_id(ustring name);
- uint get_attribute_id(AttributeStandard std);
+ virtual uint64_t get_attribute_id(ustring name);
+ virtual uint64_t get_attribute_id(AttributeStandard std);
/* get shader id for mesh faces */
int get_shader_id(Shader *shader, bool smooth = false);
@@ -223,7 +223,7 @@ class ShaderManager {
uint32_t update_flags;
- typedef unordered_map<ustring, uint, ustringHash> AttributeIDMap;
+ typedef unordered_map<ustring, uint64_t, ustringHash> AttributeIDMap;
AttributeIDMap unique_attribute_id;
static thread_mutex lookup_table_mutex;