forked from bartvdbraak/blender
Cycles: Adapt volumetric lambda functions to work on MSL
This patch adapts the existing volumetric read/write lambda functions for Metal. Lambda expressions are not supported on MSL, so two new macros `VOLUME_READ_LAMBDA` and `VOLUME_WRITE_LAMBDA` have been defined with a default implementation which, on Metal, is overridden to use inline function objects. This patch also removes the last remaining mention of the now-unused `ccl_addr_space`. Ref T92212 Reviewed By: leesonw Maniphest Tasks: T92212 Differential Revision: https://developer.blender.org/D13234
This commit is contained in:
parent
85ac9b8584
commit
64003fa4b0
@ -150,6 +150,31 @@ void kernel_gpu_##name::run(thread MetalKernelContext& context, \
|
||||
|
||||
// clang-format on
|
||||
|
||||
/* volumetric lambda functions - use function objects for lambda-like functionality */
|
||||
#define VOLUME_READ_LAMBDA(function_call) \
|
||||
struct FnObjectRead { \
|
||||
KernelGlobals kg; \
|
||||
ccl_private MetalKernelContext *context; \
|
||||
int state; \
|
||||
\
|
||||
VolumeStack operator()(const int i) const \
|
||||
{ \
|
||||
return context->function_call; \
|
||||
} \
|
||||
} volume_read_lambda_pass{kg, this, state};
|
||||
|
||||
#define VOLUME_WRITE_LAMBDA(function_call) \
|
||||
struct FnObjectWrite { \
|
||||
KernelGlobals kg; \
|
||||
ccl_private MetalKernelContext *context; \
|
||||
int state; \
|
||||
\
|
||||
void operator()(const int i, VolumeStack entry) const \
|
||||
{ \
|
||||
context->function_call; \
|
||||
} \
|
||||
} volume_write_lambda_pass{kg, this, state};
|
||||
|
||||
/* make_type definitions with Metal style element initializers */
|
||||
#ifdef make_float2
|
||||
# undef make_float2
|
||||
|
@ -95,8 +95,8 @@ ccl_device_inline void integrate_transparent_volume_shadow(KernelGlobals kg,
|
||||
|
||||
shader_setup_from_volume(kg, shadow_sd, &ray);
|
||||
|
||||
const float step_size = volume_stack_step_size(
|
||||
kg, [=](const int i) { return integrator_state_read_shadow_volume_stack(state, i); });
|
||||
VOLUME_READ_LAMBDA(integrator_state_read_shadow_volume_stack(state, i));
|
||||
const float step_size = volume_stack_step_size(kg, volume_read_lambda_pass);
|
||||
|
||||
volume_shadow_heterogeneous(kg, state, &ray, shadow_sd, throughput, step_size);
|
||||
}
|
||||
|
@ -78,9 +78,8 @@ ccl_device_inline bool shadow_volume_shader_sample(KernelGlobals kg,
|
||||
ccl_private ShaderData *ccl_restrict sd,
|
||||
ccl_private float3 *ccl_restrict extinction)
|
||||
{
|
||||
shader_eval_volume<true>(kg, state, sd, PATH_RAY_SHADOW, [=](const int i) {
|
||||
return integrator_state_read_shadow_volume_stack(state, i);
|
||||
});
|
||||
VOLUME_READ_LAMBDA(integrator_state_read_shadow_volume_stack(state, i))
|
||||
shader_eval_volume<true>(kg, state, sd, PATH_RAY_SHADOW, volume_read_lambda_pass);
|
||||
|
||||
if (!(sd->flag & SD_EXTINCTION)) {
|
||||
return false;
|
||||
@ -98,9 +97,8 @@ ccl_device_inline bool volume_shader_sample(KernelGlobals kg,
|
||||
ccl_private VolumeShaderCoefficients *coeff)
|
||||
{
|
||||
const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
|
||||
shader_eval_volume<false>(kg, state, sd, path_flag, [=](const int i) {
|
||||
return integrator_state_read_volume_stack(state, i);
|
||||
});
|
||||
VOLUME_READ_LAMBDA(integrator_state_read_volume_stack(state, i))
|
||||
shader_eval_volume<false>(kg, state, sd, path_flag, volume_read_lambda_pass);
|
||||
|
||||
if (!(sd->flag & (SD_EXTINCTION | SD_SCATTER | SD_EMISSION))) {
|
||||
return false;
|
||||
@ -921,8 +919,8 @@ ccl_device VolumeIntegrateEvent volume_integrate(KernelGlobals kg,
|
||||
VOLUME_SAMPLE_DISTANCE;
|
||||
|
||||
/* Step through volume. */
|
||||
const float step_size = volume_stack_step_size(
|
||||
kg, [=](const int i) { return integrator_state_read_volume_stack(state, i); });
|
||||
VOLUME_READ_LAMBDA(integrator_state_read_volume_stack(state, i))
|
||||
const float step_size = volume_stack_step_size(kg, volume_read_lambda_pass);
|
||||
|
||||
/* TODO: expensive to zero closures? */
|
||||
VolumeIntegrateResult result = {};
|
||||
|
@ -18,6 +18,14 @@
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* Volumetric read/write lambda functions - default implementations */
|
||||
#ifndef VOLUME_READ_LAMBDA
|
||||
# define VOLUME_READ_LAMBDA(function_call) \
|
||||
auto volume_read_lambda_pass = [=](const int i) { return function_call; };
|
||||
# define VOLUME_WRITE_LAMBDA(function_call) \
|
||||
auto volume_write_lambda_pass = [=](const int i, VolumeStack entry) { function_call; };
|
||||
#endif
|
||||
|
||||
/* Volume Stack
|
||||
*
|
||||
* This is an array of object/shared ID's that the current segment of the path
|
||||
@ -88,26 +96,18 @@ ccl_device void volume_stack_enter_exit(KernelGlobals kg,
|
||||
IntegratorState state,
|
||||
ccl_private const ShaderData *sd)
|
||||
{
|
||||
volume_stack_enter_exit(
|
||||
kg,
|
||||
sd,
|
||||
[=](const int i) { return integrator_state_read_volume_stack(state, i); },
|
||||
[=](const int i, const VolumeStack entry) {
|
||||
integrator_state_write_volume_stack(state, i, entry);
|
||||
});
|
||||
VOLUME_READ_LAMBDA(integrator_state_read_volume_stack(state, i))
|
||||
VOLUME_WRITE_LAMBDA(integrator_state_write_volume_stack(state, i, entry))
|
||||
volume_stack_enter_exit(kg, sd, volume_read_lambda_pass, volume_write_lambda_pass);
|
||||
}
|
||||
|
||||
ccl_device void shadow_volume_stack_enter_exit(KernelGlobals kg,
|
||||
IntegratorShadowState state,
|
||||
ccl_private const ShaderData *sd)
|
||||
{
|
||||
volume_stack_enter_exit(
|
||||
kg,
|
||||
sd,
|
||||
[=](const int i) { return integrator_state_read_shadow_volume_stack(state, i); },
|
||||
[=](const int i, const VolumeStack entry) {
|
||||
integrator_state_write_shadow_volume_stack(state, i, entry);
|
||||
});
|
||||
VOLUME_READ_LAMBDA(integrator_state_read_shadow_volume_stack(state, i))
|
||||
VOLUME_WRITE_LAMBDA(integrator_state_write_shadow_volume_stack(state, i, entry))
|
||||
volume_stack_enter_exit(kg, sd, volume_read_lambda_pass, volume_write_lambda_pass);
|
||||
}
|
||||
|
||||
/* Clean stack after the last bounce.
|
||||
|
@ -36,13 +36,6 @@
|
||||
# define __KERNEL_CPU__
|
||||
#endif
|
||||
|
||||
/* TODO(sergey): This is only to make it possible to include this header
|
||||
* from outside of the kernel. but this could be done somewhat cleaner?
|
||||
*/
|
||||
#ifndef ccl_addr_space
|
||||
# define ccl_addr_space
|
||||
#endif
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* Constants */
|
||||
|
Loading…
Reference in New Issue
Block a user