Cycles: Improve Metal kernel specialisation

This improves the existing scene specialisation mechanism by replacing "kernel_data.kernel_features" with a function constant. It doesn't cause any additional compilation requests, but allows the backend compiler to eliminate more dead code. An additional compiler hint is provided for dead-stripping "volume_stack_enter_exit" which results in slightly faster rendering of non-volumetric scenes.

Pull Request: https://projects.blender.org/blender/blender/pulls/142235
This commit is contained in:
Michael Jones
2025-07-18 11:18:43 +02:00
committed by Michael Jones (Apple)
parent a565e96f6c
commit 8077384e3a
4 changed files with 21 additions and 0 deletions

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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 */