Files
blender/intern/cycles/kernel/closure/alloc.h
Andrii Symkin d832d993c5 Cycles: add new Spectrum and PackedSpectrum types
These replace float3 and packed_float3 in various places in the kernel where a
spectral color representation will be used in the future. That representation
will require more than 3 channels and conversion to from/RGB. The kernel code
was refactored to remove the assumption that Spectrum and RGB colors are the
same thing.

There are no functional changes, Spectrum is still a float3 and the conversion
functions are no-ops.

Differential Revision: https://developer.blender.org/D15535
2022-08-09 16:49:34 +02:00

105 lines
2.9 KiB
C

/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
#pragma once
CCL_NAMESPACE_BEGIN
ccl_device ccl_private ShaderClosure *closure_alloc(ccl_private ShaderData *sd,
int size,
ClosureType type,
Spectrum weight)
{
kernel_assert(size <= sizeof(ShaderClosure));
if (sd->num_closure_left == 0)
return NULL;
ccl_private ShaderClosure *sc = &sd->closure[sd->num_closure];
sc->type = type;
sc->weight = weight;
sd->num_closure++;
sd->num_closure_left--;
return sc;
}
ccl_device ccl_private void *closure_alloc_extra(ccl_private ShaderData *sd, int size)
{
/* Allocate extra space for closure that need more parameters. We allocate
* in chunks of sizeof(ShaderClosure) starting from the end of the closure
* array.
*
* This lets us keep the same fast array iteration over closures, as we
* found linked list iteration and iteration with skipping to be slower. */
int num_extra = ((size + sizeof(ShaderClosure) - 1) / sizeof(ShaderClosure));
if (num_extra > sd->num_closure_left) {
/* Remove previous closure if it was allocated. */
sd->num_closure--;
sd->num_closure_left++;
return NULL;
}
sd->num_closure_left -= num_extra;
return (ccl_private void *)(sd->closure + sd->num_closure + sd->num_closure_left);
}
ccl_device_inline ccl_private ShaderClosure *bsdf_alloc(ccl_private ShaderData *sd,
int size,
Spectrum weight)
{
kernel_assert(isfinite_safe(weight));
const float sample_weight = fabsf(average(weight));
/* Use comparison this way to help dealing with non-finite weight: if the average is not finite
* we will not allocate new closure. */
if (sample_weight >= CLOSURE_WEIGHT_CUTOFF) {
ccl_private ShaderClosure *sc = closure_alloc(sd, size, CLOSURE_NONE_ID, weight);
if (sc == NULL) {
return NULL;
}
sc->sample_weight = sample_weight;
return sc;
}
return NULL;
}
#ifdef __OSL__
ccl_device_inline ShaderClosure *bsdf_alloc_osl(ShaderData *sd,
int size,
Spectrum weight,
void *data)
{
kernel_assert(isfinite_safe(weight));
const float sample_weight = fabsf(average(weight));
/* Use comparison this way to help dealing with non-finite weight: if the average is not finite
* we will not allocate new closure. */
if (sample_weight >= CLOSURE_WEIGHT_CUTOFF) {
ShaderClosure *sc = closure_alloc(sd, size, CLOSURE_NONE_ID, weight);
if (!sc) {
return NULL;
}
memcpy((void *)sc, data, size);
sc->weight = weight;
sc->sample_weight = sample_weight;
return sc;
}
return NULL;
}
#endif
CCL_NAMESPACE_END