mirror of
https://github.com/blender/blender
synced 2026-09-29 04:37:17 +03:00
The intel/llvm 7.1 upgrade is giving a large performance regression in shade_surface kernel on Intel GPUs. I've root-caused it down to a slight shift in private memory layout due to slightly different inlining. To fix both this regression and overall performance sensitivity on private memory layout, that can happen with any code change beyond the DPC++ upgrade, I'm forcing ShaderData and svm's stack alignments to 64 bytes. Pull Request: https://projects.blender.org/blender/blender/pulls/164411
718 lines
25 KiB
C++
718 lines
25 KiB
C++
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0 */
|
|
|
|
#pragma once
|
|
|
|
/* Shader Virtual Machine
|
|
*
|
|
* A shader is a list of nodes to be executed. These are simply read one after
|
|
* the other and executed, using an node counter. Each node and its associated
|
|
* data is encoded as one or more uint4's in a 1D texture. If the data is larger
|
|
* than an uint4, the node can increase the node counter to compensate for this.
|
|
* Floats are encoded as int and then converted to float again.
|
|
*
|
|
* Nodes write their output into a stack. All stack data in the stack is
|
|
* floats, since it's all factors, colors and vectors. The stack will be stored
|
|
* in local memory on the GPU, as it would take too many register and indexes in
|
|
* ways not known at compile time. This seems the only solution even though it
|
|
* may be slow, with two positive factors. If the same shader is being executed,
|
|
* memory access will be coalesced and cached.
|
|
*
|
|
* The result of shader execution will be a single closure. This means the
|
|
* closure type, associated label, data and weight. Sampling from multiple
|
|
* closures is supported through the mix closure node, the logic for that is
|
|
* mostly taken care of in the SVM compiler.
|
|
*/
|
|
|
|
#include "kernel/globals.h"
|
|
#include "kernel/types.h"
|
|
|
|
#include "kernel/svm/types.h"
|
|
#include "kernel/svm/util.h"
|
|
|
|
/* Nodes */
|
|
|
|
#include "kernel/svm/aov.h"
|
|
#include "kernel/svm/attribute.h"
|
|
#include "kernel/svm/blackbody.h"
|
|
#include "kernel/svm/boolean_math.h"
|
|
#include "kernel/svm/brick.h"
|
|
#include "kernel/svm/brightness.h"
|
|
#include "kernel/svm/bump.h"
|
|
#include "kernel/svm/camera.h"
|
|
#include "kernel/svm/checker.h"
|
|
#include "kernel/svm/clamp.h"
|
|
#include "kernel/svm/closure.h"
|
|
#include "kernel/svm/convert.h"
|
|
#include "kernel/svm/displace.h"
|
|
#include "kernel/svm/fresnel.h"
|
|
#include "kernel/svm/gabor.h"
|
|
#include "kernel/svm/gamma.h"
|
|
#include "kernel/svm/geometry.h"
|
|
#include "kernel/svm/gradient.h"
|
|
#include "kernel/svm/hsv.h"
|
|
#include "kernel/svm/ies.h"
|
|
#include "kernel/svm/image.h"
|
|
#include "kernel/svm/integer_math.h"
|
|
#include "kernel/svm/invert.h"
|
|
#include "kernel/svm/light_path.h"
|
|
#include "kernel/svm/magic.h"
|
|
#include "kernel/svm/map_range.h"
|
|
#include "kernel/svm/mapping.h"
|
|
#include "kernel/svm/math.h"
|
|
#include "kernel/svm/mix.h"
|
|
#include "kernel/svm/noisetex.h"
|
|
#include "kernel/svm/normal.h"
|
|
#include "kernel/svm/radial_tiling.h"
|
|
#include "kernel/svm/ramp.h"
|
|
#include "kernel/svm/scene_time.h"
|
|
#include "kernel/svm/sepcomb_color.h"
|
|
#include "kernel/svm/sepcomb_vector.h"
|
|
#include "kernel/svm/sky.h"
|
|
#include "kernel/svm/tex_coord.h"
|
|
#include "kernel/svm/value.h"
|
|
#include "kernel/svm/vector_rotate.h"
|
|
#include "kernel/svm/vector_transform.h"
|
|
#include "kernel/svm/vertex_color.h"
|
|
#include "kernel/svm/voronoi.h"
|
|
#include "kernel/svm/wave.h"
|
|
#include "kernel/svm/wavelength.h"
|
|
#include "kernel/svm/white_noise.h"
|
|
#include "kernel/svm/wireframe.h"
|
|
#include "util/defines.h"
|
|
|
|
#ifdef __SHADER_RAYTRACE__
|
|
# include "kernel/svm/ao.h"
|
|
# include "kernel/svm/bevel.h"
|
|
# include "kernel/svm/raycast.h"
|
|
#endif
|
|
|
|
CCL_NAMESPACE_BEGIN
|
|
|
|
#ifdef __KERNEL_USE_DATA_CONSTANTS__
|
|
# define SVM_CASE(node) \
|
|
case node: \
|
|
if (!kernel_data_svm_usage_##node) \
|
|
break;
|
|
#else
|
|
# define SVM_CASE(node) case node:
|
|
#endif
|
|
|
|
/* Main Interpreter Loop */
|
|
template<uint64_t node_feature_mask, ShaderType type, typename ConstIntegratorGenericState>
|
|
ccl_device void svm_eval_nodes(KernelGlobals kg,
|
|
ConstIntegratorGenericState state,
|
|
ccl_private ShaderData *sd,
|
|
ccl_global float *render_buffer,
|
|
const PathRayVisibility path_visibility,
|
|
const uint32_t path_flag)
|
|
{
|
|
#ifdef __KERNEL_ONEAPI__
|
|
/* On Intel GPUs, for large structs in private memory, an alignment of 64 gives the best
|
|
* performance. */
|
|
ccl_align(64) float stack[SVM_STACK_SIZE];
|
|
#else
|
|
float stack[SVM_STACK_SIZE];
|
|
#endif
|
|
/* Initialize to silence (false positive?) warning about uninitialized use on Windows. */
|
|
Spectrum closure_weight = zero_spectrum();
|
|
int offset = (sd->shader & SHADER_MASK) * (1 + sizeof(SVMNodeShaderJump) / sizeof(uint));
|
|
|
|
while (true) {
|
|
const uint node_type = kernel_data_fetch(svm_nodes, offset++);
|
|
|
|
/* NOTE: Every case must always read its full node struct regardless of enabled features,
|
|
* so that the offset advances past the SVM node data. */
|
|
switch (node_type) {
|
|
SVM_CASE(NODE_END)
|
|
return;
|
|
SVM_CASE(NODE_SHADER_JUMP)
|
|
{
|
|
const SVMNodeShaderJump jump = svm_node_get<SVMNodeShaderJump>(kg, &offset);
|
|
if (type == SHADER_TYPE_SURFACE) {
|
|
offset = jump.offset_surface;
|
|
}
|
|
else if (type == SHADER_TYPE_VOLUME) {
|
|
offset = jump.offset_volume;
|
|
}
|
|
else if (type == SHADER_TYPE_DISPLACEMENT) {
|
|
offset = jump.offset_displacement;
|
|
}
|
|
else {
|
|
return;
|
|
}
|
|
break;
|
|
}
|
|
SVM_CASE(NODE_CLOSURE_BSDF)
|
|
{
|
|
const ccl_global SVMNodeClosureBsdf &bsdf_node = svm_node_get<SVMNodeClosureBsdf>(kg,
|
|
&offset);
|
|
offset = svm_node_closure_bsdf<node_feature_mask, type>(
|
|
kg, sd, stack, closure_weight, bsdf_node, path_visibility, path_flag, offset);
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_CLOSURE_EMISSION)
|
|
{
|
|
const ccl_global SVMNodeClosureEmission &bsdf_node = svm_node_get<SVMNodeClosureEmission>(
|
|
kg, &offset);
|
|
IF_KERNEL_NODES_FEATURE(EMISSION)
|
|
{
|
|
svm_node_closure_emission(
|
|
kg, sd, stack, closure_weight, bsdf_node, path_visibility, path_flag);
|
|
}
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_CLOSURE_BACKGROUND)
|
|
{
|
|
const ccl_global auto &node = svm_node_get<SVMNodeClosureBackground>(kg, &offset);
|
|
IF_KERNEL_NODES_FEATURE(EMISSION)
|
|
{
|
|
svm_node_closure_background(sd, stack, closure_weight, node);
|
|
}
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_CLOSURE_SET_WEIGHT)
|
|
svm_node_closure_set_weight(&closure_weight,
|
|
svm_node_get<SVMNodeClosureSetWeight>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_CLOSURE_WEIGHT)
|
|
svm_node_closure_weight(
|
|
stack, &closure_weight, svm_node_get<SVMNodeClosureWeight>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_EMISSION_WEIGHT)
|
|
{
|
|
const ccl_global auto &node = svm_node_get<SVMNodeEmissionWeight>(kg, &offset);
|
|
IF_KERNEL_NODES_FEATURE(EMISSION)
|
|
{
|
|
svm_node_emission_weight(stack, &closure_weight, node);
|
|
}
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_MIX_CLOSURE)
|
|
svm_node_mix_closure(stack, svm_node_get<SVMNodeMixClosure>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_JUMP_IF_ZERO)
|
|
{
|
|
const SVMNodeJumpIfZero jump = svm_node_get<SVMNodeJumpIfZero>(kg, &offset);
|
|
if (stack_load_float(stack, jump.stack_offset) <= 0.0f) {
|
|
offset += jump.jump_offset;
|
|
}
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_JUMP_IF_ONE)
|
|
{
|
|
const SVMNodeJumpIfOne jump = svm_node_get<SVMNodeJumpIfOne>(kg, &offset);
|
|
if (stack_load_float(stack, jump.stack_offset) >= 1.0f) {
|
|
offset += jump.jump_offset;
|
|
}
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_GEOMETRY)
|
|
svm_node_geometry<float3>(kg, sd, stack, svm_node_get<SVMNodeGeometry>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_GEOMETRY_DERIVATIVE)
|
|
{
|
|
const ccl_global auto &node = svm_node_get<SVMNodeGeometry>(kg, &offset);
|
|
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
|
|
{
|
|
svm_node_geometry<dual3>(kg, sd, stack, node);
|
|
}
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_CONVERT)
|
|
svm_node_convert<float, float3>(kg, stack, svm_node_get<SVMNodeConvert>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_CONVERT_DERIVATIVE)
|
|
{
|
|
const ccl_global auto &node = svm_node_get<SVMNodeConvert>(kg, &offset);
|
|
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
|
|
{
|
|
svm_node_convert<dual1, dual3>(kg, stack, node);
|
|
}
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_TEX_COORD)
|
|
{
|
|
const ccl_global auto &node = svm_node_get<SVMNodeTexCoord>(kg, &offset);
|
|
offset = svm_node_tex_coord(kg, sd, path_visibility, stack, node, offset);
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_TEX_COORD_DERIVATIVE)
|
|
{
|
|
const ccl_global auto &node = svm_node_get<SVMNodeTexCoord>(kg, &offset);
|
|
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
|
|
{
|
|
offset = svm_node_tex_coord_derivative(kg, sd, path_visibility, stack, node, offset);
|
|
}
|
|
else {
|
|
offset = svm_node_tex_coord_skip(node, offset);
|
|
}
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_VALUE_F)
|
|
svm_node_value_f<float>(stack, svm_node_get<SVMNodeValueF>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_VALUE_F_DERIVATIVE)
|
|
{
|
|
const ccl_global auto &node = svm_node_get<SVMNodeValueF>(kg, &offset);
|
|
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
|
|
{
|
|
svm_node_value_f<dual1>(stack, node);
|
|
}
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_VALUE_V)
|
|
svm_node_value_v<float3>(stack, svm_node_get<SVMNodeValueV>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_VALUE_V_DERIVATIVE)
|
|
{
|
|
const ccl_global auto &node = svm_node_get<SVMNodeValueV>(kg, &offset);
|
|
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
|
|
{
|
|
svm_node_value_v<dual3>(stack, node);
|
|
}
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_ATTR)
|
|
{
|
|
const ccl_global auto &node = svm_node_get<SVMNodeAttr>(kg, &offset);
|
|
IF_KERNEL_NODES_FEATURE(VOLUME)
|
|
{
|
|
#ifdef __VOLUME__
|
|
svm_node_attr_volume(kg, sd, stack, node);
|
|
#endif
|
|
}
|
|
else {
|
|
svm_node_attr_surface(kg, sd, stack, node);
|
|
}
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_ATTR_DERIVATIVE)
|
|
{
|
|
const ccl_global auto &node = svm_node_get<SVMNodeAttr>(kg, &offset);
|
|
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
|
|
{
|
|
svm_node_attr_derivative(kg, sd, stack, node);
|
|
}
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_VERTEX_COLOR)
|
|
svm_node_vertex_color(kg, sd, stack, svm_node_get<SVMNodeVertexColor>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_VERTEX_COLOR_DERIVATIVE)
|
|
{
|
|
const ccl_global auto &node = svm_node_get<SVMNodeVertexColor>(kg, &offset);
|
|
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
|
|
{
|
|
svm_node_vertex_color_derivative(kg, sd, stack, node);
|
|
}
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_SET_DISPLACEMENT)
|
|
svm_node_set_displacement<node_feature_mask>(
|
|
sd, stack, svm_node_get<SVMNodeSetDisplacement>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_DISPLACEMENT)
|
|
svm_node_displacement<node_feature_mask>(
|
|
kg, sd, stack, svm_node_get<SVMNodeDisplacement>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_VECTOR_DISPLACEMENT)
|
|
svm_node_vector_displacement<node_feature_mask>(
|
|
kg, sd, stack, svm_node_get<SVMNodeVectorDisplacement>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_TEX_IMAGE)
|
|
svm_node_tex_image<float3>(kg, sd, stack, svm_node_get<SVMNodeTexImage>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_TEX_IMAGE_DERIVATIVE)
|
|
{
|
|
const ccl_global auto &node = svm_node_get<SVMNodeTexImage>(kg, &offset);
|
|
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
|
|
{
|
|
svm_node_tex_image<dual3>(kg, sd, stack, node);
|
|
}
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_TEX_IMAGE_BOX)
|
|
svm_node_tex_image_box<float3>(kg, sd, stack, svm_node_get<SVMNodeTexImageBox>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_TEX_IMAGE_BOX_DERIVATIVE)
|
|
{
|
|
const ccl_global auto &node = svm_node_get<SVMNodeTexImageBox>(kg, &offset);
|
|
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
|
|
{
|
|
svm_node_tex_image_box<dual3>(kg, sd, stack, node);
|
|
}
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_TEX_NOISE)
|
|
svm_node_tex_noise(stack, svm_node_get<SVMNodeTexNoise>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_SET_BUMP)
|
|
svm_node_set_bump<node_feature_mask>(
|
|
kg, sd, stack, svm_node_get<SVMNodeSetBump>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_CLOSURE_SET_NORMAL)
|
|
{
|
|
const ccl_global auto &node = svm_node_get<SVMNodeClosureSetNormal>(kg, &offset);
|
|
IF_KERNEL_NODES_FEATURE(BUMP)
|
|
{
|
|
svm_node_set_normal(sd, stack, node);
|
|
}
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_ENTER_BUMP_EVAL)
|
|
{
|
|
const ccl_global auto &node = svm_node_get<SVMNodeEnterBumpEval>(kg, &offset);
|
|
IF_KERNEL_NODES_FEATURE(BUMP_STATE)
|
|
{
|
|
svm_node_enter_bump_eval(kg, sd, stack, node);
|
|
}
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_LEAVE_BUMP_EVAL)
|
|
{
|
|
const ccl_global auto &node = svm_node_get<SVMNodeLeaveBumpEval>(kg, &offset);
|
|
IF_KERNEL_NODES_FEATURE(BUMP_STATE)
|
|
{
|
|
svm_node_leave_bump_eval(sd, stack, node);
|
|
}
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_HSV)
|
|
svm_node_hsv(stack, svm_node_get<SVMNodeHSV>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_CLOSURE_HOLDOUT)
|
|
svm_node_closure_holdout(
|
|
sd, stack, closure_weight, svm_node_get<SVMNodeClosureHoldout>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_FRESNEL)
|
|
svm_node_fresnel(sd, stack, svm_node_get<SVMNodeFresnel>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_LAYER_WEIGHT)
|
|
svm_node_layer_weight(sd, stack, svm_node_get<SVMNodeLayerWeight>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_CLOSURE_VOLUME)
|
|
{
|
|
const ccl_global auto &node = svm_node_get<SVMNodeClosureVolume>(kg, &offset);
|
|
IF_KERNEL_NODES_FEATURE(VOLUME)
|
|
{
|
|
svm_node_closure_volume<type>(kg, sd, stack, closure_weight, node);
|
|
}
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_VOLUME_COEFFICIENTS)
|
|
{
|
|
const ccl_global SVMNodeVolumeCoefficients &bsdf_node =
|
|
svm_node_get<SVMNodeVolumeCoefficients>(kg, &offset);
|
|
IF_KERNEL_NODES_FEATURE(VOLUME)
|
|
{
|
|
svm_node_volume_coefficients<type>(
|
|
kg, sd, stack, closure_weight, bsdf_node, path_visibility, path_flag);
|
|
}
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_PRINCIPLED_VOLUME)
|
|
{
|
|
const ccl_global SVMNodePrincipledVolume &bsdf_node =
|
|
svm_node_get<SVMNodePrincipledVolume>(kg, &offset);
|
|
IF_KERNEL_NODES_FEATURE(VOLUME)
|
|
{
|
|
svm_node_principled_volume<type>(
|
|
kg, sd, stack, closure_weight, bsdf_node, path_visibility, path_flag);
|
|
}
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_MATH)
|
|
svm_node_math(stack, svm_node_get<SVMNodeMath>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_BOOLEAN_MATH)
|
|
svm_node_boolean_math(stack, svm_node_get<SVMNodeBooleanMath>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_INTEGER_MATH)
|
|
svm_node_integer_math(stack, svm_node_get<SVMNodeIntegerMath>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_VECTOR_MATH)
|
|
svm_node_vector_math<float3>(stack, svm_node_get<SVMNodeVectorMath>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_VECTOR_MATH_DERIVATIVE)
|
|
{
|
|
const ccl_global auto &node = svm_node_get<SVMNodeVectorMath>(kg, &offset);
|
|
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
|
|
{
|
|
svm_node_vector_math<dual3>(stack, node);
|
|
}
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_RGB_RAMP)
|
|
{
|
|
const ccl_global auto &node = svm_node_get<SVMNodeRGBRamp>(kg, &offset);
|
|
offset = svm_node_rgb_ramp(kg, stack, node, offset);
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_GAMMA)
|
|
svm_node_gamma(stack, svm_node_get<SVMNodeGamma>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_BRIGHTCONTRAST)
|
|
svm_node_brightness(stack, svm_node_get<SVMNodeBrightContrast>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_LIGHT_PATH)
|
|
svm_node_light_path<node_feature_mask>(kg,
|
|
state,
|
|
sd,
|
|
stack,
|
|
svm_node_get<SVMNodeLightPath>(kg, &offset),
|
|
path_visibility,
|
|
path_flag);
|
|
break;
|
|
SVM_CASE(NODE_OBJECT_INFO)
|
|
svm_node_object_info(kg, sd, stack, svm_node_get<SVMNodeObjectInfo>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_PARTICLE_INFO)
|
|
svm_node_particle_info(kg, sd, stack, svm_node_get<SVMNodeParticleInfo>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_HAIR_INFO)
|
|
svm_node_hair_info(kg, sd, stack, svm_node_get<SVMNodeHairInfo>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_POINT_INFO)
|
|
svm_node_point_info(kg, sd, stack, svm_node_get<SVMNodePointInfo>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_TEXTURE_MAPPING)
|
|
svm_node_texture_mapping<float3>(stack, svm_node_get<SVMNodeTextureMapping>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_TEXTURE_MAPPING_DERIVATIVE)
|
|
{
|
|
const ccl_global auto &node = svm_node_get<SVMNodeTextureMapping>(kg, &offset);
|
|
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
|
|
{
|
|
svm_node_texture_mapping<dual3>(stack, node);
|
|
}
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_MAPPING)
|
|
svm_node_mapping<float3>(stack, svm_node_get<SVMNodeMapping>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_MAPPING_DERIVATIVE)
|
|
{
|
|
const ccl_global auto &node = svm_node_get<SVMNodeMapping>(kg, &offset);
|
|
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
|
|
{
|
|
svm_node_mapping<dual3>(stack, node);
|
|
}
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_MIN_MAX)
|
|
svm_node_min_max(stack, svm_node_get<SVMNodeMinMax>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_CAMERA)
|
|
svm_node_camera(kg, sd, stack, svm_node_get<SVMNodeCamera>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_TEX_ENVIRONMENT)
|
|
svm_node_tex_environment<float3>(
|
|
kg, sd, stack, svm_node_get<SVMNodeTexEnvironment>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_TEX_ENVIRONMENT_DERIVATIVE)
|
|
{
|
|
const ccl_global auto &node = svm_node_get<SVMNodeTexEnvironment>(kg, &offset);
|
|
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
|
|
{
|
|
svm_node_tex_environment<dual3>(kg, sd, stack, node);
|
|
}
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_TEX_SKY)
|
|
{
|
|
const ccl_global auto &node = svm_node_get<SVMNodeTexSky>(kg, &offset);
|
|
offset = svm_node_tex_sky(kg, sd, path_flag, stack, node, offset);
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_TEX_GRADIENT)
|
|
svm_node_tex_gradient(stack, svm_node_get<SVMNodeTexGradient>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_TEX_VORONOI)
|
|
svm_node_tex_voronoi<node_feature_mask>(stack, svm_node_get<SVMNodeTexVoronoi>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_TEX_GABOR)
|
|
svm_node_tex_gabor(stack, svm_node_get<SVMNodeTexGabor>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_TEX_WAVE)
|
|
svm_node_tex_wave(stack, svm_node_get<SVMNodeTexWave>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_TEX_MAGIC)
|
|
svm_node_tex_magic(stack, svm_node_get<SVMNodeTexMagic>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_TEX_CHECKER)
|
|
svm_node_tex_checker(stack, svm_node_get<SVMNodeTexChecker>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_TEX_BRICK)
|
|
svm_node_tex_brick(stack, svm_node_get<SVMNodeTexBrick>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_TEX_WHITE_NOISE)
|
|
svm_node_tex_white_noise(stack, svm_node_get<SVMNodeTexWhiteNoise>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_NORMAL)
|
|
svm_node_normal(stack, svm_node_get<SVMNodeNormal>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_LIGHT_FALLOFF)
|
|
svm_node_light_falloff(sd, stack, svm_node_get<SVMNodeLightFalloff>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_IES)
|
|
svm_node_ies(kg, sd, stack, svm_node_get<SVMNodeIES>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_CURVES)
|
|
{
|
|
const ccl_global auto &node = svm_node_get<SVMNodeCurves>(kg, &offset);
|
|
offset = svm_node_curves(kg, stack, node, offset);
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_TANGENT)
|
|
svm_node_tangent<float3>(kg, sd, stack, svm_node_get<SVMNodeTangent>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_TANGENT_DERIVATIVE)
|
|
{
|
|
const ccl_global auto &node = svm_node_get<SVMNodeTangent>(kg, &offset);
|
|
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
|
|
{
|
|
svm_node_tangent<dual3>(kg, sd, stack, node);
|
|
}
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_NORMAL_MAP)
|
|
svm_node_normal_map(kg, sd, stack, svm_node_get<SVMNodeNormalMap>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_RADIAL_TILING)
|
|
svm_node_radial_tiling<node_feature_mask>(stack,
|
|
svm_node_get<SVMNodeRadialTiling>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_INVERT)
|
|
svm_node_invert(stack, svm_node_get<SVMNodeInvert>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_MIX)
|
|
svm_node_mix(stack, svm_node_get<SVMNodeMix>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_SEPARATE_COLOR)
|
|
svm_node_separate_color(stack, svm_node_get<SVMNodeSeparateColor>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_COMBINE_COLOR)
|
|
svm_node_combine_color(stack, svm_node_get<SVMNodeCombineColor>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_SEPARATE_VECTOR)
|
|
svm_node_separate_vector<float3>(stack, svm_node_get<SVMNodeSeparateVector>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_SEPARATE_VECTOR_DERIVATIVE)
|
|
{
|
|
const ccl_global auto &node = svm_node_get<SVMNodeSeparateVector>(kg, &offset);
|
|
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
|
|
{
|
|
svm_node_separate_vector<dual3>(stack, node);
|
|
}
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_COMBINE_VECTOR)
|
|
svm_node_combine_vector<float3>(stack, svm_node_get<SVMNodeCombineVector>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_COMBINE_VECTOR_DERIVATIVE)
|
|
{
|
|
const ccl_global auto &node = svm_node_get<SVMNodeCombineVector>(kg, &offset);
|
|
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
|
|
{
|
|
svm_node_combine_vector<dual3>(stack, node);
|
|
}
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_GET_VECTOR_COMPONENT)
|
|
svm_node_get_vector_component<float3>(stack,
|
|
svm_node_get<SVMNodeGetVectorComponent>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_GET_VECTOR_COMPONENT_DERIVATIVE)
|
|
{
|
|
const ccl_global auto &node = svm_node_get<SVMNodeGetVectorComponent>(kg, &offset);
|
|
IF_NOT_KERNEL_NODES_FEATURE(VOLUME)
|
|
{
|
|
svm_node_get_vector_component<dual3>(stack, node);
|
|
}
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_VECTOR_ROTATE)
|
|
svm_node_vector_rotate(stack, svm_node_get<SVMNodeVectorRotate>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_VECTOR_TRANSFORM)
|
|
svm_node_vector_transform(kg, sd, stack, svm_node_get<SVMNodeVectorTransform>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_WIREFRAME)
|
|
svm_node_wireframe(kg, sd, stack, svm_node_get<SVMNodeWireframe>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_WAVELENGTH)
|
|
svm_node_wavelength(kg, stack, svm_node_get<SVMNodeWavelength>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_BLACKBODY)
|
|
svm_node_blackbody(kg, stack, svm_node_get<SVMNodeBlackbody>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_MAP_RANGE)
|
|
svm_node_map_range(stack, svm_node_get<SVMNodeMapRange>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_VECTOR_MAP_RANGE)
|
|
svm_node_vector_map_range(stack, svm_node_get<SVMNodeVectorMapRange>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_CLAMP)
|
|
svm_node_clamp(stack, svm_node_get<SVMNodeClamp>(kg, &offset));
|
|
break;
|
|
#ifdef __SHADER_RAYTRACE__
|
|
SVM_CASE(NODE_BEVEL)
|
|
svm_node_bevel<node_feature_mask>(
|
|
kg, state, sd, stack, svm_node_get<SVMNodeBevel>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_AMBIENT_OCCLUSION)
|
|
svm_node_ao<node_feature_mask>(
|
|
kg, state, sd, stack, svm_node_get<SVMNodeAmbientOcclusion>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_RAYCAST)
|
|
{
|
|
const ccl_global auto &node = svm_node_get<SVMNodeRaycast>(kg, &offset);
|
|
offset = svm_node_raycast<node_feature_mask>(kg, state, sd, stack, node, offset);
|
|
}
|
|
break;
|
|
#endif
|
|
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, sd, state, stack, svm_node_get<SVMNodeAOVColor>(kg, &offset), render_buffer);
|
|
break;
|
|
SVM_CASE(NODE_AOV_VALUE)
|
|
svm_node_aov_value<node_feature_mask>(
|
|
kg, sd, state, stack, svm_node_get<SVMNodeAOVValue>(kg, &offset), render_buffer);
|
|
break;
|
|
SVM_CASE(NODE_FLOAT_CURVE)
|
|
{
|
|
const ccl_global auto &node = svm_node_get<SVMNodeFloatCurve>(kg, &offset);
|
|
offset = svm_node_curve(kg, stack, node, offset);
|
|
}
|
|
break;
|
|
SVM_CASE(NODE_MIX_COLOR)
|
|
svm_node_mix_color(stack, svm_node_get<SVMNodeMixColor>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_MIX_FLOAT)
|
|
svm_node_mix_float(stack, svm_node_get<SVMNodeMixFloat>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_MIX_VECTOR)
|
|
svm_node_mix_vector(stack, svm_node_get<SVMNodeMixVector>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_MIX_VECTOR_NON_UNIFORM)
|
|
svm_node_mix_vector_non_uniform(stack,
|
|
svm_node_get<SVMNodeMixVectorNonUniform>(kg, &offset));
|
|
break;
|
|
SVM_CASE(NODE_SCENE_TIME)
|
|
svm_node_scene_time(kg, stack, svm_node_get<SVMNodeSceneTime>(kg, &offset));
|
|
break;
|
|
default:
|
|
kernel_assert(!"Unknown node type was passed to the SVM machine");
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
CCL_NAMESPACE_END
|