
Was causing calculation issues later on in the kernel. This change catches the most obvious case: missing attribute. The old code was trying to set tangent to 0, but because it was transformed as a normal it got converted to non-finite value. This change makes it so that no transform is involved and 0 is written directly to the SVM stack. To cover all cases it will require using safe_normalize() in this node and in the normal transform function. This is more involved change from performance point of view, would be nice to verify whether we really want to go this route. I've left asserts in the BSDF allocation functions. Don't have strong connection to them, but think they are handy and are not different from having an assert in the path radiance checks. Differential Revision: https://developer.blender.org/D11235
111 lines
3.1 KiB
C
111 lines
3.1 KiB
C
/*
|
|
* Copyright 2011-2016 Blender Foundation
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
CCL_NAMESPACE_BEGIN
|
|
|
|
ccl_device ShaderClosure *closure_alloc(ShaderData *sd, int size, ClosureType type, float3 weight)
|
|
{
|
|
kernel_assert(size <= sizeof(ShaderClosure));
|
|
|
|
if (sd->num_closure_left == 0)
|
|
return NULL;
|
|
|
|
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_addr_space void *closure_alloc_extra(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_addr_space void *)(sd->closure + sd->num_closure + sd->num_closure_left);
|
|
}
|
|
|
|
ccl_device_inline ShaderClosure *bsdf_alloc(ShaderData *sd, int size, float3 weight)
|
|
{
|
|
kernel_assert(isfinite3_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 == 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,
|
|
float3 weight,
|
|
void *data)
|
|
{
|
|
kernel_assert(isfinite3_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
|