Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/kernel/integrator/integrator_state.h
| Show All 21 Lines | |||||
| * The size of this state must be kept as small as possible, to reduce cache misses and keep memory | * The size of this state must be kept as small as possible, to reduce cache misses and keep memory | ||||
| * usage under control on GPUs that may execute millions of kernels. | * usage under control on GPUs that may execute millions of kernels. | ||||
| * | * | ||||
| * Memory may be allocated and passed along in different ways depending on the device. There may | * Memory may be allocated and passed along in different ways depending on the device. There may | ||||
| * be a scalar layout, or AoS or SoA layout for batches. The state may be passed along as a pointer | * be a scalar layout, or AoS or SoA layout for batches. The state may be passed along as a pointer | ||||
| * to every kernel, or the pointer may exist at program scope or in constant memory. To abstract | * to every kernel, or the pointer may exist at program scope or in constant memory. To abstract | ||||
| * these differences between devices and experiment with different layouts, macros are used. | * these differences between devices and experiment with different layouts, macros are used. | ||||
| * | * | ||||
| * INTEGRATOR_STATE_ARGS: prepend to argument definitions for every function that accesses | * Use IntegratorState to pass a reference to the integrator state for the current path. These are | ||||
| * path state. | * defined differently on the CPU and GPU. Use ConstIntegratorState instead of const | ||||
| * INTEGRATOR_STATE_CONST_ARGS: same as INTEGRATOR_STATE_ARGS, when state is read-only | * IntegratorState for passing state as read-only, to avoid oddities in typedef behavior. | ||||
| * INTEGRATOR_STATE_PASS: use to pass along state to other functions access it. | |||||
| * | * | ||||
| * INTEGRATOR_STATE(x, y): read nested struct member x.y of IntegratorState | * INTEGRATOR_STATE(state, x, y): read nested struct member x.y of IntegratorState | ||||
| * INTEGRATOR_STATE_WRITE(x, y): write to nested struct member x.y of IntegratorState | * INTEGRATOR_STATE_WRITE(state, x, y): write to nested struct member x.y of IntegratorState | ||||
| * | * | ||||
| * INTEGRATOR_STATE_ARRAY(x, index, y): read x[index].y | * INTEGRATOR_STATE_ARRAY(state, x, index, y): read x[index].y | ||||
| * INTEGRATOR_STATE_ARRAY_WRITE(x, index, y): write x[index].y | * INTEGRATOR_STATE_ARRAY_WRITE(state, x, index, y): write x[index].y | ||||
| * | * | ||||
| * INTEGRATOR_STATE_COPY(to_x, from_x): copy contents of one nested struct to another | * INTEGRATOR_STATE_NULL: use to pass empty state to other functions. | ||||
| * | |||||
| * INTEGRATOR_STATE_IS_NULL: test if any integrator state is available, for shader evaluation | |||||
| * INTEGRATOR_STATE_PASS_NULL: use to pass empty state to other functions. | |||||
| * | |||||
| * NOTE: if we end up with a device that passes no arguments, the leading comma will be a problem. | |||||
| * Can solve it with more macros if we encounter it, but rather ugly so postpone for now. | |||||
| */ | */ | ||||
| #include "kernel/kernel_types.h" | #include "kernel/kernel_types.h" | ||||
| #include "util/util_types.h" | #include "util/util_types.h" | ||||
| #pragma once | #pragma once | ||||
| ▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | |||||
| * happen from a kernel which operates on a "main" path. Attempt to use shadow catcher accessors | * happen from a kernel which operates on a "main" path. Attempt to use shadow catcher accessors | ||||
| * from a kernel which operates on a shadow catcher state will cause bad memory access. */ | * from a kernel which operates on a shadow catcher state will cause bad memory access. */ | ||||
| #ifdef __KERNEL_CPU__ | #ifdef __KERNEL_CPU__ | ||||
| /* Scalar access on CPU. */ | /* Scalar access on CPU. */ | ||||
| typedef IntegratorStateCPU *ccl_restrict IntegratorState; | typedef IntegratorStateCPU *ccl_restrict IntegratorState; | ||||
| typedef const IntegratorStateCPU *ccl_restrict ConstIntegratorState; | |||||
| # define INTEGRATOR_STATE_NULL nullptr | |||||
| # define INTEGRATOR_STATE_ARGS \ | # define INTEGRATOR_STATE(state, nested_struct, member) ((state)->nested_struct.member) | ||||
| ccl_attr_maybe_unused const KernelGlobals *ccl_restrict kg, \ | # define INTEGRATOR_STATE_WRITE(state, nested_struct, member) ((state)->nested_struct.member) | ||||
| IntegratorStateCPU *ccl_restrict state | |||||
| # define INTEGRATOR_STATE_CONST_ARGS \ | # define INTEGRATOR_STATE_ARRAY(state, nested_struct, array_index, member) \ | ||||
| ccl_attr_maybe_unused const KernelGlobals *ccl_restrict kg, \ | ((state)->nested_struct[array_index].member) | ||||
| const IntegratorStateCPU *ccl_restrict state | # define INTEGRATOR_STATE_ARRAY_WRITE(state, nested_struct, array_index, member) \ | ||||
| # define INTEGRATOR_STATE_PASS kg, state | |||||
| # define INTEGRATOR_STATE_PASS_NULL kg, NULL | |||||
| # define INTEGRATOR_STATE_IS_NULL (state == NULL) | |||||
| # define INTEGRATOR_STATE(nested_struct, member) \ | |||||
| (((const IntegratorStateCPU *)state)->nested_struct.member) | |||||
| # define INTEGRATOR_STATE_WRITE(nested_struct, member) (state->nested_struct.member) | |||||
| # define INTEGRATOR_STATE_ARRAY(nested_struct, array_index, member) \ | |||||
| (((const IntegratorStateCPU *)state)->nested_struct[array_index].member) | |||||
| # define INTEGRATOR_STATE_ARRAY_WRITE(nested_struct, array_index, member) \ | |||||
| ((state)->nested_struct[array_index].member) | ((state)->nested_struct[array_index].member) | ||||
| #else /* __KERNEL_CPU__ */ | #else /* __KERNEL_CPU__ */ | ||||
| /* Array access on GPU with Structure-of-Arrays. */ | /* Array access on GPU with Structure-of-Arrays. */ | ||||
| typedef int IntegratorState; | typedef const int IntegratorState; | ||||
| typedef const int ConstIntegratorState; | |||||
| # define INTEGRATOR_STATE_ARGS \ | |||||
| ccl_global const KernelGlobals *ccl_restrict kg, const IntegratorState state | |||||
| # define INTEGRATOR_STATE_CONST_ARGS \ | |||||
| ccl_global const KernelGlobals *ccl_restrict kg, const IntegratorState state | |||||
| # define INTEGRATOR_STATE_PASS kg, state | |||||
| # define INTEGRATOR_STATE_PASS_NULL kg, -1 | # define INTEGRATOR_STATE_NULL -1 | ||||
| # define INTEGRATOR_STATE_IS_NULL (state == -1) | |||||
| # define INTEGRATOR_STATE(nested_struct, member) \ | # define INTEGRATOR_STATE(state, nested_struct, member) \ | ||||
| kernel_integrator_state.nested_struct.member[state] | kernel_integrator_state.nested_struct.member[state] | ||||
| # define INTEGRATOR_STATE_WRITE(nested_struct, member) INTEGRATOR_STATE(nested_struct, member) | # define INTEGRATOR_STATE_WRITE(state, nested_struct, member) \ | ||||
| INTEGRATOR_STATE(state, nested_struct, member) | |||||
| # define INTEGRATOR_STATE_ARRAY(nested_struct, array_index, member) \ | # define INTEGRATOR_STATE_ARRAY(state, nested_struct, array_index, member) \ | ||||
| kernel_integrator_state.nested_struct[array_index].member[state] | kernel_integrator_state.nested_struct[array_index].member[state] | ||||
| # define INTEGRATOR_STATE_ARRAY_WRITE(nested_struct, array_index, member) \ | # define INTEGRATOR_STATE_ARRAY_WRITE(state, nested_struct, array_index, member) \ | ||||
| INTEGRATOR_STATE_ARRAY(nested_struct, array_index, member) | INTEGRATOR_STATE_ARRAY(state, nested_struct, array_index, member) | ||||
| #endif /* __KERNEL_CPU__ */ | #endif /* __KERNEL_CPU__ */ | ||||
| CCL_NAMESPACE_END | CCL_NAMESPACE_END | ||||