diff --git a/intern/cycles/device/metal/device_impl.mm b/intern/cycles/device/metal/device_impl.mm index 218183a0af4..e7f9151d952 100644 --- a/intern/cycles/device/metal/device_impl.mm +++ b/intern/cycles/device/metal/device_impl.mm @@ -309,6 +309,10 @@ string MetalDevice::preprocess_source(MetalPipelineType pso_type, # undef KERNEL_STRUCT_MEMBER_DONT_SPECIALIZE # undef KERNEL_STRUCT_BEGIN + /* Replace "kernel_data.kernel_features" memory fetches with a function constant. */ + string_replace_same_length( + *source, "kernel_data.kernel_features", "kernel_data_kernel_features"); + metal_printf("KernelData patching took %.1f ms", (time_dt() - starttime) * 1000.0); } diff --git a/intern/cycles/device/metal/kernel.mm b/intern/cycles/device/metal/kernel.mm index 79e90526a27..64ddf316d6a 100644 --- a/intern/cycles/device/metal/kernel.mm +++ b/intern/cycles/device/metal/kernel.mm @@ -461,6 +461,10 @@ static MTLFunctionConstantValues *GetConstantValues(const KernelData *data = nul # include "kernel/data_template.h" + [constant_values setConstantValue:&data->kernel_features + type:MTLDataTypeInt + atIndex:KernelData_kernel_features]; + return constant_values; } diff --git a/intern/cycles/kernel/device/metal/function_constants.h b/intern/cycles/kernel/device/metal/function_constants.h index 17fb034300d..4fed68bd199 100644 --- a/intern/cycles/kernel/device/metal/function_constants.h +++ b/intern/cycles/kernel/device/metal/function_constants.h @@ -6,6 +6,8 @@ enum { Kernel_DummyConstant, #define KERNEL_STRUCT_MEMBER(parent, type, name) KernelData_##parent##_##name, #include "kernel/data_template.h" + + KernelData_kernel_features }; #ifdef __KERNEL_METAL__ @@ -13,4 +15,6 @@ enum { constant type kernel_data_##parent##_##name \ [[function_constant(KernelData_##parent##_##name)]]; # include "kernel/data_template.h" + +constant int kernel_data_kernel_features [[function_constant(KernelData_kernel_features)]]; #endif diff --git a/intern/cycles/kernel/integrator/volume_stack.h b/intern/cycles/kernel/integrator/volume_stack.h index 95f84be385f..094a38caaea 100644 --- a/intern/cycles/kernel/integrator/volume_stack.h +++ b/intern/cycles/kernel/integrator/volume_stack.h @@ -27,6 +27,15 @@ ccl_device void volume_stack_enter_exit(KernelGlobals kg, StackReadOp stack_read, StackWriteOp stack_write) { +# ifdef __KERNEL_USE_DATA_CONSTANTS__ + /* If we're using data constants, this fetch disappears. + * On Apple GPUs, scenes without volumetric features can render 1 or 2% faster by dead-stripping + * this function. */ + if (!(kernel_data.kernel_features & KERNEL_FEATURE_VOLUME)) { + return; + } +# endif + /* todo: we should have some way for objects to indicate if they want the * world shader to work inside them. excluding it by default is problematic * because non-volume objects can't be assumed to be closed manifolds */