Cycles: keep track of SVM nodes used in kernels

To be used for specialization in Metal, to automatically leave out unused nodes
from the kernel.

Ref D14645
This commit is contained in:
Michael Jones
2022-07-12 17:22:36 +02:00
committed by Brecht Van Lommel
parent 79da7f2a8f
commit 5653c5fcdd
8 changed files with 477 additions and 444 deletions

View File

@@ -154,6 +154,7 @@ set(SRC_KERNEL_SVM_HEADERS
svm/math_util.h
svm/mix.h
svm/musgrave.h
svm/node_types_template.h
svm/noise.h
svm/noisetex.h
svm/normal.h

View File

@@ -194,6 +194,13 @@ KERNEL_STRUCT_MEMBER(integrator, int, direct_light_sampling_type)
KERNEL_STRUCT_MEMBER(integrator, int, pad1)
KERNEL_STRUCT_END(KernelIntegrator)
/* SVM. For shader specialization. */
KERNEL_STRUCT_BEGIN(KernelSVMUsage, svm_usage)
#define SHADER_NODE_TYPE(type) KERNEL_STRUCT_MEMBER(svm_usage, int, type)
#include "kernel/svm/node_types_template.h"
KERNEL_STRUCT_END(KernelSVMUsage)
#undef KERNEL_STRUCT_BEGIN
#undef KERNEL_STRUCT_MEMBER
#undef KERNEL_STRUCT_END

View File

@@ -0,0 +1,110 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
#ifndef SHADER_NODE_TYPE
# define SHADER_NODE_TYPE(name)
#endif
/* NOTE: for best OpenCL performance, item definition in the enum must
* match the switch case order in `svm.h`. */
SHADER_NODE_TYPE(NODE_END)
SHADER_NODE_TYPE(NODE_SHADER_JUMP)
SHADER_NODE_TYPE(NODE_CLOSURE_BSDF)
SHADER_NODE_TYPE(NODE_CLOSURE_EMISSION)
SHADER_NODE_TYPE(NODE_CLOSURE_BACKGROUND)
SHADER_NODE_TYPE(NODE_CLOSURE_SET_WEIGHT)
SHADER_NODE_TYPE(NODE_CLOSURE_WEIGHT)
SHADER_NODE_TYPE(NODE_EMISSION_WEIGHT)
SHADER_NODE_TYPE(NODE_MIX_CLOSURE)
SHADER_NODE_TYPE(NODE_JUMP_IF_ZERO)
SHADER_NODE_TYPE(NODE_JUMP_IF_ONE)
SHADER_NODE_TYPE(NODE_GEOMETRY)
SHADER_NODE_TYPE(NODE_CONVERT)
SHADER_NODE_TYPE(NODE_TEX_COORD)
SHADER_NODE_TYPE(NODE_VALUE_F)
SHADER_NODE_TYPE(NODE_VALUE_V)
SHADER_NODE_TYPE(NODE_ATTR)
SHADER_NODE_TYPE(NODE_VERTEX_COLOR)
SHADER_NODE_TYPE(NODE_GEOMETRY_BUMP_DX)
SHADER_NODE_TYPE(NODE_GEOMETRY_BUMP_DY)
SHADER_NODE_TYPE(NODE_SET_DISPLACEMENT)
SHADER_NODE_TYPE(NODE_DISPLACEMENT)
SHADER_NODE_TYPE(NODE_VECTOR_DISPLACEMENT)
SHADER_NODE_TYPE(NODE_TEX_IMAGE)
SHADER_NODE_TYPE(NODE_TEX_IMAGE_BOX)
SHADER_NODE_TYPE(NODE_TEX_NOISE)
SHADER_NODE_TYPE(NODE_SET_BUMP)
SHADER_NODE_TYPE(NODE_ATTR_BUMP_DX)
SHADER_NODE_TYPE(NODE_ATTR_BUMP_DY)
SHADER_NODE_TYPE(NODE_VERTEX_COLOR_BUMP_DX)
SHADER_NODE_TYPE(NODE_VERTEX_COLOR_BUMP_DY)
SHADER_NODE_TYPE(NODE_TEX_COORD_BUMP_DX)
SHADER_NODE_TYPE(NODE_TEX_COORD_BUMP_DY)
SHADER_NODE_TYPE(NODE_CLOSURE_SET_NORMAL)
SHADER_NODE_TYPE(NODE_ENTER_BUMP_EVAL)
SHADER_NODE_TYPE(NODE_LEAVE_BUMP_EVAL)
SHADER_NODE_TYPE(NODE_HSV)
SHADER_NODE_TYPE(NODE_CLOSURE_HOLDOUT)
SHADER_NODE_TYPE(NODE_FRESNEL)
SHADER_NODE_TYPE(NODE_LAYER_WEIGHT)
SHADER_NODE_TYPE(NODE_CLOSURE_VOLUME)
SHADER_NODE_TYPE(NODE_PRINCIPLED_VOLUME)
SHADER_NODE_TYPE(NODE_MATH)
SHADER_NODE_TYPE(NODE_VECTOR_MATH)
SHADER_NODE_TYPE(NODE_RGB_RAMP)
SHADER_NODE_TYPE(NODE_GAMMA)
SHADER_NODE_TYPE(NODE_BRIGHTCONTRAST)
SHADER_NODE_TYPE(NODE_LIGHT_PATH)
SHADER_NODE_TYPE(NODE_OBJECT_INFO)
SHADER_NODE_TYPE(NODE_PARTICLE_INFO)
SHADER_NODE_TYPE(NODE_HAIR_INFO)
SHADER_NODE_TYPE(NODE_POINT_INFO)
SHADER_NODE_TYPE(NODE_TEXTURE_MAPPING)
SHADER_NODE_TYPE(NODE_MAPPING)
SHADER_NODE_TYPE(NODE_MIN_MAX)
SHADER_NODE_TYPE(NODE_CAMERA)
SHADER_NODE_TYPE(NODE_TEX_ENVIRONMENT)
SHADER_NODE_TYPE(NODE_TEX_SKY)
SHADER_NODE_TYPE(NODE_TEX_GRADIENT)
SHADER_NODE_TYPE(NODE_TEX_VORONOI)
SHADER_NODE_TYPE(NODE_TEX_MUSGRAVE)
SHADER_NODE_TYPE(NODE_TEX_WAVE)
SHADER_NODE_TYPE(NODE_TEX_MAGIC)
SHADER_NODE_TYPE(NODE_TEX_CHECKER)
SHADER_NODE_TYPE(NODE_TEX_BRICK)
SHADER_NODE_TYPE(NODE_TEX_WHITE_NOISE)
SHADER_NODE_TYPE(NODE_NORMAL)
SHADER_NODE_TYPE(NODE_LIGHT_FALLOFF)
SHADER_NODE_TYPE(NODE_IES)
SHADER_NODE_TYPE(NODE_CURVES)
SHADER_NODE_TYPE(NODE_TANGENT)
SHADER_NODE_TYPE(NODE_NORMAL_MAP)
SHADER_NODE_TYPE(NODE_INVERT)
SHADER_NODE_TYPE(NODE_MIX)
SHADER_NODE_TYPE(NODE_SEPARATE_COLOR)
SHADER_NODE_TYPE(NODE_COMBINE_COLOR)
SHADER_NODE_TYPE(NODE_SEPARATE_VECTOR)
SHADER_NODE_TYPE(NODE_COMBINE_VECTOR)
SHADER_NODE_TYPE(NODE_SEPARATE_HSV)
SHADER_NODE_TYPE(NODE_COMBINE_HSV)
SHADER_NODE_TYPE(NODE_VECTOR_ROTATE)
SHADER_NODE_TYPE(NODE_VECTOR_TRANSFORM)
SHADER_NODE_TYPE(NODE_WIREFRAME)
SHADER_NODE_TYPE(NODE_WAVELENGTH)
SHADER_NODE_TYPE(NODE_BLACKBODY)
SHADER_NODE_TYPE(NODE_MAP_RANGE)
SHADER_NODE_TYPE(NODE_VECTOR_MAP_RANGE)
SHADER_NODE_TYPE(NODE_CLAMP)
SHADER_NODE_TYPE(NODE_BEVEL)
SHADER_NODE_TYPE(NODE_AMBIENT_OCCLUSION)
SHADER_NODE_TYPE(NODE_TEX_VOXEL)
SHADER_NODE_TYPE(NODE_AOV_START)
SHADER_NODE_TYPE(NODE_AOV_COLOR)
SHADER_NODE_TYPE(NODE_AOV_VALUE)
SHADER_NODE_TYPE(NODE_FLOAT_CURVE)
/* Padding for struct alignment. */
SHADER_NODE_TYPE(NODE_PAD1)
#undef SHADER_NODE_TYPE

View File

@@ -204,6 +204,8 @@ CCL_NAMESPACE_END
CCL_NAMESPACE_BEGIN
#define SVM_CASE(node) case node:
/* Main Interpreter Loop */
template<uint node_feature_mask, ShaderType type, typename ConstIntegratorGenericState>
ccl_device void svm_eval_nodes(KernelGlobals kg,
@@ -219,9 +221,10 @@ ccl_device void svm_eval_nodes(KernelGlobals kg,
uint4 node = read_node(kg, &offset);
switch (node.x) {
case NODE_END:
return;
case NODE_SHADER_JUMP: {
SVM_CASE(NODE_END)
return;
SVM_CASE(NODE_SHADER_JUMP)
{
if (type == SHADER_TYPE_SURFACE)
offset = node.y;
else if (type == SHADER_TYPE_VOLUME)
@@ -232,351 +235,349 @@ ccl_device void svm_eval_nodes(KernelGlobals kg,
return;
break;
}
case NODE_CLOSURE_BSDF:
offset = svm_node_closure_bsdf<node_feature_mask, type>(
kg, sd, stack, node, path_flag, offset);
break;
case NODE_CLOSURE_EMISSION:
IF_KERNEL_NODES_FEATURE(EMISSION)
{
svm_node_closure_emission(sd, stack, node);
}
break;
case NODE_CLOSURE_BACKGROUND:
IF_KERNEL_NODES_FEATURE(EMISSION)
{
svm_node_closure_background(sd, stack, node);
}
break;
case NODE_CLOSURE_SET_WEIGHT:
svm_node_closure_set_weight(sd, node.y, node.z, node.w);
break;
case NODE_CLOSURE_WEIGHT:
svm_node_closure_weight(sd, stack, node.y);
break;
case NODE_EMISSION_WEIGHT:
IF_KERNEL_NODES_FEATURE(EMISSION)
{
svm_node_emission_weight(kg, sd, stack, node);
}
break;
case NODE_MIX_CLOSURE:
svm_node_mix_closure(sd, stack, node);
break;
case NODE_JUMP_IF_ZERO:
if (stack_load_float(stack, node.z) <= 0.0f)
offset += node.y;
break;
case NODE_JUMP_IF_ONE:
if (stack_load_float(stack, node.z) >= 1.0f)
offset += node.y;
break;
case NODE_GEOMETRY:
svm_node_geometry(kg, sd, stack, node.y, node.z);
break;
case NODE_CONVERT:
svm_node_convert(kg, sd, stack, node.y, node.z, node.w);
break;
case NODE_TEX_COORD:
offset = svm_node_tex_coord(kg, sd, path_flag, stack, node, offset);
break;
case NODE_VALUE_F:
svm_node_value_f(kg, sd, stack, node.y, node.z);
break;
case NODE_VALUE_V:
offset = svm_node_value_v(kg, sd, stack, node.y, offset);
break;
case NODE_ATTR:
svm_node_attr<node_feature_mask>(kg, sd, stack, node);
break;
case NODE_VERTEX_COLOR:
svm_node_vertex_color(kg, sd, stack, node.y, node.z, node.w);
break;
case NODE_GEOMETRY_BUMP_DX:
IF_KERNEL_NODES_FEATURE(BUMP)
{
svm_node_geometry_bump_dx(kg, sd, stack, node.y, node.z);
}
break;
case NODE_GEOMETRY_BUMP_DY:
IF_KERNEL_NODES_FEATURE(BUMP)
{
svm_node_geometry_bump_dy(kg, sd, stack, node.y, node.z);
}
break;
case NODE_SET_DISPLACEMENT:
svm_node_set_displacement<node_feature_mask>(kg, sd, stack, node.y);
break;
case NODE_DISPLACEMENT:
svm_node_displacement<node_feature_mask>(kg, sd, stack, node);
break;
case NODE_VECTOR_DISPLACEMENT:
offset = svm_node_vector_displacement<node_feature_mask>(kg, sd, stack, node, offset);
break;
case NODE_TEX_IMAGE:
offset = svm_node_tex_image(kg, sd, stack, node, offset);
break;
case NODE_TEX_IMAGE_BOX:
svm_node_tex_image_box(kg, sd, stack, node);
break;
case NODE_TEX_NOISE:
offset = svm_node_tex_noise(kg, sd, stack, node.y, node.z, node.w, offset);
break;
case NODE_SET_BUMP:
svm_node_set_bump<node_feature_mask>(kg, sd, stack, node);
break;
case NODE_ATTR_BUMP_DX:
IF_KERNEL_NODES_FEATURE(BUMP)
{
svm_node_attr_bump_dx(kg, sd, stack, node);
}
break;
case NODE_ATTR_BUMP_DY:
IF_KERNEL_NODES_FEATURE(BUMP)
{
svm_node_attr_bump_dy(kg, sd, stack, node);
}
break;
case NODE_VERTEX_COLOR_BUMP_DX:
IF_KERNEL_NODES_FEATURE(BUMP)
{
svm_node_vertex_color_bump_dx(kg, sd, stack, node.y, node.z, node.w);
}
break;
case NODE_VERTEX_COLOR_BUMP_DY:
IF_KERNEL_NODES_FEATURE(BUMP)
{
svm_node_vertex_color_bump_dy(kg, sd, stack, node.y, node.z, node.w);
}
break;
case NODE_TEX_COORD_BUMP_DX:
IF_KERNEL_NODES_FEATURE(BUMP)
{
offset = svm_node_tex_coord_bump_dx(kg, sd, path_flag, stack, node, offset);
}
break;
case NODE_TEX_COORD_BUMP_DY:
IF_KERNEL_NODES_FEATURE(BUMP)
{
offset = svm_node_tex_coord_bump_dy(kg, sd, path_flag, stack, node, offset);
}
break;
case NODE_CLOSURE_SET_NORMAL:
IF_KERNEL_NODES_FEATURE(BUMP)
{
svm_node_set_normal(kg, sd, stack, node.y, node.z);
}
break;
case NODE_ENTER_BUMP_EVAL:
IF_KERNEL_NODES_FEATURE(BUMP_STATE)
{
svm_node_enter_bump_eval(kg, sd, stack, node.y);
}
break;
case NODE_LEAVE_BUMP_EVAL:
IF_KERNEL_NODES_FEATURE(BUMP_STATE)
{
svm_node_leave_bump_eval(kg, sd, stack, node.y);
}
break;
case NODE_HSV:
svm_node_hsv(kg, sd, stack, node);
break;
case NODE_CLOSURE_HOLDOUT:
svm_node_closure_holdout(sd, stack, node);
break;
case NODE_FRESNEL:
svm_node_fresnel(sd, stack, node.y, node.z, node.w);
break;
case NODE_LAYER_WEIGHT:
svm_node_layer_weight(sd, stack, node);
break;
case NODE_CLOSURE_VOLUME:
IF_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_closure_volume<type>(kg, sd, stack, node);
}
break;
case NODE_PRINCIPLED_VOLUME:
IF_KERNEL_NODES_FEATURE(VOLUME)
{
offset = svm_node_principled_volume<type>(kg, sd, stack, node, path_flag, offset);
}
break;
case NODE_MATH:
svm_node_math(kg, sd, stack, node.y, node.z, node.w);
break;
case NODE_VECTOR_MATH:
offset = svm_node_vector_math(kg, sd, stack, node.y, node.z, node.w, offset);
break;
case NODE_RGB_RAMP:
offset = svm_node_rgb_ramp(kg, sd, stack, node, offset);
break;
case NODE_GAMMA:
svm_node_gamma(sd, stack, node.y, node.z, node.w);
break;
case NODE_BRIGHTCONTRAST:
svm_node_brightness(sd, stack, node.y, node.z, node.w);
break;
case NODE_LIGHT_PATH:
svm_node_light_path<node_feature_mask>(kg, state, sd, stack, node.y, node.z, path_flag);
break;
case NODE_OBJECT_INFO:
svm_node_object_info(kg, sd, stack, node.y, node.z);
break;
case NODE_PARTICLE_INFO:
svm_node_particle_info(kg, sd, stack, node.y, node.z);
break;
SVM_CASE(NODE_CLOSURE_BSDF)
offset = svm_node_closure_bsdf<node_feature_mask, type>(
kg, sd, stack, node, path_flag, offset);
break;
SVM_CASE(NODE_CLOSURE_EMISSION)
IF_KERNEL_NODES_FEATURE(EMISSION)
{
svm_node_closure_emission(sd, stack, node);
}
break;
SVM_CASE(NODE_CLOSURE_BACKGROUND)
IF_KERNEL_NODES_FEATURE(EMISSION)
{
svm_node_closure_background(sd, stack, node);
}
break;
SVM_CASE(NODE_CLOSURE_SET_WEIGHT)
svm_node_closure_set_weight(sd, node.y, node.z, node.w);
break;
SVM_CASE(NODE_CLOSURE_WEIGHT)
svm_node_closure_weight(sd, stack, node.y);
break;
SVM_CASE(NODE_EMISSION_WEIGHT)
IF_KERNEL_NODES_FEATURE(EMISSION)
{
svm_node_emission_weight(kg, sd, stack, node);
}
break;
SVM_CASE(NODE_MIX_CLOSURE)
svm_node_mix_closure(sd, stack, node);
break;
SVM_CASE(NODE_JUMP_IF_ZERO)
if (stack_load_float(stack, node.z) <= 0.0f)
offset += node.y;
break;
SVM_CASE(NODE_JUMP_IF_ONE)
if (stack_load_float(stack, node.z) >= 1.0f)
offset += node.y;
break;
SVM_CASE(NODE_GEOMETRY)
svm_node_geometry(kg, sd, stack, node.y, node.z);
break;
SVM_CASE(NODE_CONVERT)
svm_node_convert(kg, sd, stack, node.y, node.z, node.w);
break;
SVM_CASE(NODE_TEX_COORD)
offset = svm_node_tex_coord(kg, sd, path_flag, stack, node, offset);
break;
SVM_CASE(NODE_VALUE_F)
svm_node_value_f(kg, sd, stack, node.y, node.z);
break;
SVM_CASE(NODE_VALUE_V)
offset = svm_node_value_v(kg, sd, stack, node.y, offset);
break;
SVM_CASE(NODE_ATTR)
svm_node_attr<node_feature_mask>(kg, sd, stack, node);
break;
SVM_CASE(NODE_VERTEX_COLOR)
svm_node_vertex_color(kg, sd, stack, node.y, node.z, node.w);
break;
SVM_CASE(NODE_GEOMETRY_BUMP_DX)
IF_KERNEL_NODES_FEATURE(BUMP)
{
svm_node_geometry_bump_dx(kg, sd, stack, node.y, node.z);
}
break;
SVM_CASE(NODE_GEOMETRY_BUMP_DY)
IF_KERNEL_NODES_FEATURE(BUMP)
{
svm_node_geometry_bump_dy(kg, sd, stack, node.y, node.z);
}
break;
SVM_CASE(NODE_SET_DISPLACEMENT)
svm_node_set_displacement<node_feature_mask>(kg, sd, stack, node.y);
break;
SVM_CASE(NODE_DISPLACEMENT)
svm_node_displacement<node_feature_mask>(kg, sd, stack, node);
break;
SVM_CASE(NODE_VECTOR_DISPLACEMENT)
offset = svm_node_vector_displacement<node_feature_mask>(kg, sd, stack, node, offset);
break;
SVM_CASE(NODE_TEX_IMAGE)
offset = svm_node_tex_image(kg, sd, stack, node, offset);
break;
SVM_CASE(NODE_TEX_IMAGE_BOX)
svm_node_tex_image_box(kg, sd, stack, node);
break;
SVM_CASE(NODE_TEX_NOISE)
offset = svm_node_tex_noise(kg, sd, stack, node.y, node.z, node.w, offset);
break;
SVM_CASE(NODE_SET_BUMP)
svm_node_set_bump<node_feature_mask>(kg, sd, stack, node);
break;
SVM_CASE(NODE_ATTR_BUMP_DX)
IF_KERNEL_NODES_FEATURE(BUMP)
{
svm_node_attr_bump_dx(kg, sd, stack, node);
}
break;
SVM_CASE(NODE_ATTR_BUMP_DY)
IF_KERNEL_NODES_FEATURE(BUMP)
{
svm_node_attr_bump_dy(kg, sd, stack, node);
}
break;
SVM_CASE(NODE_VERTEX_COLOR_BUMP_DX)
IF_KERNEL_NODES_FEATURE(BUMP)
{
svm_node_vertex_color_bump_dx(kg, sd, stack, node.y, node.z, node.w);
}
break;
SVM_CASE(NODE_VERTEX_COLOR_BUMP_DY)
IF_KERNEL_NODES_FEATURE(BUMP)
{
svm_node_vertex_color_bump_dy(kg, sd, stack, node.y, node.z, node.w);
}
break;
SVM_CASE(NODE_TEX_COORD_BUMP_DX)
IF_KERNEL_NODES_FEATURE(BUMP)
{
offset = svm_node_tex_coord_bump_dx(kg, sd, path_flag, stack, node, offset);
}
break;
SVM_CASE(NODE_TEX_COORD_BUMP_DY)
IF_KERNEL_NODES_FEATURE(BUMP)
{
offset = svm_node_tex_coord_bump_dy(kg, sd, path_flag, stack, node, offset);
}
break;
SVM_CASE(NODE_CLOSURE_SET_NORMAL)
IF_KERNEL_NODES_FEATURE(BUMP)
{
svm_node_set_normal(kg, sd, stack, node.y, node.z);
}
break;
SVM_CASE(NODE_ENTER_BUMP_EVAL)
IF_KERNEL_NODES_FEATURE(BUMP_STATE)
{
svm_node_enter_bump_eval(kg, sd, stack, node.y);
}
break;
SVM_CASE(NODE_LEAVE_BUMP_EVAL)
IF_KERNEL_NODES_FEATURE(BUMP_STATE)
{
svm_node_leave_bump_eval(kg, sd, stack, node.y);
}
break;
SVM_CASE(NODE_HSV)
svm_node_hsv(kg, sd, stack, node);
break;
SVM_CASE(NODE_CLOSURE_HOLDOUT)
svm_node_closure_holdout(sd, stack, node);
break;
SVM_CASE(NODE_FRESNEL)
svm_node_fresnel(sd, stack, node.y, node.z, node.w);
break;
SVM_CASE(NODE_LAYER_WEIGHT)
svm_node_layer_weight(sd, stack, node);
break;
SVM_CASE(NODE_CLOSURE_VOLUME)
IF_KERNEL_NODES_FEATURE(VOLUME)
{
svm_node_closure_volume<type>(kg, sd, stack, node);
}
break;
SVM_CASE(NODE_PRINCIPLED_VOLUME)
IF_KERNEL_NODES_FEATURE(VOLUME)
{
offset = svm_node_principled_volume<type>(kg, sd, stack, node, path_flag, offset);
}
break;
SVM_CASE(NODE_MATH)
svm_node_math(kg, sd, stack, node.y, node.z, node.w);
break;
SVM_CASE(NODE_VECTOR_MATH)
offset = svm_node_vector_math(kg, sd, stack, node.y, node.z, node.w, offset);
break;
SVM_CASE(NODE_RGB_RAMP)
offset = svm_node_rgb_ramp(kg, sd, stack, node, offset);
break;
SVM_CASE(NODE_GAMMA)
svm_node_gamma(sd, stack, node.y, node.z, node.w);
break;
SVM_CASE(NODE_BRIGHTCONTRAST)
svm_node_brightness(sd, stack, node.y, node.z, node.w);
break;
SVM_CASE(NODE_LIGHT_PATH)
svm_node_light_path<node_feature_mask>(kg, state, sd, stack, node.y, node.z, path_flag);
break;
SVM_CASE(NODE_OBJECT_INFO)
svm_node_object_info(kg, sd, stack, node.y, node.z);
break;
SVM_CASE(NODE_PARTICLE_INFO)
svm_node_particle_info(kg, sd, stack, node.y, node.z);
break;
#if defined(__HAIR__)
case NODE_HAIR_INFO:
svm_node_hair_info(kg, sd, stack, node.y, node.z);
break;
SVM_CASE(NODE_HAIR_INFO)
svm_node_hair_info(kg, sd, stack, node.y, node.z);
break;
#endif
#if defined(__POINTCLOUD__)
case NODE_POINT_INFO:
svm_node_point_info(kg, sd, stack, node.y, node.z);
break;
SVM_CASE(NODE_POINT_INFO)
svm_node_point_info(kg, sd, stack, node.y, node.z);
break;
#endif
case NODE_TEXTURE_MAPPING:
offset = svm_node_texture_mapping(kg, sd, stack, node.y, node.z, offset);
break;
case NODE_MAPPING:
svm_node_mapping(kg, sd, stack, node.y, node.z, node.w);
break;
case NODE_MIN_MAX:
offset = svm_node_min_max(kg, sd, stack, node.y, node.z, offset);
break;
case NODE_CAMERA:
svm_node_camera(kg, sd, stack, node.y, node.z, node.w);
break;
case NODE_TEX_ENVIRONMENT:
svm_node_tex_environment(kg, sd, stack, node);
break;
case NODE_TEX_SKY:
offset = svm_node_tex_sky(kg, sd, stack, node, offset);
break;
case NODE_TEX_GRADIENT:
svm_node_tex_gradient(sd, stack, node);
break;
case NODE_TEX_VORONOI:
offset = svm_node_tex_voronoi<node_feature_mask>(
kg, sd, stack, node.y, node.z, node.w, offset);
break;
case NODE_TEX_MUSGRAVE:
offset = svm_node_tex_musgrave(kg, sd, stack, node.y, node.z, node.w, offset);
break;
case NODE_TEX_WAVE:
offset = svm_node_tex_wave(kg, sd, stack, node, offset);
break;
case NODE_TEX_MAGIC:
offset = svm_node_tex_magic(kg, sd, stack, node, offset);
break;
case NODE_TEX_CHECKER:
svm_node_tex_checker(kg, sd, stack, node);
break;
case NODE_TEX_BRICK:
offset = svm_node_tex_brick(kg, sd, stack, node, offset);
break;
case NODE_TEX_WHITE_NOISE:
svm_node_tex_white_noise(kg, sd, stack, node.y, node.z, node.w);
break;
case NODE_NORMAL:
offset = svm_node_normal(kg, sd, stack, node.y, node.z, node.w, offset);
break;
case NODE_LIGHT_FALLOFF:
svm_node_light_falloff(sd, stack, node);
break;
case NODE_IES:
svm_node_ies(kg, sd, stack, node);
break;
case NODE_RGB_CURVES:
case NODE_VECTOR_CURVES:
offset = svm_node_curves(kg, sd, stack, node, offset);
break;
case NODE_FLOAT_CURVE:
offset = svm_node_curve(kg, sd, stack, node, offset);
break;
case NODE_TANGENT:
svm_node_tangent(kg, sd, stack, node);
break;
case NODE_NORMAL_MAP:
svm_node_normal_map(kg, sd, stack, node);
break;
case NODE_INVERT:
svm_node_invert(sd, stack, node.y, node.z, node.w);
break;
case NODE_MIX:
offset = svm_node_mix(kg, sd, stack, node.y, node.z, node.w, offset);
break;
case NODE_SEPARATE_COLOR:
svm_node_separate_color(kg, sd, stack, node.y, node.z, node.w);
break;
case NODE_COMBINE_COLOR:
svm_node_combine_color(kg, sd, stack, node.y, node.z, node.w);
break;
case NODE_SEPARATE_VECTOR:
svm_node_separate_vector(sd, stack, node.y, node.z, node.w);
break;
case NODE_COMBINE_VECTOR:
svm_node_combine_vector(sd, stack, node.y, node.z, node.w);
break;
case NODE_SEPARATE_HSV:
offset = svm_node_separate_hsv(kg, sd, stack, node.y, node.z, node.w, offset);
break;
case NODE_COMBINE_HSV:
offset = svm_node_combine_hsv(kg, sd, stack, node.y, node.z, node.w, offset);
break;
case NODE_VECTOR_ROTATE:
svm_node_vector_rotate(sd, stack, node.y, node.z, node.w);
break;
case NODE_VECTOR_TRANSFORM:
svm_node_vector_transform(kg, sd, stack, node);
break;
case NODE_WIREFRAME:
svm_node_wireframe(kg, sd, stack, node);
break;
case NODE_WAVELENGTH:
svm_node_wavelength(kg, sd, stack, node.y, node.z);
break;
case NODE_BLACKBODY:
svm_node_blackbody(kg, sd, stack, node.y, node.z);
break;
case NODE_MAP_RANGE:
offset = svm_node_map_range(kg, sd, stack, node.y, node.z, node.w, offset);
break;
case NODE_VECTOR_MAP_RANGE:
offset = svm_node_vector_map_range(kg, sd, stack, node.y, node.z, node.w, offset);
break;
case NODE_CLAMP:
offset = svm_node_clamp(kg, sd, stack, node.y, node.z, node.w, offset);
break;
SVM_CASE(NODE_TEXTURE_MAPPING)
offset = svm_node_texture_mapping(kg, sd, stack, node.y, node.z, offset);
break;
SVM_CASE(NODE_MAPPING)
svm_node_mapping(kg, sd, stack, node.y, node.z, node.w);
break;
SVM_CASE(NODE_MIN_MAX)
offset = svm_node_min_max(kg, sd, stack, node.y, node.z, offset);
break;
SVM_CASE(NODE_CAMERA)
svm_node_camera(kg, sd, stack, node.y, node.z, node.w);
break;
SVM_CASE(NODE_TEX_ENVIRONMENT)
svm_node_tex_environment(kg, sd, stack, node);
break;
SVM_CASE(NODE_TEX_SKY)
offset = svm_node_tex_sky(kg, sd, stack, node, offset);
break;
SVM_CASE(NODE_TEX_GRADIENT)
svm_node_tex_gradient(sd, stack, node);
break;
SVM_CASE(NODE_TEX_VORONOI)
offset = svm_node_tex_voronoi<node_feature_mask>(
kg, sd, stack, node.y, node.z, node.w, offset);
break;
SVM_CASE(NODE_TEX_MUSGRAVE)
offset = svm_node_tex_musgrave(kg, sd, stack, node.y, node.z, node.w, offset);
break;
SVM_CASE(NODE_TEX_WAVE)
offset = svm_node_tex_wave(kg, sd, stack, node, offset);
break;
SVM_CASE(NODE_TEX_MAGIC)
offset = svm_node_tex_magic(kg, sd, stack, node, offset);
break;
SVM_CASE(NODE_TEX_CHECKER)
svm_node_tex_checker(kg, sd, stack, node);
break;
SVM_CASE(NODE_TEX_BRICK)
offset = svm_node_tex_brick(kg, sd, stack, node, offset);
break;
SVM_CASE(NODE_TEX_WHITE_NOISE)
svm_node_tex_white_noise(kg, sd, stack, node.y, node.z, node.w);
break;
SVM_CASE(NODE_NORMAL)
offset = svm_node_normal(kg, sd, stack, node.y, node.z, node.w, offset);
break;
SVM_CASE(NODE_LIGHT_FALLOFF)
svm_node_light_falloff(sd, stack, node);
break;
SVM_CASE(NODE_IES)
svm_node_ies(kg, sd, stack, node);
break;
SVM_CASE(NODE_CURVES)
offset = svm_node_curves(kg, sd, stack, node, offset);
break;
SVM_CASE(NODE_FLOAT_CURVE)
offset = svm_node_curve(kg, sd, stack, node, offset);
break;
SVM_CASE(NODE_TANGENT)
svm_node_tangent(kg, sd, stack, node);
break;
SVM_CASE(NODE_NORMAL_MAP)
svm_node_normal_map(kg, sd, stack, node);
break;
SVM_CASE(NODE_INVERT)
svm_node_invert(sd, stack, node.y, node.z, node.w);
break;
SVM_CASE(NODE_MIX)
offset = svm_node_mix(kg, sd, stack, node.y, node.z, node.w, offset);
break;
SVM_CASE(NODE_SEPARATE_COLOR)
svm_node_separate_color(kg, sd, stack, node.y, node.z, node.w);
break;
SVM_CASE(NODE_COMBINE_COLOR)
svm_node_combine_color(kg, sd, stack, node.y, node.z, node.w);
break;
SVM_CASE(NODE_SEPARATE_VECTOR)
svm_node_separate_vector(sd, stack, node.y, node.z, node.w);
break;
SVM_CASE(NODE_COMBINE_VECTOR)
svm_node_combine_vector(sd, stack, node.y, node.z, node.w);
break;
SVM_CASE(NODE_SEPARATE_HSV)
offset = svm_node_separate_hsv(kg, sd, stack, node.y, node.z, node.w, offset);
break;
SVM_CASE(NODE_COMBINE_HSV)
offset = svm_node_combine_hsv(kg, sd, stack, node.y, node.z, node.w, offset);
break;
SVM_CASE(NODE_VECTOR_ROTATE)
svm_node_vector_rotate(sd, stack, node.y, node.z, node.w);
break;
SVM_CASE(NODE_VECTOR_TRANSFORM)
svm_node_vector_transform(kg, sd, stack, node);
break;
SVM_CASE(NODE_WIREFRAME)
svm_node_wireframe(kg, sd, stack, node);
break;
SVM_CASE(NODE_WAVELENGTH)
svm_node_wavelength(kg, sd, stack, node.y, node.z);
break;
SVM_CASE(NODE_BLACKBODY)
svm_node_blackbody(kg, sd, stack, node.y, node.z);
break;
SVM_CASE(NODE_MAP_RANGE)
offset = svm_node_map_range(kg, sd, stack, node.y, node.z, node.w, offset);
break;
SVM_CASE(NODE_VECTOR_MAP_RANGE)
offset = svm_node_vector_map_range(kg, sd, stack, node.y, node.z, node.w, offset);
break;
SVM_CASE(NODE_CLAMP)
offset = svm_node_clamp(kg, sd, stack, node.y, node.z, node.w, offset);
break;
#ifdef __SHADER_RAYTRACE__
case NODE_BEVEL:
svm_node_bevel<node_feature_mask>(kg, state, sd, stack, node);
break;
case NODE_AMBIENT_OCCLUSION:
svm_node_ao<node_feature_mask>(kg, state, sd, stack, node);
break;
SVM_CASE(NODE_BEVEL)
svm_node_bevel<node_feature_mask>(kg, state, sd, stack, node);
break;
SVM_CASE(NODE_AMBIENT_OCCLUSION)
svm_node_ao<node_feature_mask>(kg, state, sd, stack, node);
break;
#endif
case NODE_TEX_VOXEL:
IF_KERNEL_NODES_FEATURE(VOLUME)
{
offset = svm_node_tex_voxel(kg, sd, stack, node, offset);
}
break;
case NODE_AOV_START:
if (!svm_node_aov_check(path_flag, render_buffer)) {
return;
}
break;
case NODE_AOV_COLOR:
svm_node_aov_color<node_feature_mask>(kg, state, sd, stack, node, render_buffer);
break;
case NODE_AOV_VALUE:
svm_node_aov_value<node_feature_mask>(kg, state, sd, stack, node, render_buffer);
break;
SVM_CASE(NODE_TEX_VOXEL)
IF_KERNEL_NODES_FEATURE(VOLUME)
{
offset = svm_node_tex_voxel(kg, sd, stack, node, offset);
}
break;
SVM_CASE(NODE_AOV_START)
if (!svm_node_aov_check(path_flag, render_buffer)) {
return;
}
break;
SVM_CASE(NODE_AOV_COLOR)
svm_node_aov_color<node_feature_mask>(kg, state, sd, stack, node, render_buffer);
break;
SVM_CASE(NODE_AOV_VALUE)
svm_node_aov_value<node_feature_mask>(kg, state, sd, stack, node, render_buffer);
break;
default:
kernel_assert(!"Unknown node type was passed to the SVM machine");
return;

View File

@@ -17,104 +17,9 @@ CCL_NAMESPACE_BEGIN
/* Nodes */
typedef enum ShaderNodeType {
NODE_END = 0,
NODE_SHADER_JUMP,
NODE_CLOSURE_BSDF,
NODE_CLOSURE_EMISSION,
NODE_CLOSURE_BACKGROUND,
NODE_CLOSURE_SET_WEIGHT,
NODE_CLOSURE_WEIGHT,
NODE_EMISSION_WEIGHT,
NODE_MIX_CLOSURE,
NODE_JUMP_IF_ZERO,
NODE_JUMP_IF_ONE,
NODE_GEOMETRY,
NODE_CONVERT,
NODE_TEX_COORD,
NODE_VALUE_F,
NODE_VALUE_V,
NODE_ATTR,
NODE_VERTEX_COLOR,
NODE_GEOMETRY_BUMP_DX,
NODE_GEOMETRY_BUMP_DY,
NODE_SET_DISPLACEMENT,
NODE_DISPLACEMENT,
NODE_VECTOR_DISPLACEMENT,
NODE_TEX_IMAGE,
NODE_TEX_IMAGE_BOX,
NODE_TEX_NOISE,
NODE_SET_BUMP,
NODE_ATTR_BUMP_DX,
NODE_ATTR_BUMP_DY,
NODE_VERTEX_COLOR_BUMP_DX,
NODE_VERTEX_COLOR_BUMP_DY,
NODE_TEX_COORD_BUMP_DX,
NODE_TEX_COORD_BUMP_DY,
NODE_CLOSURE_SET_NORMAL,
NODE_ENTER_BUMP_EVAL,
NODE_LEAVE_BUMP_EVAL,
NODE_HSV,
NODE_CLOSURE_HOLDOUT,
NODE_FRESNEL,
NODE_LAYER_WEIGHT,
NODE_CLOSURE_VOLUME,
NODE_PRINCIPLED_VOLUME,
NODE_MATH,
NODE_VECTOR_MATH,
NODE_RGB_RAMP,
NODE_GAMMA,
NODE_BRIGHTCONTRAST,
NODE_LIGHT_PATH,
NODE_OBJECT_INFO,
NODE_PARTICLE_INFO,
NODE_HAIR_INFO,
NODE_POINT_INFO,
NODE_TEXTURE_MAPPING,
NODE_MAPPING,
NODE_MIN_MAX,
NODE_CAMERA,
NODE_TEX_ENVIRONMENT,
NODE_TEX_SKY,
NODE_TEX_GRADIENT,
NODE_TEX_VORONOI,
NODE_TEX_MUSGRAVE,
NODE_TEX_WAVE,
NODE_TEX_MAGIC,
NODE_TEX_CHECKER,
NODE_TEX_BRICK,
NODE_TEX_WHITE_NOISE,
NODE_NORMAL,
NODE_LIGHT_FALLOFF,
NODE_IES,
NODE_RGB_CURVES,
NODE_VECTOR_CURVES,
NODE_TANGENT,
NODE_NORMAL_MAP,
NODE_INVERT,
NODE_MIX,
NODE_SEPARATE_COLOR,
NODE_COMBINE_COLOR,
NODE_SEPARATE_VECTOR,
NODE_COMBINE_VECTOR,
NODE_SEPARATE_HSV,
NODE_COMBINE_HSV,
NODE_VECTOR_ROTATE,
NODE_VECTOR_TRANSFORM,
NODE_WIREFRAME,
NODE_WAVELENGTH,
NODE_BLACKBODY,
NODE_MAP_RANGE,
NODE_VECTOR_MAP_RANGE,
NODE_CLAMP,
NODE_BEVEL,
NODE_AMBIENT_OCCLUSION,
NODE_TEX_VOXEL,
NODE_AOV_START,
NODE_AOV_COLOR,
NODE_AOV_VALUE,
NODE_FLOAT_CURVE,
/* NOTE: for best OpenCL performance, item definition in the enum must
* match the switch case order in `svm.h`. */
#define SHADER_NODE_TYPE(name) name,
#include "node_types_template.h"
NODE_NUM
} ShaderNodeType;
typedef enum NodeAttributeOutputType {

View File

@@ -6671,7 +6671,7 @@ void CurvesNode::compile(SVMCompiler &compiler,
ShaderInput *fac_in = input("Fac");
compiler.add_node(type,
compiler.add_node(ShaderNodeType(type),
compiler.encode_uchar4(compiler.stack_assign(fac_in),
compiler.stack_assign(value_in),
compiler.stack_assign(value_out),
@@ -6736,7 +6736,7 @@ void RGBCurvesNode::constant_fold(const ConstantFolder &folder)
void RGBCurvesNode::compile(SVMCompiler &compiler)
{
CurvesNode::compile(compiler, NODE_RGB_CURVES, input("Color"), output("Color"));
CurvesNode::compile(compiler, NODE_CURVES, input("Color"), output("Color"));
}
void RGBCurvesNode::compile(OSLCompiler &compiler)
@@ -6774,7 +6774,7 @@ void VectorCurvesNode::constant_fold(const ConstantFolder &folder)
void VectorCurvesNode::compile(SVMCompiler &compiler)
{
CurvesNode::compile(compiler, NODE_VECTOR_CURVES, input("Vector"), output("Vector"));
CurvesNode::compile(compiler, NODE_CURVES, input("Vector"), output("Vector"));
}
void VectorCurvesNode::compile(OSLCompiler &compiler)

View File

@@ -44,8 +44,6 @@ void SVMShaderManager::device_update_shader(Scene *scene,
}
assert(shader->graph);
svm_nodes->push_back_slow(make_int4(NODE_SHADER_JUMP, 0, 0, 0));
SVMCompiler::Summary summary;
SVMCompiler compiler(scene);
compiler.background = (shader == scene->background->get_shader(scene));
@@ -170,6 +168,9 @@ SVMCompiler::SVMCompiler(Scene *scene) : scene(scene)
background = false;
mix_weight_offset = SVM_STACK_INVALID;
compile_failed = false;
/* This struct has one entry for every node, in order of ShaderNodeType definition. */
svm_node_types_used = (std::atomic_int *)&scene->dscene.data.svm_usage;
}
int SVMCompiler::stack_size(SocketType::Type type)
@@ -378,11 +379,13 @@ void SVMCompiler::add_node(int a, int b, int c, int d)
void SVMCompiler::add_node(ShaderNodeType type, int a, int b, int c)
{
svm_node_types_used[type] = true;
current_svm_nodes.push_back_slow(make_int4(type, a, b, c));
}
void SVMCompiler::add_node(ShaderNodeType type, const float3 &f)
{
svm_node_types_used[type] = true;
current_svm_nodes.push_back_slow(
make_int4(type, __float_as_int(f.x), __float_as_int(f.y), __float_as_int(f.z)));
}
@@ -663,6 +666,7 @@ void SVMCompiler::generate_multi_closure(ShaderNode *root_node,
/* Add instruction to skip closure and its dependencies if mix
* weight is zero.
*/
svm_node_types_used[NODE_JUMP_IF_ONE] = true;
current_svm_nodes.push_back_slow(make_int4(NODE_JUMP_IF_ONE, 0, stack_assign(facin), 0));
int node_jump_skip_index = current_svm_nodes.size() - 1;
@@ -678,6 +682,7 @@ void SVMCompiler::generate_multi_closure(ShaderNode *root_node,
/* Add instruction to skip closure and its dependencies if mix
* weight is zero.
*/
svm_node_types_used[NODE_JUMP_IF_ZERO] = true;
current_svm_nodes.push_back_slow(make_int4(NODE_JUMP_IF_ZERO, 0, stack_assign(facin), 0));
int node_jump_skip_index = current_svm_nodes.size() - 1;
@@ -844,6 +849,9 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty
void SVMCompiler::compile(Shader *shader, array<int4> &svm_nodes, int index, Summary *summary)
{
svm_node_types_used[NODE_SHADER_JUMP] = true;
svm_nodes.push_back_slow(make_int4(NODE_SHADER_JUMP, 0, 0, 0));
/* copy graph for shader with bump mapping */
ShaderNode *output = shader->graph->output();
int start_num_svm_nodes = svm_nodes.size();

View File

@@ -211,6 +211,7 @@ class SVMCompiler {
/* compile */
void compile_type(Shader *shader, ShaderGraph *graph, ShaderType type);
std::atomic_int *svm_node_types_used;
array<int4> current_svm_nodes;
ShaderType current_type;
Shader *current_shader;