Cleanup: Cycles: Deduplication svm bump functions

This commit is contained in:
Weizhen Huang
2025-07-23 15:07:35 +02:00
committed by Weizhen Huang
parent 32c9bd8b81
commit f9a65ebbea
2 changed files with 156 additions and 225 deletions

View File

@@ -49,6 +49,113 @@ ccl_device AttributeDescriptor svm_node_attr_init(KernelGlobals kg,
return desc;
}
ccl_device_inline void svm_node_attr_store(const NodeAttributeOutputType type,
ccl_private float *stack,
const uint out_offset,
const float f)
{
if (type == NODE_ATTR_OUTPUT_FLOAT) {
stack_store_float(stack, out_offset, f);
}
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
stack_store_float3(stack, out_offset, make_float3(f));
}
else {
stack_store_float(stack, out_offset, 1.0f);
}
}
ccl_device_inline void svm_node_attr_store(const NodeAttributeOutputType type,
ccl_private float *stack,
const uint out_offset,
const ccl_private float2 &f)
{
if (type == NODE_ATTR_OUTPUT_FLOAT) {
stack_store_float(stack, out_offset, f.x);
}
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
stack_store_float3(stack, out_offset, make_float3(f));
}
else {
stack_store_float(stack, out_offset, 1.0f);
}
}
ccl_device_inline void svm_node_attr_store(const NodeAttributeOutputType type,
ccl_private float *stack,
const uint out_offset,
const ccl_private float3 &f)
{
if (type == NODE_ATTR_OUTPUT_FLOAT) {
stack_store_float(stack, out_offset, average(f));
}
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
stack_store_float3(stack, out_offset, f);
}
else {
stack_store_float(stack, out_offset, 1.0f);
}
}
ccl_device_inline void svm_node_attr_store(const NodeAttributeOutputType type,
ccl_private float *stack,
const uint out_offset,
const ccl_private float4 &f)
{
if (type == NODE_ATTR_OUTPUT_FLOAT) {
stack_store_float(stack, out_offset, average(make_float3(f)));
}
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
stack_store_float3(stack, out_offset, make_float3(f));
}
else {
kernel_assert(type == NODE_ATTR_OUTPUT_FLOAT_ALPHA);
stack_store_float(stack, out_offset, f.w);
}
}
template<class T>
ccl_device_inline void svm_surface_attr(KernelGlobals kg,
const ccl_private ShaderData *sd,
const AttributeDescriptor desc,
const NodeAttributeOutputType type,
ccl_private float *stack,
const uint out_offset)
{
T f = primitive_surface_attribute<T>(kg, sd, desc, nullptr, nullptr);
svm_node_attr_store(type, stack, out_offset, f);
}
template<class T>
ccl_device_inline void svm_surface_attr_dx(KernelGlobals kg,
const ccl_private ShaderData *sd,
const AttributeDescriptor desc,
const float bump_filter_width,
const NodeAttributeOutputType type,
ccl_private float *stack,
const uint out_offset)
{
T dfdx;
T f = primitive_surface_attribute<T>(kg, sd, desc, &dfdx, nullptr);
f += dfdx * bump_filter_width;
svm_node_attr_store(type, stack, out_offset, f);
}
template<class T>
ccl_device_inline void svm_surface_attr_dy(KernelGlobals kg,
const ccl_private ShaderData *sd,
const AttributeDescriptor desc,
const float bump_filter_width,
const NodeAttributeOutputType type,
ccl_private float *stack,
const uint out_offset)
{
T dfdy;
T f = primitive_surface_attribute<T>(kg, sd, desc, nullptr, &dfdy);
f += dfdy * bump_filter_width;
svm_node_attr_store(type, stack, out_offset, f);
}
template<uint node_feature_mask>
ccl_device_noinline void svm_node_attr(KernelGlobals kg,
ccl_private ShaderData *sd,
@@ -96,66 +203,22 @@ ccl_device_noinline void svm_node_attr(KernelGlobals kg,
if (sd->object != OBJECT_NONE) {
object_inverse_position_transform(kg, sd, &f);
}
if (type == NODE_ATTR_OUTPUT_FLOAT) {
stack_store_float(stack, out_offset, average(f));
}
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
stack_store_float3(stack, out_offset, f);
}
else {
stack_store_float(stack, out_offset, 1.0f);
}
svm_node_attr_store(type, stack, out_offset, f);
return;
}
/* Surface. */
if (desc.type == NODE_ATTR_FLOAT) {
const float f = primitive_surface_attribute<float>(kg, sd, desc, nullptr, nullptr);
if (type == NODE_ATTR_OUTPUT_FLOAT) {
stack_store_float(stack, out_offset, f);
}
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
stack_store_float3(stack, out_offset, make_float3(f, f, f));
}
else {
stack_store_float(stack, out_offset, 1.0f);
}
svm_surface_attr<float>(kg, sd, desc, type, stack, out_offset);
}
else if (desc.type == NODE_ATTR_FLOAT2) {
const float2 f = primitive_surface_attribute<float2>(kg, sd, desc, nullptr, nullptr);
if (type == NODE_ATTR_OUTPUT_FLOAT) {
stack_store_float(stack, out_offset, f.x);
}
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
stack_store_float3(stack, out_offset, make_float3(f.x, f.y, 0.0f));
}
else {
stack_store_float(stack, out_offset, 1.0f);
}
svm_surface_attr<float2>(kg, sd, desc, type, stack, out_offset);
}
else if (desc.type == NODE_ATTR_FLOAT4 || desc.type == NODE_ATTR_RGBA) {
const float4 f = primitive_surface_attribute<float4>(kg, sd, desc, nullptr, nullptr);
if (type == NODE_ATTR_OUTPUT_FLOAT) {
stack_store_float(stack, out_offset, average(make_float3(f)));
}
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
stack_store_float3(stack, out_offset, make_float3(f));
}
else {
stack_store_float(stack, out_offset, f.w);
}
svm_surface_attr<float4>(kg, sd, desc, type, stack, out_offset);
}
else {
const float3 f = primitive_surface_attribute<float3>(kg, sd, desc, nullptr, nullptr);
if (type == NODE_ATTR_OUTPUT_FLOAT) {
stack_store_float(stack, out_offset, average(f));
}
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
stack_store_float3(stack, out_offset, f);
}
else {
stack_store_float(stack, out_offset, 1.0f);
}
svm_surface_attr<float3>(kg, sd, desc, type, stack, out_offset);
}
}
@@ -187,15 +250,7 @@ ccl_device_noinline void svm_node_attr_bump_dx(KernelGlobals kg,
#ifdef __VOLUME__
/* Volume */
if (primitive_is_volume_attribute(sd)) {
if (type == NODE_ATTR_OUTPUT_FLOAT) {
stack_store_float(stack, out_offset, 0.0f);
}
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
stack_store_float3(stack, out_offset, make_float3(0.0f, 0.0f, 0.0f));
}
else {
stack_store_float(stack, out_offset, 1.0f);
}
svm_node_attr_store(type, stack, out_offset, 0.0f);
return;
}
#endif
@@ -206,74 +261,22 @@ ccl_device_noinline void svm_node_attr_bump_dx(KernelGlobals kg,
if (sd->object != OBJECT_NONE) {
object_inverse_position_transform(kg, sd, &f_x);
}
if (type == NODE_ATTR_OUTPUT_FLOAT) {
stack_store_float(stack, out_offset, average(f_x));
}
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
stack_store_float3(stack, out_offset, f_x);
}
else {
stack_store_float(stack, out_offset, 1.0f);
}
svm_node_attr_store(type, stack, out_offset, f_x);
return;
}
/* Surface */
if (desc.type == NODE_ATTR_FLOAT) {
float dfdx;
const float f = primitive_surface_attribute<float>(kg, sd, desc, &dfdx, nullptr);
const float f_x = f + dfdx * bump_filter_width;
if (type == NODE_ATTR_OUTPUT_FLOAT) {
stack_store_float(stack, out_offset, f_x);
}
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
stack_store_float3(stack, out_offset, make_float3(f_x));
}
else {
stack_store_float(stack, out_offset, 1.0f);
}
svm_surface_attr_dx<float>(kg, sd, desc, bump_filter_width, type, stack, out_offset);
}
else if (desc.type == NODE_ATTR_FLOAT2) {
float2 dfdx;
const float2 f = primitive_surface_attribute<float2>(kg, sd, desc, &dfdx, nullptr);
const float2 f_x = f + dfdx * bump_filter_width;
if (type == NODE_ATTR_OUTPUT_FLOAT) {
stack_store_float(stack, out_offset, f_x.x);
}
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
stack_store_float3(stack, out_offset, make_float3(f_x));
}
else {
stack_store_float(stack, out_offset, 1.0f);
}
svm_surface_attr_dx<float2>(kg, sd, desc, bump_filter_width, type, stack, out_offset);
}
else if (desc.type == NODE_ATTR_FLOAT4 || desc.type == NODE_ATTR_RGBA) {
float4 dfdx;
const float4 f = primitive_surface_attribute<float4>(kg, sd, desc, &dfdx, nullptr);
const float4 f_x = f + dfdx * bump_filter_width;
if (type == NODE_ATTR_OUTPUT_FLOAT) {
stack_store_float(stack, out_offset, average(make_float3(f_x)));
}
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
stack_store_float3(stack, out_offset, make_float3(f_x));
}
else {
stack_store_float(stack, out_offset, f_x.w);
}
svm_surface_attr_dx<float4>(kg, sd, desc, bump_filter_width, type, stack, out_offset);
}
else {
float3 dfdx;
const float3 f = primitive_surface_attribute<float3>(kg, sd, desc, &dfdx, nullptr);
const float3 f_x = f + dfdx * bump_filter_width;
if (type == NODE_ATTR_OUTPUT_FLOAT) {
stack_store_float(stack, out_offset, average(f_x));
}
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
stack_store_float3(stack, out_offset, f_x);
}
else {
stack_store_float(stack, out_offset, 1.0f);
}
svm_surface_attr_dx<float3>(kg, sd, desc, bump_filter_width, type, stack, out_offset);
}
}
@@ -291,93 +294,34 @@ ccl_device_noinline void svm_node_attr_bump_dy(KernelGlobals kg,
#ifdef __VOLUME__
/* Volume */
if (primitive_is_volume_attribute(sd)) {
if (type == NODE_ATTR_OUTPUT_FLOAT) {
stack_store_float(stack, out_offset, 0.0f);
}
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
stack_store_float3(stack, out_offset, make_float3(0.0f, 0.0f, 0.0f));
}
else {
stack_store_float(stack, out_offset, 1.0f);
}
svm_node_attr_store(type, stack, out_offset, 0.0f);
return;
}
#endif
if (node.y == ATTR_STD_GENERATED && desc.element == ATTR_ELEMENT_NONE) {
/* No generated attribute, fall back to object coordinates. */
/* TODO:(weizhen) */
float3 f_y = svm_node_bump_P_dy(sd, bump_filter_width);
if (sd->object != OBJECT_NONE) {
object_inverse_position_transform(kg, sd, &f_y);
}
if (type == NODE_ATTR_OUTPUT_FLOAT) {
stack_store_float(stack, out_offset, average(f_y));
}
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
stack_store_float3(stack, out_offset, f_y);
}
else {
stack_store_float(stack, out_offset, 1.0f);
}
svm_node_attr_store(type, stack, out_offset, f_y);
return;
}
/* Surface */
if (desc.type == NODE_ATTR_FLOAT) {
float dfdy;
const float f = primitive_surface_attribute<float>(kg, sd, desc, nullptr, &dfdy);
const float f_y = f + dfdy * bump_filter_width;
if (type == NODE_ATTR_OUTPUT_FLOAT) {
stack_store_float(stack, out_offset, f_y);
}
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
stack_store_float3(stack, out_offset, make_float3(f_y));
}
else {
stack_store_float(stack, out_offset, 1.0f);
}
svm_surface_attr_dy<float>(kg, sd, desc, bump_filter_width, type, stack, out_offset);
}
else if (desc.type == NODE_ATTR_FLOAT2) {
float2 dfdy;
const float2 f = primitive_surface_attribute<float2>(kg, sd, desc, nullptr, &dfdy);
const float2 f_y = f + dfdy * bump_filter_width;
if (type == NODE_ATTR_OUTPUT_FLOAT) {
stack_store_float(stack, out_offset, f_y.x);
}
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
stack_store_float3(stack, out_offset, make_float3(f_y));
}
else {
stack_store_float(stack, out_offset, 1.0f);
}
svm_surface_attr_dy<float2>(kg, sd, desc, bump_filter_width, type, stack, out_offset);
}
else if (desc.type == NODE_ATTR_FLOAT4 || desc.type == NODE_ATTR_RGBA) {
float4 dfdy;
const float4 f = primitive_surface_attribute<float4>(kg, sd, desc, nullptr, &dfdy);
const float4 f_y = f + dfdy * bump_filter_width;
if (type == NODE_ATTR_OUTPUT_FLOAT) {
stack_store_float(stack, out_offset, average(make_float3(f_y)));
}
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
stack_store_float3(stack, out_offset, make_float3(f_y));
}
else {
stack_store_float(stack, out_offset, f_y.w);
}
svm_surface_attr_dy<float4>(kg, sd, desc, bump_filter_width, type, stack, out_offset);
}
else {
float3 dfdy;
const float3 f = primitive_surface_attribute<float3>(kg, sd, desc, nullptr, &dfdy);
const float3 f_y = f + dfdy * bump_filter_width;
if (type == NODE_ATTR_OUTPUT_FLOAT) {
stack_store_float(stack, out_offset, average(f_y));
}
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
stack_store_float3(stack, out_offset, f_y);
}
else {
stack_store_float(stack, out_offset, 1.0f);
}
svm_surface_attr_dy<float3>(kg, sd, desc, bump_filter_width, type, stack, out_offset);
}
}

View File

@@ -19,6 +19,28 @@ CCL_NAMESPACE_BEGIN
/* Texture Coordinate Node */
ccl_device_inline float3 svm_texco_reflection(const ccl_private ShaderData *sd)
{
float3 data = sd->wi;
if (sd->object != OBJECT_NONE) {
data = -reflect(data, sd->N);
}
return data;
}
ccl_device_inline float3 svm_texco_camera(KernelGlobals kg,
const ccl_private ShaderData *sd,
const ccl_private float3 &P)
{
float3 data = P;
const Transform tfm = kernel_data.cam.worldtocamera;
if (sd->object == OBJECT_NONE) {
data += camera_position(kg);
}
data = transform_point(&tfm, data);
return data;
}
ccl_device_noinline int svm_node_tex_coord(KernelGlobals kg,
ccl_private ShaderData *sd,
const uint32_t path_flag,
@@ -54,14 +76,8 @@ ccl_device_noinline int svm_node_tex_coord(KernelGlobals kg,
break;
}
case NODE_TEXCO_CAMERA: {
const Transform tfm = kernel_data.cam.worldtocamera;
if (sd->object != OBJECT_NONE) {
data = transform_point(&tfm, sd->P);
}
else {
data = transform_point(&tfm, sd->P + camera_position(kg));
}
const float3 P = sd->P;
data = svm_texco_camera(kg, sd, P);
break;
}
case NODE_TEXCO_WINDOW: {
@@ -77,12 +93,7 @@ ccl_device_noinline int svm_node_tex_coord(KernelGlobals kg,
break;
}
case NODE_TEXCO_REFLECTION: {
if (sd->object != OBJECT_NONE) {
data = 2.0f * dot(sd->N, sd->wi) * sd->N - sd->wi;
}
else {
data = sd->wi;
}
data = svm_texco_reflection(sd);
break;
}
case NODE_TEXCO_DUPLI_GENERATED: {
@@ -178,15 +189,8 @@ ccl_device_noinline int svm_node_tex_coord_bump_dx(KernelGlobals kg,
break;
}
case NODE_TEXCO_CAMERA: {
const Transform tfm = kernel_data.cam.worldtocamera;
if (sd->object != OBJECT_NONE) {
data = transform_point(&tfm, svm_node_bump_P_dx(sd, bump_filter_width));
}
else {
data = transform_point(&tfm,
svm_node_bump_P_dx(sd, bump_filter_width) + camera_position(kg));
}
const float3 P = svm_node_bump_P_dx(sd, bump_filter_width);
data = svm_texco_camera(kg, sd, P);
break;
}
case NODE_TEXCO_WINDOW: {
@@ -202,12 +206,7 @@ ccl_device_noinline int svm_node_tex_coord_bump_dx(KernelGlobals kg,
break;
}
case NODE_TEXCO_REFLECTION: {
if (sd->object != OBJECT_NONE) {
data = 2.0f * dot(sd->N, sd->wi) * sd->N - sd->wi;
}
else {
data = sd->wi;
}
data = svm_texco_reflection(sd);
break;
}
case NODE_TEXCO_DUPLI_GENERATED: {
@@ -274,15 +273,8 @@ ccl_device_noinline int svm_node_tex_coord_bump_dy(KernelGlobals kg,
break;
}
case NODE_TEXCO_CAMERA: {
const Transform tfm = kernel_data.cam.worldtocamera;
if (sd->object != OBJECT_NONE) {
data = transform_point(&tfm, svm_node_bump_P_dy(sd, bump_filter_width));
}
else {
data = transform_point(&tfm,
svm_node_bump_P_dy(sd, bump_filter_width) + camera_position(kg));
}
const float3 P = svm_node_bump_P_dy(sd, bump_filter_width);
data = svm_texco_camera(kg, sd, P);
break;
}
case NODE_TEXCO_WINDOW: {
@@ -298,12 +290,7 @@ ccl_device_noinline int svm_node_tex_coord_bump_dy(KernelGlobals kg,
break;
}
case NODE_TEXCO_REFLECTION: {
if (sd->object != OBJECT_NONE) {
data = 2.0f * dot(sd->N, sd->wi) * sd->N - sd->wi;
}
else {
data = sd->wi;
}
data = svm_texco_reflection(sd);
break;
}
case NODE_TEXCO_DUPLI_GENERATED: {