Cycles: Guiding cleaning up and refactoring the guiding code
In detail:
- Direct accesses of state attributes are replaced with the INTEGRATOR_STATE and INTEGRATOR_STATE_WRITE macros.
- Unified the checks for the __PATH_GUIDING define to use # if defined (__PATH_GUIDING__).
- Even if __PATH_GUIDING__ is defined, we now check if the feature is enabled using if ((kernel_data.kernel_features & KERNEL_FEATURE_PATH_GUIDING)) {. This is important for later GPU ports.
- The kernel usage of the guiding field, surface, and volume sampling distributions is wrapped behind macros for each specific device (atm only CPU). This will make it easier for a GPU port later.
This commit is contained in:
@@ -284,7 +284,7 @@ void CPUDevice::build_bvh(BVH *bvh, Progress &progress, bool refit)
|
||||
|
||||
void *CPUDevice::get_guiding_device() const
|
||||
{
|
||||
#ifdef WITH_PATH_GUIDING
|
||||
#if defined(WITH_PATH_GUIDING)
|
||||
if (!guiding_device) {
|
||||
if (guiding_device_type() == 8) {
|
||||
guiding_device = make_unique<openpgl::cpp::Device>(PGL_DEVICE_TYPE_CPU_8);
|
||||
|
||||
@@ -48,7 +48,7 @@ class CPUDevice : public Device {
|
||||
RTCScene embree_scene = nullptr;
|
||||
RTCDevice embree_device;
|
||||
#endif
|
||||
#ifdef WITH_PATH_GUIDING
|
||||
#if defined(WITH_PATH_GUIDING)
|
||||
mutable unique_ptr<openpgl::cpp::Device> guiding_device;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1335,7 +1335,7 @@ string PathTrace::full_report() const
|
||||
|
||||
void PathTrace::set_guiding_params(const GuidingParams &guiding_params, const bool reset)
|
||||
{
|
||||
#ifdef WITH_PATH_GUIDING
|
||||
#if defined(WITH_PATH_GUIDING)
|
||||
if (guiding_params_.modified(guiding_params)) {
|
||||
guiding_params_ = guiding_params;
|
||||
|
||||
@@ -1435,7 +1435,7 @@ void PathTrace::set_guiding_params(const GuidingParams &guiding_params, const bo
|
||||
|
||||
void PathTrace::guiding_prepare_structures()
|
||||
{
|
||||
#ifdef WITH_PATH_GUIDING
|
||||
#if defined(WITH_PATH_GUIDING)
|
||||
const bool train = (guiding_params_.training_samples == 0) ||
|
||||
(guiding_field_->GetIteration() < guiding_params_.training_samples);
|
||||
|
||||
@@ -1460,7 +1460,7 @@ void PathTrace::guiding_prepare_structures()
|
||||
|
||||
void PathTrace::guiding_update_structures()
|
||||
{
|
||||
#ifdef WITH_PATH_GUIDING
|
||||
#if defined(WITH_PATH_GUIDING)
|
||||
VLOG_WORK << "Update path guiding structures";
|
||||
|
||||
VLOG_DEBUG << "Number of surface samples: " << guiding_sample_data_storage_->GetSizeSurface();
|
||||
|
||||
@@ -289,7 +289,7 @@ class PathTrace {
|
||||
/* Denoiser device descriptor which holds the denoised big tile for multi-device workloads. */
|
||||
unique_ptr<PathTraceWork> big_tile_denoise_work_;
|
||||
|
||||
#ifdef WITH_PATH_GUIDING
|
||||
#if defined(WITH_PATH_GUIDING)
|
||||
/* Guiding related attributes */
|
||||
GuidingParams guiding_params_;
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ class PathTraceWork {
|
||||
return device_;
|
||||
}
|
||||
|
||||
#ifdef WITH_PATH_GUIDING
|
||||
#if defined(WITH_PATH_GUIDING)
|
||||
/* Initializes the per-thread guiding kernel data. */
|
||||
virtual void guiding_init_kernel_globals(void * /*unused*/,
|
||||
void * /*unused*/,
|
||||
|
||||
@@ -148,7 +148,7 @@ void PathTraceWorkCPU::render_samples_full_pipeline(ThreadKernelGlobalsCPU *kern
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WITH_PATH_GUIDING
|
||||
#if defined(WITH_PATH_GUIDING)
|
||||
if (kernel_globals->data.integrator.train_guiding) {
|
||||
assert(kernel_globals->opgl_path_segment_storage);
|
||||
assert(kernel_globals->opgl_path_segment_storage->GetNumSegments() == 0);
|
||||
@@ -303,7 +303,7 @@ void PathTraceWorkCPU::cryptomatte_postproces()
|
||||
});
|
||||
}
|
||||
|
||||
#ifdef WITH_PATH_GUIDING
|
||||
#if defined(WITH_PATH_GUIDING)
|
||||
/* NOTE: It seems that this is called before every rendering iteration/progression and not once per
|
||||
* rendering. May be we find a way to call it only once per rendering. */
|
||||
void PathTraceWorkCPU::guiding_init_kernel_globals(void *guiding_field,
|
||||
|
||||
@@ -52,7 +52,7 @@ class PathTraceWorkCPU : public PathTraceWork {
|
||||
int adaptive_sampling_converge_filter_count_active(const float threshold, bool reset) override;
|
||||
void cryptomatte_postproces() override;
|
||||
|
||||
#ifdef WITH_PATH_GUIDING
|
||||
#if defined(WITH_PATH_GUIDING)
|
||||
/* Initializes the per-thread guiding kernel data. The function sets the pointers to the
|
||||
* global guiding field and the sample data storage as well es initializes the per-thread
|
||||
* guided sampling distributions (e.g., SurfaceSamplingDistribution and
|
||||
|
||||
@@ -388,6 +388,7 @@ set(SRC_UTIL_HEADERS
|
||||
../util/atomic.h
|
||||
../util/color.h
|
||||
../util/defines.h
|
||||
../util/guiding.h
|
||||
../util/half.h
|
||||
../util/hash.h
|
||||
../util/math.h
|
||||
|
||||
@@ -25,7 +25,7 @@ ThreadKernelGlobalsCPU::ThreadKernelGlobalsCPU(const KernelGlobalsCPU &kernel_gl
|
||||
(void)osl_globals;
|
||||
#endif
|
||||
|
||||
#ifdef WITH_PATH_GUIDING
|
||||
#if defined(WITH_PATH_GUIDING)
|
||||
opgl_path_segment_storage = make_unique<openpgl::cpp::PathSegmentStorage>();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ struct ThreadKernelGlobalsCPU : public KernelGlobalsCPU {
|
||||
OSLThreadData osl;
|
||||
#endif
|
||||
|
||||
#ifdef __PATH_GUIDING__
|
||||
#if defined(__PATH_GUIDING__)
|
||||
/* Pointers to shared global data structures. */
|
||||
openpgl::cpp::SampleStorage *opgl_sample_data_storage = nullptr;
|
||||
openpgl::cpp::Field *opgl_guiding_field = nullptr;
|
||||
@@ -95,5 +95,10 @@ using KernelGlobals = const ThreadKernelGlobalsCPU *;
|
||||
#define kernel_data_fetch(name, index) (kg->name.fetch(index))
|
||||
#define kernel_data_array(name) (kg->name.data)
|
||||
#define kernel_data (kg->data)
|
||||
#if defined(WITH_PATH_GUIDING)
|
||||
# define guiding_guiding_field kg->opgl_guiding_field
|
||||
# define guiding_ssd kg->opgl_surface_sampling_distribution
|
||||
# define guiding_vsd kg->opgl_volume_sampling_distribution
|
||||
#endif
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
@@ -65,12 +65,12 @@ ccl_device_forceinline bool calculate_ris_target(ccl_private GuidingRISSample *r
|
||||
#if defined(__PATH_GUIDING__)
|
||||
static pgl_vec3f guiding_vec3f(const float3 v)
|
||||
{
|
||||
return openpgl::cpp::Vector3(v.x, v.y, v.z);
|
||||
return {v.x, v.y, v.z};
|
||||
}
|
||||
|
||||
static pgl_point3f guiding_point3f(const float3 v)
|
||||
ccl_device_forceinline pgl_point3f guiding_point3f(const float3 v)
|
||||
{
|
||||
return openpgl::cpp::Point3(v.x, v.y, v.z);
|
||||
return {v.x, v.y, v.z};
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -550,14 +550,11 @@ ccl_device_forceinline bool guiding_bsdf_init(KernelGlobals kg,
|
||||
ccl_private float &rand)
|
||||
{
|
||||
#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
|
||||
if (kg->opgl_surface_sampling_distribution->Init(
|
||||
kg->opgl_guiding_field, guiding_point3f(P), rand))
|
||||
{
|
||||
kg->opgl_surface_sampling_distribution->ApplyCosineProduct(guiding_point3f(N));
|
||||
if (guiding_ssd->Init(guiding_guiding_field, guiding_point3f(P), rand)) {
|
||||
guiding_ssd->ApplyCosineProduct(guiding_point3f(N));
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -568,8 +565,8 @@ ccl_device_forceinline float guiding_bsdf_sample(KernelGlobals kg,
|
||||
{
|
||||
#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
|
||||
pgl_vec3f pgl_wo;
|
||||
const pgl_point2f rand = openpgl::cpp::Point2(rand_bsdf.x, rand_bsdf.y);
|
||||
const float pdf = kg->opgl_surface_sampling_distribution->SamplePDF(rand, pgl_wo);
|
||||
const pgl_point2f rand = {rand_bsdf.x, rand_bsdf.y};
|
||||
const float pdf = guiding_ssd->SamplePDF(rand, pgl_wo);
|
||||
*wo = make_float3(pgl_wo.x, pgl_wo.y, pgl_wo.z);
|
||||
return pdf;
|
||||
#else
|
||||
@@ -582,7 +579,7 @@ ccl_device_forceinline float guiding_bsdf_pdf(KernelGlobals kg,
|
||||
const float3 wo)
|
||||
{
|
||||
#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
|
||||
return kg->opgl_surface_sampling_distribution->PDF(guiding_vec3f(wo));
|
||||
return guiding_ssd->PDF(guiding_vec3f(wo));
|
||||
#else
|
||||
return 0.0f;
|
||||
#endif
|
||||
@@ -593,7 +590,7 @@ ccl_device_forceinline float guiding_surface_incoming_radiance_pdf(KernelGlobals
|
||||
const float3 wo)
|
||||
{
|
||||
#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
|
||||
return kg->opgl_surface_sampling_distribution->IncomingRadiancePDF(guiding_vec3f(wo));
|
||||
return guiding_ssd->IncomingRadiancePDF(guiding_vec3f(wo));
|
||||
#else
|
||||
return 0.0f;
|
||||
#endif
|
||||
@@ -614,11 +611,8 @@ ccl_device_forceinline bool guiding_phase_init(KernelGlobals kg,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (kg->opgl_volume_sampling_distribution->Init(
|
||||
kg->opgl_guiding_field, guiding_point3f(P), rand))
|
||||
{
|
||||
kg->opgl_volume_sampling_distribution->ApplySingleLobeHenyeyGreensteinProduct(guiding_vec3f(D),
|
||||
g);
|
||||
if (guiding_vsd->Init(guiding_guiding_field, guiding_point3f(P), rand)) {
|
||||
guiding_vsd->ApplySingleLobeHenyeyGreensteinProduct(guiding_vec3f(D), g);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
@@ -633,8 +627,8 @@ ccl_device_forceinline float guiding_phase_sample(KernelGlobals kg,
|
||||
{
|
||||
#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
|
||||
pgl_vec3f pgl_wo;
|
||||
const pgl_point2f rand = openpgl::cpp::Point2(rand_phase.x, rand_phase.y);
|
||||
const float pdf = kg->opgl_volume_sampling_distribution->SamplePDF(rand, pgl_wo);
|
||||
const pgl_point2f rand = {rand_phase.x, rand_phase.y};
|
||||
const float pdf = guiding_vsd->SamplePDF(rand, pgl_wo);
|
||||
*wo = make_float3(pgl_wo.x, pgl_wo.y, pgl_wo.z);
|
||||
return pdf;
|
||||
#else
|
||||
@@ -647,7 +641,7 @@ ccl_device_forceinline float guiding_phase_pdf(KernelGlobals kg,
|
||||
const float3 wo)
|
||||
{
|
||||
#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
|
||||
return kg->opgl_volume_sampling_distribution->PDF(guiding_vec3f(wo));
|
||||
return guiding_vsd->PDF(guiding_vec3f(wo));
|
||||
#else
|
||||
return 0.0f;
|
||||
#endif
|
||||
|
||||
@@ -59,19 +59,19 @@ ccl_device_inline void path_state_init_integrator(KernelGlobals kg,
|
||||
INTEGRATOR_STATE_WRITE(state, path, min_ray_pdf) = FLT_MAX;
|
||||
INTEGRATOR_STATE_WRITE(state, path, continuation_probability) = 1.0f;
|
||||
INTEGRATOR_STATE_WRITE(state, path, throughput) = throughput;
|
||||
|
||||
#ifdef __PATH_GUIDING__
|
||||
INTEGRATOR_STATE_WRITE(state, path, unguided_throughput) = 1.0f;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, path_segment) = nullptr;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, use_surface_guiding) = false;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, sample_surface_guiding_rand) = 0.5f;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, surface_guiding_sampling_prob) = 0.0f;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, bssrdf_sampling_prob) = 0.0f;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, use_volume_guiding) = false;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, sample_volume_guiding_rand) = 0.5f;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, volume_guiding_sampling_prob) = 0.0f;
|
||||
#if defined(__PATH_GUIDING__)
|
||||
if ((kernel_data.kernel_features & KERNEL_FEATURE_PATH_GUIDING)) {
|
||||
INTEGRATOR_STATE_WRITE(state, path, unguided_throughput) = 1.0f;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, path_segment) = nullptr;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, use_surface_guiding) = false;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, sample_surface_guiding_rand) = 0.5f;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, surface_guiding_sampling_prob) = 0.0f;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, bssrdf_sampling_prob) = 0.0f;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, use_volume_guiding) = false;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, sample_volume_guiding_rand) = 0.5f;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, volume_guiding_sampling_prob) = 0.0f;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __MNEE__
|
||||
INTEGRATOR_STATE_WRITE(state, path, mnee) = 0;
|
||||
#endif
|
||||
@@ -280,7 +280,9 @@ ccl_device_inline float path_state_continuation_probability(KernelGlobals kg,
|
||||
* transform and do path termination a bit later on average. */
|
||||
Spectrum throughput = INTEGRATOR_STATE(state, path, throughput);
|
||||
#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
|
||||
throughput *= INTEGRATOR_STATE(state, path, unguided_throughput);
|
||||
if ((kernel_data.kernel_features & KERNEL_FEATURE_PATH_GUIDING)) {
|
||||
throughput *= INTEGRATOR_STATE(state, path, unguided_throughput);
|
||||
}
|
||||
#endif
|
||||
return min(sqrtf(reduce_max(fabs(throughput))), 1.0f);
|
||||
}
|
||||
|
||||
@@ -211,7 +211,7 @@ ccl_device void shadow_linking_shade(KernelGlobals kg,
|
||||
|
||||
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, flag) = shadow_flag;
|
||||
|
||||
# ifdef __PATH_GUIDING__
|
||||
# if defined(__PATH_GUIDING__)
|
||||
if (kernel_data.integrator.train_guiding) {
|
||||
guiding_record_light_surface_segment(kg, state, &isect);
|
||||
INTEGRATOR_STATE(shadow_state, shadow_path, guiding_mis_weight) = mis_weight;
|
||||
|
||||
@@ -271,11 +271,13 @@ integrate_direct_light_shadow_init_common(KernelGlobals kg,
|
||||
/* Write Light-group, +1 as light-group is int but we need to encode into a uint8_t. */
|
||||
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, lightgroup) = light_group + 1;
|
||||
|
||||
#ifdef __PATH_GUIDING__
|
||||
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, unlit_throughput) = unlit_throughput;
|
||||
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, path_segment) = INTEGRATOR_STATE(
|
||||
state, guiding, path_segment);
|
||||
INTEGRATOR_STATE(shadow_state, shadow_path, guiding_mis_weight) = 0.0f;
|
||||
#if defined(__PATH_GUIDING__)
|
||||
if ((kernel_data.kernel_features & KERNEL_FEATURE_PATH_GUIDING)) {
|
||||
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, unlit_throughput) = unlit_throughput;
|
||||
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, path_segment) = INTEGRATOR_STATE(
|
||||
state, guiding, path_segment);
|
||||
INTEGRATOR_STATE(shadow_state, shadow_path, guiding_mis_weight) = 0.0f;
|
||||
}
|
||||
#endif
|
||||
|
||||
return shadow_state;
|
||||
@@ -473,7 +475,9 @@ ccl_device_forceinline int integrate_surface_bsdf_bssrdf_bounce(
|
||||
float mis_pdf = 1.0f;
|
||||
|
||||
#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
|
||||
if (kernel_data.integrator.use_surface_guiding) {
|
||||
if (kernel_data.integrator.use_surface_guiding &&
|
||||
(kernel_data.kernel_features & KERNEL_FEATURE_PATH_GUIDING))
|
||||
{
|
||||
label = surface_shader_bsdf_guided_sample_closure(kg,
|
||||
state,
|
||||
sd,
|
||||
@@ -783,8 +787,10 @@ ccl_device int integrate_surface(KernelGlobals kg,
|
||||
path_state_rng_load(state, &rng_state);
|
||||
|
||||
#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
|
||||
surface_shader_prepare_guiding(kg, state, &sd, &rng_state);
|
||||
guiding_write_debug_passes(kg, state, &sd, render_buffer);
|
||||
if (kernel_data.kernel_features & KERNEL_FEATURE_PATH_GUIDING) {
|
||||
surface_shader_prepare_guiding(kg, state, &sd, &rng_state);
|
||||
guiding_write_debug_passes(kg, state, &sd, render_buffer);
|
||||
}
|
||||
#endif
|
||||
/* Direct light. */
|
||||
PROFILING_EVENT(PROFILING_SHADE_SURFACE_DIRECT_LIGHT);
|
||||
|
||||
@@ -39,7 +39,7 @@ struct VolumeIntegrateResult {
|
||||
Spectrum direct_throughput;
|
||||
float direct_t;
|
||||
ShaderVolumePhases direct_phases;
|
||||
# ifdef __PATH_GUIDING__
|
||||
# if defined(__PATH_GUIDING__)
|
||||
VolumeSampleMethod direct_sample_method;
|
||||
# endif
|
||||
|
||||
@@ -591,7 +591,7 @@ ccl_device_forceinline void volume_integrate_heterogeneous(
|
||||
result.direct_t = volume_equiangular_sample(
|
||||
ray, equiangular_coeffs, vstate.rscatter, &vstate.equiangular_pdf);
|
||||
}
|
||||
# ifdef __PATH_GUIDING__
|
||||
# if defined(__PATH_GUIDING__)
|
||||
result.direct_sample_method = vstate.direct_sample_method;
|
||||
# endif
|
||||
|
||||
@@ -729,7 +729,7 @@ ccl_device_forceinline void integrate_volume_direct_light(
|
||||
const ccl_private RNGState *ccl_restrict rng_state,
|
||||
const float3 P,
|
||||
const ccl_private ShaderVolumePhases *ccl_restrict phases,
|
||||
# ifdef __PATH_GUIDING__
|
||||
# if defined(__PATH_GUIDING__)
|
||||
const ccl_private Spectrum unlit_throughput,
|
||||
# endif
|
||||
const ccl_private Spectrum throughput,
|
||||
@@ -849,11 +849,13 @@ ccl_device_forceinline void integrate_volume_direct_light(
|
||||
/* Write Light-group, +1 as light-group is int but we need to encode into a uint8_t. */
|
||||
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, lightgroup) = ls.group + 1;
|
||||
|
||||
# ifdef __PATH_GUIDING__
|
||||
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, unlit_throughput) = unlit_throughput;
|
||||
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, path_segment) = INTEGRATOR_STATE(
|
||||
state, guiding, path_segment);
|
||||
INTEGRATOR_STATE(shadow_state, shadow_path, guiding_mis_weight) = 0.0f;
|
||||
# if defined(__PATH_GUIDING__)
|
||||
if ((kernel_data.kernel_features & KERNEL_FEATURE_PATH_GUIDING)) {
|
||||
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, unlit_throughput) = unlit_throughput;
|
||||
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, path_segment) = INTEGRATOR_STATE(
|
||||
state, guiding, path_segment);
|
||||
INTEGRATOR_STATE(shadow_state, shadow_path, guiding_mis_weight) = 0.0f;
|
||||
}
|
||||
# endif
|
||||
|
||||
integrator_state_copy_volume_stack_to_shadow(kg, shadow_state, state);
|
||||
@@ -883,7 +885,9 @@ ccl_device_forceinline bool integrate_volume_phase_scatter(
|
||||
int label;
|
||||
|
||||
# if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
|
||||
if (kernel_data.integrator.use_guiding) {
|
||||
if (kernel_data.integrator.use_guiding &&
|
||||
(kernel_data.kernel_features & KERNEL_FEATURE_PATH_GUIDING))
|
||||
{
|
||||
label = volume_shader_phase_guided_sample(kg,
|
||||
state,
|
||||
sd,
|
||||
@@ -1042,7 +1046,7 @@ ccl_device VolumeIntegrateEvent volume_integrate(KernelGlobals kg,
|
||||
if (result.direct_scatter) {
|
||||
const float3 direct_P = ray->P + result.direct_t * ray->D;
|
||||
|
||||
# ifdef __PATH_GUIDING__
|
||||
# if defined(__PATH_GUIDING__)
|
||||
if (kernel_data.integrator.use_guiding) {
|
||||
# if PATH_GUIDING_LEVEL >= 1
|
||||
if (result.direct_sample_method == VOLUME_SAMPLE_DISTANCE) {
|
||||
@@ -1064,8 +1068,9 @@ ccl_device VolumeIntegrateEvent volume_integrate(KernelGlobals kg,
|
||||
* unlit_throughput has to be adjusted to include the scattering at the previous segment.
|
||||
*/
|
||||
float3 scatterEval = one_float3();
|
||||
if (state->guiding.path_segment) {
|
||||
const pgl_vec3f scatteringWeight = state->guiding.path_segment->scatteringWeight;
|
||||
if (INTEGRATOR_STATE(state, guiding, path_segment)) {
|
||||
const pgl_vec3f scatteringWeight =
|
||||
INTEGRATOR_STATE(state, guiding, path_segment)->scatteringWeight;
|
||||
scatterEval = make_float3(scatteringWeight.x, scatteringWeight.y, scatteringWeight.z);
|
||||
}
|
||||
unlit_throughput /= scatterEval;
|
||||
@@ -1075,8 +1080,10 @@ ccl_device VolumeIntegrateEvent volume_integrate(KernelGlobals kg,
|
||||
}
|
||||
# endif
|
||||
# if PATH_GUIDING_LEVEL >= 4
|
||||
volume_shader_prepare_guiding(
|
||||
kg, state, &sd, rand_phase_guiding, direct_P, ray->D, &result.direct_phases);
|
||||
if ((kernel_data.kernel_features & KERNEL_FEATURE_PATH_GUIDING)) {
|
||||
volume_shader_prepare_guiding(
|
||||
kg, state, &sd, rand_phase_guiding, direct_P, ray->D, &result.direct_phases);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
# endif
|
||||
@@ -1088,7 +1095,7 @@ ccl_device VolumeIntegrateEvent volume_integrate(KernelGlobals kg,
|
||||
&rng_state,
|
||||
direct_P,
|
||||
&result.direct_phases,
|
||||
# ifdef __PATH_GUIDING__
|
||||
# if defined(__PATH_GUIDING__)
|
||||
unlit_throughput,
|
||||
# endif
|
||||
result.direct_throughput,
|
||||
@@ -1115,20 +1122,22 @@ ccl_device VolumeIntegrateEvent volume_integrate(KernelGlobals kg,
|
||||
sd.P = ray->P + result.indirect_t * ray->D;
|
||||
|
||||
# if defined(__PATH_GUIDING__)
|
||||
if ((kernel_data.kernel_features & KERNEL_FEATURE_PATH_GUIDING)) {
|
||||
# if PATH_GUIDING_LEVEL >= 1
|
||||
if (!guiding_generated_new_segment) {
|
||||
guiding_record_volume_segment(kg, state, sd.P, sd.wi);
|
||||
}
|
||||
if (!guiding_generated_new_segment) {
|
||||
guiding_record_volume_segment(kg, state, sd.P, sd.wi);
|
||||
}
|
||||
# endif
|
||||
# if PATH_GUIDING_LEVEL >= 4
|
||||
/* If the direct scatter event was generated using VOLUME_SAMPLE_EQUIANGULAR we need to
|
||||
* initialize the guiding distribution at the indirect scatter position. */
|
||||
if (result.direct_sample_method == VOLUME_SAMPLE_EQUIANGULAR) {
|
||||
rand_phase_guiding = path_state_rng_1D(kg, &rng_state, PRNG_VOLUME_PHASE_GUIDING_DISTANCE);
|
||||
volume_shader_prepare_guiding(
|
||||
kg, state, &sd, rand_phase_guiding, sd.P, ray->D, &result.indirect_phases);
|
||||
}
|
||||
/* If the direct scatter event was generated using VOLUME_SAMPLE_EQUIANGULAR we need to
|
||||
* initialize the guiding distribution at the indirect scatter position. */
|
||||
if (result.direct_sample_method == VOLUME_SAMPLE_EQUIANGULAR) {
|
||||
rand_phase_guiding = path_state_rng_1D(kg, &rng_state, PRNG_VOLUME_PHASE_GUIDING_DISTANCE);
|
||||
volume_shader_prepare_guiding(
|
||||
kg, state, &sd, rand_phase_guiding, sd.P, ray->D, &result.indirect_phases);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
# endif
|
||||
|
||||
if (integrate_volume_phase_scatter(kg, state, &sd, ray, &rng_state, &result.indirect_phases)) {
|
||||
@@ -1138,7 +1147,9 @@ ccl_device VolumeIntegrateEvent volume_integrate(KernelGlobals kg,
|
||||
}
|
||||
# if defined(__PATH_GUIDING__)
|
||||
/* No guiding if we don't scatter. */
|
||||
state->guiding.use_volume_guiding = false;
|
||||
if ((kernel_data.kernel_features & KERNEL_FEATURE_PATH_GUIDING)) {
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, use_volume_guiding) = false;
|
||||
}
|
||||
# endif
|
||||
return VOLUME_PATH_ATTENUATED;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ KERNEL_STRUCT_MEMBER(shadow_path, uint16_t, num_hits, KERNEL_FEATURE_PATH_TRACIN
|
||||
KERNEL_STRUCT_MEMBER(shadow_path, uint8_t, lightgroup, KERNEL_FEATURE_PATH_TRACING)
|
||||
/* Path guiding. */
|
||||
KERNEL_STRUCT_MEMBER(shadow_path, PackedSpectrum, unlit_throughput, KERNEL_FEATURE_PATH_GUIDING)
|
||||
#ifdef __PATH_GUIDING__
|
||||
#if defined(__PATH_GUIDING__)
|
||||
KERNEL_STRUCT_MEMBER(shadow_path,
|
||||
openpgl::cpp::PathSegment *,
|
||||
path_segment,
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
#include "util/types.h"
|
||||
|
||||
#ifdef __PATH_GUIDING__
|
||||
#if defined(__PATH_GUIDING__)
|
||||
# include "util/guiding.h" // IWYU pragma: keep
|
||||
#endif
|
||||
|
||||
|
||||
@@ -81,8 +81,10 @@ ccl_device_forceinline IntegratorShadowState integrator_shadow_path_init(
|
||||
&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;
|
||||
# ifdef __PATH_GUIDING__
|
||||
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, path_segment) = nullptr;
|
||||
# if defined(__PATH_GUIDING__)
|
||||
if ((kernel_data.kernel_features & KERNEL_FEATURE_PATH_GUIDING)) {
|
||||
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, path_segment) = nullptr;
|
||||
}
|
||||
# endif
|
||||
return shadow_state;
|
||||
}
|
||||
@@ -203,8 +205,10 @@ ccl_device_forceinline IntegratorShadowState integrator_shadow_path_init(
|
||||
{
|
||||
IntegratorShadowState shadow_state = (is_ao) ? &state->ao : &state->shadow;
|
||||
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, queued_kernel) = next_kernel;
|
||||
# ifdef __PATH_GUIDING__
|
||||
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, path_segment) = nullptr;
|
||||
# if defined(__PATH_GUIDING__)
|
||||
if ((kernel_data.kernel_features & KERNEL_FEATURE_PATH_GUIDING)) {
|
||||
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, path_segment) = nullptr;
|
||||
}
|
||||
# endif
|
||||
return shadow_state;
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ KERNEL_STRUCT_END_ARRAY(volume_stack,
|
||||
|
||||
/************************************ Path Guiding *****************************/
|
||||
KERNEL_STRUCT_BEGIN(guiding)
|
||||
#ifdef __PATH_GUIDING__
|
||||
#if defined(__PATH_GUIDING__)
|
||||
/* Current path segment of the random walk/path. */
|
||||
KERNEL_STRUCT_MEMBER(guiding,
|
||||
openpgl::cpp::PathSegment *,
|
||||
|
||||
@@ -24,7 +24,7 @@ CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* Guiding */
|
||||
|
||||
#ifdef __PATH_GUIDING__
|
||||
#if defined(__PATH_GUIDING__)
|
||||
|
||||
ccl_device float surface_shader_average_sample_weight_squared_roughness(
|
||||
const ccl_private ShaderData *sd)
|
||||
@@ -54,7 +54,7 @@ ccl_device_inline void surface_shader_prepare_guiding(KernelGlobals kg,
|
||||
{
|
||||
/* Have any BSDF to guide? */
|
||||
if (!(kernel_data.integrator.use_surface_guiding && (sd->flag & SD_BSDF_HAS_EVAL))) {
|
||||
state->guiding.use_surface_guiding = false;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, use_surface_guiding) = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -106,31 +106,35 @@ ccl_device_inline void surface_shader_prepare_guiding(KernelGlobals kg,
|
||||
(diffuse_sampling_fraction <= 0.0f)) ||
|
||||
!guiding_bsdf_init(kg, state, sd->P, sd->N, rand_bsdf_guiding))
|
||||
{
|
||||
state->guiding.use_surface_guiding = false;
|
||||
state->guiding.surface_guiding_sampling_prob = 0.0f;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, use_surface_guiding) = false;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, surface_guiding_sampling_prob) = 0.f;
|
||||
return;
|
||||
}
|
||||
|
||||
state->guiding.use_surface_guiding = true;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, use_surface_guiding) = true;
|
||||
if (kernel_data.integrator.guiding_directional_sampling_type ==
|
||||
GUIDING_DIRECTIONAL_SAMPLING_TYPE_PRODUCT_MIS)
|
||||
{
|
||||
state->guiding.surface_guiding_sampling_prob = surface_guiding_probability *
|
||||
diffuse_sampling_fraction;
|
||||
INTEGRATOR_STATE_WRITE(
|
||||
state, guiding, surface_guiding_sampling_prob) = surface_guiding_probability *
|
||||
diffuse_sampling_fraction;
|
||||
}
|
||||
else if (kernel_data.integrator.guiding_directional_sampling_type ==
|
||||
GUIDING_DIRECTIONAL_SAMPLING_TYPE_RIS)
|
||||
{
|
||||
state->guiding.surface_guiding_sampling_prob = surface_guiding_probability;
|
||||
INTEGRATOR_STATE_WRITE(
|
||||
state, guiding, surface_guiding_sampling_prob) = surface_guiding_probability;
|
||||
}
|
||||
else { // GUIDING_DIRECTIONAL_SAMPLING_TYPE_ROUGHNESS
|
||||
state->guiding.surface_guiding_sampling_prob = surface_guiding_probability * avg_roughness;
|
||||
INTEGRATOR_STATE_WRITE(
|
||||
state, guiding, surface_guiding_sampling_prob) = surface_guiding_probability *
|
||||
avg_roughness;
|
||||
}
|
||||
state->guiding.bssrdf_sampling_prob = bssrdf_sampling_fraction;
|
||||
state->guiding.sample_surface_guiding_rand = rand_bsdf_guiding;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, bssrdf_sampling_prob) = bssrdf_sampling_fraction;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, sample_surface_guiding_rand) = rand_bsdf_guiding;
|
||||
|
||||
kernel_assert(state->guiding.surface_guiding_sampling_prob > 0.0f &&
|
||||
state->guiding.surface_guiding_sampling_prob <= 1.0f);
|
||||
kernel_assert(INTEGRATOR_STATE(state, guiding, surface_guiding_sampling_prob) > 0.0f &&
|
||||
INTEGRATOR_STATE(state, guiding, surface_guiding_sampling_prob) <= 1.0f);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -372,19 +376,22 @@ ccl_device_inline
|
||||
}
|
||||
|
||||
#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
|
||||
if (pdf > 0.0f && state->guiding.use_surface_guiding) {
|
||||
const float guiding_sampling_prob = state->guiding.surface_guiding_sampling_prob;
|
||||
const float bssrdf_sampling_prob = state->guiding.bssrdf_sampling_prob;
|
||||
const float guide_pdf = guiding_bsdf_pdf(kg, state, wo);
|
||||
if ((kernel_data.kernel_features & KERNEL_FEATURE_PATH_GUIDING)) {
|
||||
if (pdf > 0.0f && INTEGRATOR_STATE(state, guiding, use_surface_guiding)) {
|
||||
const float guiding_sampling_prob = INTEGRATOR_STATE(
|
||||
state, guiding, surface_guiding_sampling_prob);
|
||||
const float bssrdf_sampling_prob = INTEGRATOR_STATE(state, guiding, bssrdf_sampling_prob);
|
||||
const float guide_pdf = guiding_bsdf_pdf(kg, state, wo);
|
||||
|
||||
if (kernel_data.integrator.guiding_directional_sampling_type ==
|
||||
GUIDING_DIRECTIONAL_SAMPLING_TYPE_RIS)
|
||||
{
|
||||
pdf = (0.5f * guide_pdf * (1.0f - bssrdf_sampling_prob)) + 0.5f * pdf;
|
||||
}
|
||||
else {
|
||||
pdf = (guiding_sampling_prob * guide_pdf * (1.0f - bssrdf_sampling_prob)) +
|
||||
(1.0f - guiding_sampling_prob) * pdf;
|
||||
if (kernel_data.integrator.guiding_directional_sampling_type ==
|
||||
GUIDING_DIRECTIONAL_SAMPLING_TYPE_RIS)
|
||||
{
|
||||
pdf = (0.5f * guide_pdf * (1.0f - bssrdf_sampling_prob)) + 0.5f * pdf;
|
||||
}
|
||||
else {
|
||||
pdf = (guiding_sampling_prob * guide_pdf * (1.0f - bssrdf_sampling_prob)) +
|
||||
(1.0f - guiding_sampling_prob) * pdf;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -457,7 +464,7 @@ surface_shader_bssrdf_sample_weight(const ccl_private ShaderData *ccl_restrict s
|
||||
return weight;
|
||||
}
|
||||
|
||||
#ifdef __PATH_GUIDING__
|
||||
#if defined(__PATH_GUIDING__)
|
||||
/* Sample direction for picked BSDF, and return evaluation and pdf for all
|
||||
* BSDFs combined using MIS. */
|
||||
|
||||
@@ -476,13 +483,14 @@ ccl_device int surface_shader_bsdf_guided_sample_closure_mis(KernelGlobals kg,
|
||||
/* BSSRDF should already have been handled elsewhere. */
|
||||
kernel_assert(CLOSURE_IS_BSDF(sc->type));
|
||||
|
||||
const bool use_surface_guiding = state->guiding.use_surface_guiding;
|
||||
const float guiding_sampling_prob = state->guiding.surface_guiding_sampling_prob;
|
||||
const float bssrdf_sampling_prob = state->guiding.bssrdf_sampling_prob;
|
||||
const bool use_surface_guiding = INTEGRATOR_STATE(state, guiding, use_surface_guiding);
|
||||
const float guiding_sampling_prob = INTEGRATOR_STATE(
|
||||
state, guiding, surface_guiding_sampling_prob);
|
||||
const float bssrdf_sampling_prob = INTEGRATOR_STATE(state, guiding, bssrdf_sampling_prob);
|
||||
|
||||
/* Decide between sampling guiding distribution and BSDF. */
|
||||
bool sample_guiding = false;
|
||||
float rand_bsdf_guiding = state->guiding.sample_surface_guiding_rand;
|
||||
float rand_bsdf_guiding = INTEGRATOR_STATE(state, guiding, sample_surface_guiding_rand);
|
||||
|
||||
if (use_surface_guiding && rand_bsdf_guiding < guiding_sampling_prob) {
|
||||
sample_guiding = true;
|
||||
@@ -609,12 +617,13 @@ ccl_device int surface_shader_bsdf_guided_sample_closure_ris(KernelGlobals kg,
|
||||
/* BSSRDF should already have been handled elsewhere. */
|
||||
kernel_assert(CLOSURE_IS_BSDF(sc->type));
|
||||
|
||||
const bool use_surface_guiding = state->guiding.use_surface_guiding;
|
||||
const float guiding_sampling_prob = state->guiding.surface_guiding_sampling_prob;
|
||||
const float bssrdf_sampling_prob = state->guiding.bssrdf_sampling_prob;
|
||||
const bool use_surface_guiding = INTEGRATOR_STATE(state, guiding, use_surface_guiding);
|
||||
const float guiding_sampling_prob = INTEGRATOR_STATE(
|
||||
state, guiding, surface_guiding_sampling_prob);
|
||||
const float bssrdf_sampling_prob = INTEGRATOR_STATE(state, guiding, bssrdf_sampling_prob);
|
||||
|
||||
/* Decide between sampling guiding distribution and BSDF. */
|
||||
const float rand_bsdf_guiding = state->guiding.sample_surface_guiding_rand;
|
||||
const float rand_bsdf_guiding = INTEGRATOR_STATE(state, guiding, sample_surface_guiding_rand);
|
||||
|
||||
/* Initialize to zero. */
|
||||
int label = LABEL_NONE;
|
||||
|
||||
@@ -82,7 +82,7 @@ ccl_device_inline void volume_shader_copy_phases(ccl_private ShaderVolumePhases
|
||||
|
||||
/* Guiding */
|
||||
|
||||
# ifdef __PATH_GUIDING__
|
||||
# if defined(__PATH_GUIDING__)
|
||||
ccl_device_inline void volume_shader_prepare_guiding(KernelGlobals kg,
|
||||
IntegratorState state,
|
||||
ccl_private ShaderData *sd,
|
||||
@@ -94,7 +94,7 @@ ccl_device_inline void volume_shader_prepare_guiding(KernelGlobals kg,
|
||||
/* Have any phase functions to guide? */
|
||||
const int num_phases = phases->num_closure;
|
||||
if (!kernel_data.integrator.use_volume_guiding || num_phases == 0) {
|
||||
state->guiding.use_volume_guiding = false;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, use_volume_guiding) = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -139,16 +139,17 @@ ccl_device_inline void volume_shader_prepare_guiding(KernelGlobals kg,
|
||||
const ccl_private ShaderVolumeClosure *svc = &phases->closure[phase_id];
|
||||
const float phase_g = volume_phase_get_g(svc);
|
||||
if (!guiding_phase_init(kg, state, P, D, phase_g, rand_phase_guiding)) {
|
||||
state->guiding.use_volume_guiding = false;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, use_volume_guiding) = false;
|
||||
return;
|
||||
}
|
||||
|
||||
state->guiding.use_volume_guiding = true;
|
||||
state->guiding.sample_volume_guiding_rand = rand_phase_guiding;
|
||||
state->guiding.volume_guiding_sampling_prob = volume_guiding_probability * phase_weight;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, use_volume_guiding) = true;
|
||||
INTEGRATOR_STATE_WRITE(state, guiding, sample_volume_guiding_rand) = rand_phase_guiding;
|
||||
INTEGRATOR_STATE_WRITE(
|
||||
state, guiding, volume_guiding_sampling_prob) = volume_guiding_probability * phase_weight;
|
||||
|
||||
kernel_assert(state->guiding.volume_guiding_sampling_prob > 0.0f &&
|
||||
state->guiding.volume_guiding_sampling_prob <= 1.0f);
|
||||
kernel_assert(INTEGRATOR_STATE(state, guiding, volume_guiding_sampling_prob) > 0.0f &&
|
||||
INTEGRATOR_STATE(state, guiding, volume_guiding_sampling_prob) <= 1.0f);
|
||||
}
|
||||
# endif
|
||||
|
||||
@@ -239,10 +240,13 @@ ccl_device float volume_shader_phase_eval(KernelGlobals kg,
|
||||
float pdf = _volume_shader_phase_eval_mis(sd, phases, wo, phase_eval, 0.0f, 0.0f);
|
||||
|
||||
# if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
|
||||
if (state->guiding.use_volume_guiding) {
|
||||
const float guiding_sampling_prob = state->guiding.volume_guiding_sampling_prob;
|
||||
const float guide_pdf = guiding_phase_pdf(kg, state, wo);
|
||||
pdf = (guiding_sampling_prob * guide_pdf) + (1.0f - guiding_sampling_prob) * pdf;
|
||||
if ((kernel_data.kernel_features & KERNEL_FEATURE_PATH_GUIDING)) {
|
||||
if (INTEGRATOR_STATE(state, guiding, use_volume_guiding)) {
|
||||
const float guiding_sampling_prob = INTEGRATOR_STATE(
|
||||
state, guiding, volume_guiding_sampling_prob);
|
||||
const float guide_pdf = guiding_phase_pdf(kg, state, wo);
|
||||
pdf = (guiding_sampling_prob * guide_pdf) + (1.0f - guiding_sampling_prob) * pdf;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
@@ -255,7 +259,7 @@ ccl_device float volume_shader_phase_eval(KernelGlobals kg,
|
||||
return pdf;
|
||||
}
|
||||
|
||||
# ifdef __PATH_GUIDING__
|
||||
# if defined(__PATH_GUIDING__)
|
||||
ccl_device int volume_shader_phase_guided_sample(KernelGlobals kg,
|
||||
IntegratorState state,
|
||||
const ccl_private ShaderData *sd,
|
||||
@@ -267,11 +271,12 @@ ccl_device int volume_shader_phase_guided_sample(KernelGlobals kg,
|
||||
ccl_private float *unguided_phase_pdf,
|
||||
ccl_private float *sampled_roughness)
|
||||
{
|
||||
const bool use_volume_guiding = state->guiding.use_volume_guiding;
|
||||
const float guiding_sampling_prob = state->guiding.volume_guiding_sampling_prob;
|
||||
const bool use_volume_guiding = INTEGRATOR_STATE(state, guiding, use_volume_guiding);
|
||||
const float guiding_sampling_prob = INTEGRATOR_STATE(
|
||||
state, guiding, volume_guiding_sampling_prob);
|
||||
|
||||
/* Decide between sampling guiding distribution and phase. */
|
||||
float rand_phase_guiding = state->guiding.sample_volume_guiding_rand;
|
||||
float rand_phase_guiding = INTEGRATOR_STATE(state, guiding, sample_volume_guiding_rand);
|
||||
bool sample_guiding = false;
|
||||
if (use_volume_guiding && rand_phase_guiding < guiding_sampling_prob) {
|
||||
sample_guiding = true;
|
||||
|
||||
@@ -201,7 +201,7 @@ CCL_NAMESPACE_BEGIN
|
||||
# endif
|
||||
#endif
|
||||
#ifndef __KERNEL_GPU__
|
||||
# ifdef WITH_PATH_GUIDING
|
||||
# if defined(WITH_PATH_GUIDING)
|
||||
# define __PATH_GUIDING__
|
||||
# endif
|
||||
# define __VOLUME_RECORD_ALL__
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef WITH_PATH_GUIDING
|
||||
#if defined(WITH_PATH_GUIDING)
|
||||
# include <openpgl/cpp/OpenPGL.h> // IWYU pragma: export
|
||||
# include <openpgl/version.h> // IWYU pragma: export
|
||||
#endif
|
||||
@@ -15,7 +15,7 @@ CCL_NAMESPACE_BEGIN
|
||||
|
||||
static int guiding_device_type()
|
||||
{
|
||||
#ifdef WITH_PATH_GUIDING
|
||||
#if defined(WITH_PATH_GUIDING)
|
||||
# if defined(__ARM_NEON)
|
||||
return 8;
|
||||
# else
|
||||
|
||||
Reference in New Issue
Block a user