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
path: root/intern
diff options
context:
space:
mode:
Diffstat (limited to 'intern')
-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;