2022-02-11 13:53:21 +01:00
|
|
|
/* SPDX-License-Identifier: Apache-2.0
|
|
|
|
|
* Copyright 2011-2022 Blender Foundation */
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
2021-10-24 14:19:19 +02:00
|
|
|
#include "kernel/types.h"
|
|
|
|
|
#include "util/atomic.h"
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
|
|
|
|
|
CCL_NAMESPACE_BEGIN
|
|
|
|
|
|
|
|
|
|
/* Control Flow
|
|
|
|
|
*
|
2022-07-13 14:22:42 +02:00
|
|
|
* Utilities for control flow between kernels. The implementation is different between CPU and
|
|
|
|
|
* GPU devices. For the latter part of the logic is handled on the host side with wavefronts.
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
*
|
|
|
|
|
* There is a main path for regular path tracing camera for path tracing. Shadows for next
|
|
|
|
|
* event estimation branch off from this into their own path, that may be computed in
|
2022-07-13 14:22:42 +02:00
|
|
|
* parallel while the main path continues. Additionally, shading kernels are sorted using
|
|
|
|
|
* a key for coherence.
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
*
|
|
|
|
|
* Each kernel on the main path must call one of these functions. These may not be called
|
|
|
|
|
* multiple times from the same kernel.
|
|
|
|
|
*
|
2022-07-13 14:22:42 +02:00
|
|
|
* integrator_path_init(kg, state, next_kernel)
|
|
|
|
|
* integrator_path_next(kg, state, current_kernel, next_kernel)
|
|
|
|
|
* integrator_path_terminate(kg, state, current_kernel)
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
*
|
|
|
|
|
* For the shadow path similar functions are used, and again each shadow kernel must call
|
|
|
|
|
* one of them, and only once.
|
|
|
|
|
*/
|
|
|
|
|
|
2022-07-13 14:22:42 +02:00
|
|
|
ccl_device_forceinline bool integrator_path_is_terminated(ConstIntegratorState state)
|
|
|
|
|
{
|
|
|
|
|
return INTEGRATOR_STATE(state, path, queued_kernel) == 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ccl_device_forceinline bool integrator_shadow_path_is_terminated(ConstIntegratorShadowState state)
|
|
|
|
|
{
|
|
|
|
|
return INTEGRATOR_STATE(state, shadow_path, queued_kernel) == 0;
|
|
|
|
|
}
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
|
|
|
|
|
#ifdef __KERNEL_GPU__
|
|
|
|
|
|
2022-07-13 14:22:42 +02:00
|
|
|
ccl_device_forceinline void integrator_path_init(KernelGlobals kg,
|
|
|
|
|
IntegratorState state,
|
|
|
|
|
const DeviceKernel next_kernel)
|
|
|
|
|
{
|
|
|
|
|
atomic_fetch_and_add_uint32(&kernel_integrator_state.queue_counter->num_queued[next_kernel], 1);
|
|
|
|
|
INTEGRATOR_STATE_WRITE(state, path, queued_kernel) = next_kernel;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ccl_device_forceinline void integrator_path_next(KernelGlobals kg,
|
|
|
|
|
IntegratorState state,
|
|
|
|
|
const DeviceKernel current_kernel,
|
|
|
|
|
const DeviceKernel next_kernel)
|
|
|
|
|
{
|
|
|
|
|
atomic_fetch_and_sub_uint32(&kernel_integrator_state.queue_counter->num_queued[current_kernel],
|
|
|
|
|
1);
|
|
|
|
|
atomic_fetch_and_add_uint32(&kernel_integrator_state.queue_counter->num_queued[next_kernel], 1);
|
|
|
|
|
INTEGRATOR_STATE_WRITE(state, path, queued_kernel) = next_kernel;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ccl_device_forceinline void integrator_path_terminate(KernelGlobals kg,
|
|
|
|
|
IntegratorState state,
|
|
|
|
|
const DeviceKernel current_kernel)
|
|
|
|
|
{
|
|
|
|
|
atomic_fetch_and_sub_uint32(&kernel_integrator_state.queue_counter->num_queued[current_kernel],
|
|
|
|
|
1);
|
|
|
|
|
INTEGRATOR_STATE_WRITE(state, path, queued_kernel) = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ccl_device_forceinline IntegratorShadowState integrator_shadow_path_init(
|
|
|
|
|
KernelGlobals kg, IntegratorState state, const DeviceKernel next_kernel, const bool is_ao)
|
|
|
|
|
{
|
|
|
|
|
IntegratorShadowState shadow_state = atomic_fetch_and_add_uint32(
|
|
|
|
|
&kernel_integrator_state.next_shadow_path_index[0], 1);
|
|
|
|
|
atomic_fetch_and_add_uint32(&kernel_integrator_state.queue_counter->num_queued[next_kernel], 1);
|
|
|
|
|
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, queued_kernel) = next_kernel;
|
2022-10-18 13:59:12 +02:00
|
|
|
# ifdef __PATH_GUIDING__
|
|
|
|
|
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, path_segment) = nullptr;
|
|
|
|
|
# endif
|
2022-07-13 14:22:42 +02:00
|
|
|
return shadow_state;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ccl_device_forceinline void integrator_shadow_path_next(KernelGlobals kg,
|
|
|
|
|
IntegratorShadowState state,
|
|
|
|
|
const DeviceKernel current_kernel,
|
|
|
|
|
const DeviceKernel next_kernel)
|
|
|
|
|
{
|
|
|
|
|
atomic_fetch_and_sub_uint32(&kernel_integrator_state.queue_counter->num_queued[current_kernel],
|
|
|
|
|
1);
|
|
|
|
|
atomic_fetch_and_add_uint32(&kernel_integrator_state.queue_counter->num_queued[next_kernel], 1);
|
|
|
|
|
INTEGRATOR_STATE_WRITE(state, shadow_path, queued_kernel) = next_kernel;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ccl_device_forceinline void integrator_shadow_path_terminate(KernelGlobals kg,
|
|
|
|
|
IntegratorShadowState state,
|
|
|
|
|
const DeviceKernel current_kernel)
|
|
|
|
|
{
|
|
|
|
|
atomic_fetch_and_sub_uint32(&kernel_integrator_state.queue_counter->num_queued[current_kernel],
|
|
|
|
|
1);
|
|
|
|
|
INTEGRATOR_STATE_WRITE(state, shadow_path, queued_kernel) = 0;
|
|
|
|
|
}
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
|
2022-07-13 20:56:57 +01:00
|
|
|
/* Sort first by truncated state index (for good locality), then by key (for good coherence). */
|
2022-07-14 16:42:43 +02:00
|
|
|
# define INTEGRATOR_SORT_KEY(key, state) \
|
|
|
|
|
(key + kernel_data.max_shaders * (state / kernel_integrator_state.sort_partition_divisor))
|
2022-07-13 20:56:57 +01:00
|
|
|
|
2022-07-13 14:22:42 +02:00
|
|
|
ccl_device_forceinline void integrator_path_init_sorted(KernelGlobals kg,
|
|
|
|
|
IntegratorState state,
|
|
|
|
|
const DeviceKernel next_kernel,
|
|
|
|
|
const uint32_t key)
|
|
|
|
|
{
|
|
|
|
|
const int key_ = INTEGRATOR_SORT_KEY(key, state);
|
|
|
|
|
atomic_fetch_and_add_uint32(&kernel_integrator_state.queue_counter->num_queued[next_kernel], 1);
|
|
|
|
|
INTEGRATOR_STATE_WRITE(state, path, queued_kernel) = next_kernel;
|
|
|
|
|
INTEGRATOR_STATE_WRITE(state, path, shader_sort_key) = key_;
|
2023-02-06 11:16:02 +00:00
|
|
|
|
|
|
|
|
# if defined(__KERNEL_LOCAL_ATOMIC_SORT__)
|
|
|
|
|
if (!kernel_integrator_state.sort_key_counter[next_kernel]) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
# endif
|
|
|
|
|
|
2022-07-13 14:22:42 +02:00
|
|
|
atomic_fetch_and_add_uint32(&kernel_integrator_state.sort_key_counter[next_kernel][key_], 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ccl_device_forceinline void integrator_path_next_sorted(KernelGlobals kg,
|
|
|
|
|
IntegratorState state,
|
|
|
|
|
const DeviceKernel current_kernel,
|
|
|
|
|
const DeviceKernel next_kernel,
|
|
|
|
|
const uint32_t key)
|
|
|
|
|
{
|
|
|
|
|
const int key_ = INTEGRATOR_SORT_KEY(key, state);
|
|
|
|
|
atomic_fetch_and_sub_uint32(&kernel_integrator_state.queue_counter->num_queued[current_kernel],
|
|
|
|
|
1);
|
|
|
|
|
atomic_fetch_and_add_uint32(&kernel_integrator_state.queue_counter->num_queued[next_kernel], 1);
|
|
|
|
|
INTEGRATOR_STATE_WRITE(state, path, queued_kernel) = next_kernel;
|
|
|
|
|
INTEGRATOR_STATE_WRITE(state, path, shader_sort_key) = key_;
|
2023-02-06 11:16:02 +00:00
|
|
|
|
|
|
|
|
# if defined(__KERNEL_LOCAL_ATOMIC_SORT__)
|
|
|
|
|
if (!kernel_integrator_state.sort_key_counter[next_kernel]) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
# endif
|
|
|
|
|
|
2022-07-13 14:22:42 +02:00
|
|
|
atomic_fetch_and_add_uint32(&kernel_integrator_state.sort_key_counter[next_kernel][key_], 1);
|
|
|
|
|
}
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
2022-07-13 14:22:42 +02:00
|
|
|
ccl_device_forceinline void integrator_path_init(KernelGlobals kg,
|
|
|
|
|
IntegratorState state,
|
|
|
|
|
const DeviceKernel next_kernel)
|
|
|
|
|
{
|
|
|
|
|
INTEGRATOR_STATE_WRITE(state, path, queued_kernel) = next_kernel;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ccl_device_forceinline void integrator_path_init_sorted(KernelGlobals kg,
|
|
|
|
|
IntegratorState state,
|
|
|
|
|
const DeviceKernel next_kernel,
|
|
|
|
|
const uint32_t key)
|
|
|
|
|
{
|
|
|
|
|
INTEGRATOR_STATE_WRITE(state, path, queued_kernel) = next_kernel;
|
|
|
|
|
(void)key;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ccl_device_forceinline void integrator_path_next(KernelGlobals kg,
|
|
|
|
|
IntegratorState state,
|
|
|
|
|
const DeviceKernel current_kernel,
|
|
|
|
|
const DeviceKernel next_kernel)
|
|
|
|
|
{
|
|
|
|
|
INTEGRATOR_STATE_WRITE(state, path, queued_kernel) = next_kernel;
|
|
|
|
|
(void)current_kernel;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ccl_device_forceinline void integrator_path_terminate(KernelGlobals kg,
|
|
|
|
|
IntegratorState state,
|
|
|
|
|
const DeviceKernel current_kernel)
|
|
|
|
|
{
|
|
|
|
|
INTEGRATOR_STATE_WRITE(state, path, queued_kernel) = 0;
|
|
|
|
|
(void)current_kernel;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ccl_device_forceinline void integrator_path_next_sorted(KernelGlobals kg,
|
|
|
|
|
IntegratorState state,
|
|
|
|
|
const DeviceKernel current_kernel,
|
|
|
|
|
const DeviceKernel next_kernel,
|
|
|
|
|
const uint32_t key)
|
|
|
|
|
{
|
|
|
|
|
INTEGRATOR_STATE_WRITE(state, path, queued_kernel) = next_kernel;
|
|
|
|
|
(void)key;
|
|
|
|
|
(void)current_kernel;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ccl_device_forceinline IntegratorShadowState integrator_shadow_path_init(
|
|
|
|
|
KernelGlobals kg, IntegratorState state, const DeviceKernel next_kernel, const bool is_ao)
|
|
|
|
|
{
|
|
|
|
|
IntegratorShadowState shadow_state = (is_ao) ? &state->ao : &state->shadow;
|
|
|
|
|
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, queued_kernel) = next_kernel;
|
2022-10-18 13:59:12 +02:00
|
|
|
# ifdef __PATH_GUIDING__
|
|
|
|
|
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, path_segment) = nullptr;
|
|
|
|
|
# endif
|
2022-07-13 14:22:42 +02:00
|
|
|
return shadow_state;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ccl_device_forceinline void integrator_shadow_path_next(KernelGlobals kg,
|
|
|
|
|
IntegratorShadowState state,
|
|
|
|
|
const DeviceKernel current_kernel,
|
|
|
|
|
const DeviceKernel next_kernel)
|
|
|
|
|
{
|
|
|
|
|
INTEGRATOR_STATE_WRITE(state, shadow_path, queued_kernel) = next_kernel;
|
|
|
|
|
(void)current_kernel;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ccl_device_forceinline void integrator_shadow_path_terminate(KernelGlobals kg,
|
|
|
|
|
IntegratorShadowState state,
|
|
|
|
|
const DeviceKernel current_kernel)
|
|
|
|
|
{
|
|
|
|
|
INTEGRATOR_STATE_WRITE(state, shadow_path, queued_kernel) = 0;
|
|
|
|
|
(void)current_kernel;
|
|
|
|
|
}
|
Cycles: merge of cycles-x branch, a major update to the renderer
This includes much improved GPU rendering performance, viewport interactivity,
new shadow catcher, revamped sampling settings, subsurface scattering anisotropy,
new GPU volume sampling, improved PMJ sampling pattern, and more.
Some features have also been removed or changed, breaking backwards compatibility.
Including the removal of the OpenCL backend, for which alternatives are under
development.
Release notes and code docs:
https://wiki.blender.org/wiki/Reference/Release_Notes/3.0/Cycles
https://wiki.blender.org/wiki/Source/Render/Cycles
Credits:
* Sergey Sharybin
* Brecht Van Lommel
* Patrick Mours (OptiX backend)
* Christophe Hery (subsurface scattering anisotropy)
* William Leeson (PMJ sampling pattern)
* Alaska (various fixes and tweaks)
* Thomas Dinges (various fixes)
For the full commit history, see the cycles-x branch. This squashes together
all the changes since intermediate changes would often fail building or tests.
Ref T87839, T87837, T87836
Fixes T90734, T89353, T80267, T80267, T77185, T69800
2021-09-20 17:59:20 +02:00
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
CCL_NAMESPACE_END
|