Explicit downcasting to float part 2.
Converting double to half includes an implicit intermediate cast to float. That cast can be explicit through template specialization.metadata
parent
7962cd2e20
commit
13e63e66df
|
@ -614,8 +614,8 @@ public:
|
|||
const Value p11 = evalTexel(level, xPos+1, yPos+1);
|
||||
Value tmp = p01 + p10 - p11;
|
||||
|
||||
gradient[0] = (p10 + p00*(dy-1) - tmp*dy) * size.x;
|
||||
gradient[1] = (p01 + p00*(dx-1) - tmp*dx) * size.y;
|
||||
gradient[0] = (p10 + p00*(dy-1) - tmp*dy) * static_cast<Float> (size.x);
|
||||
gradient[1] = (p01 + p00*(dx-1) - tmp*dx) * static_cast<Float> (size.y);
|
||||
}
|
||||
|
||||
/// \brief Perform a filtered texture lookup using the configured method
|
||||
|
|
|
@ -67,6 +67,17 @@ extern "C" {
|
|||
|
||||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
namespace
|
||||
{
|
||||
// Safely convert between scalar types avoiding downcasting warning
|
||||
template <typename T, typename S> inline T safe_cast(S a) {
|
||||
return static_cast<T>(a);
|
||||
}
|
||||
template <> inline half safe_cast(double a) {
|
||||
return static_cast<half>(static_cast<float>(a));
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(MTS_HAS_OPENEXR)
|
||||
/* ========================== *
|
||||
* EXR helper classes *
|
||||
|
@ -869,7 +880,7 @@ void Bitmap::convolve(const Bitmap *_kernel) {
|
|||
* (double) input[(xs+ys*width)*m_channelCount+ch];
|
||||
}
|
||||
}
|
||||
output[(x+y*width)*m_channelCount+ch] = (half) result;
|
||||
output[(x+y*width)*m_channelCount+ch] = safe_cast<half>(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -982,7 +993,7 @@ void Bitmap::scale(Float value) {
|
|||
half *data = (half *) m_data;
|
||||
for (size_t i=0; i<nPixels; ++i) {
|
||||
for (size_t j=0; j<nChannels-1; ++j) {
|
||||
*data = (half) (*data * value); ++data;
|
||||
*data = safe_cast<half> (*data * value); ++data;
|
||||
}
|
||||
++data;
|
||||
}
|
||||
|
@ -1046,7 +1057,7 @@ void Bitmap::scale(Float value) {
|
|||
case EFloat16: {
|
||||
half *data = (half *) m_data;
|
||||
for (size_t i=0; i<nEntries; ++i)
|
||||
data[i] = (half) (data[i] * value);
|
||||
data[i] = safe_cast<half> (data[i] * value);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1504,9 +1515,9 @@ template <typename T> void tonemapReinhard(T *data, size_t pixels, Bitmap::EPixe
|
|||
Z = ratio * ((Float) 1.0f - x - y);
|
||||
|
||||
/* Convert from XYZ tristimulus values to ITU-R Rec. BT.709 linear RGB */
|
||||
data[0] = (T)( 3.240479f * X + -1.537150f * Y + -0.498535f * Z);
|
||||
data[1] = (T)( -0.969256f * X + 1.875991f * Y + 0.041556f * Z);
|
||||
data[2] = (T)( 0.055648f * X + -0.204043f * Y + 1.057311f * Z);
|
||||
data[0] = safe_cast<T>( 3.240479f * X + -1.537150f * Y + -0.498535f * Z);
|
||||
data[1] = safe_cast<T>( -0.969256f * X + 1.875991f * Y + 0.041556f * Z);
|
||||
data[2] = safe_cast<T>( 0.055648f * X + -0.204043f * Y + 1.057311f * Z);
|
||||
|
||||
data += channels;
|
||||
}
|
||||
|
@ -1531,9 +1542,9 @@ template <typename T> void tonemapReinhard(T *data, size_t pixels, Bitmap::EPixe
|
|||
X = ratio * x;
|
||||
Z = ratio * ((Float) 1.0f - x - y);
|
||||
|
||||
data[0] = (T) X;
|
||||
data[1] = (T) Y;
|
||||
data[2] = (T) Z;
|
||||
data[0] = safe_cast<T>(X);
|
||||
data[1] = safe_cast<T>(Y);
|
||||
data[2] = safe_cast<T>(Z);
|
||||
|
||||
data += channels;
|
||||
}
|
||||
|
@ -1544,7 +1555,7 @@ template <typename T> void tonemapReinhard(T *data, size_t pixels, Bitmap::EPixe
|
|||
Float Lp = (Float) *data * scale;
|
||||
|
||||
/* Apply the tonemapping transformation */
|
||||
*data = (T) (Lp * (1.0f + Lp*invWp2) / (1.0f + Lp));
|
||||
*data = safe_cast<T> (Lp * (1.0f + Lp*invWp2) / (1.0f + Lp));
|
||||
|
||||
data += channels;
|
||||
}
|
||||
|
@ -1795,7 +1806,7 @@ template <typename Scalar> static void resample(ref<const ReconstructionFilter>
|
|||
+ y * target->getWidth() * channels;
|
||||
|
||||
r.resampleAndClamp(srcPtr, 1, trgPtr, 1, channels,
|
||||
(Scalar) minValue, (Scalar) maxValue);
|
||||
safe_cast<Scalar>(minValue), safe_cast<Scalar>(maxValue));
|
||||
}
|
||||
|
||||
/* Now, read from the temporary bitmap */
|
||||
|
@ -1814,7 +1825,7 @@ template <typename Scalar> static void resample(ref<const ReconstructionFilter>
|
|||
Scalar *trgPtr = (Scalar *) target->getUInt8Data() + x * channels;
|
||||
|
||||
r.resampleAndClamp(srcPtr, source->getWidth(), trgPtr, target->getWidth(),
|
||||
channels, (Scalar) minValue, (Scalar) maxValue);
|
||||
channels, safe_cast<Scalar>(minValue), safe_cast<Scalar>(maxValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3228,7 +3239,7 @@ void Bitmap::readPFM(Stream *stream) {
|
|||
}
|
||||
|
||||
stream->setByteOrder(backup);
|
||||
Float scale = std::abs(scaleAndOrder);
|
||||
const float scale = std::abs(scaleAndOrder);
|
||||
if (scale != 1) {
|
||||
for (size_t i=0; i<size; ++i)
|
||||
data[i] *= scale;
|
||||
|
|
|
@ -68,13 +68,14 @@ namespace detail {
|
|||
};
|
||||
|
||||
// Safely convert from size_t to other types, avoiding downcasting warning
|
||||
template <typename T> inline T safe_cast(size_t a) {
|
||||
template <typename T, typename S> inline T safe_cast(S a) {
|
||||
return static_cast<T>(a);
|
||||
}
|
||||
|
||||
template <> inline half safe_cast(size_t a) {
|
||||
float tmp = static_cast<float>(a);
|
||||
return static_cast<half>(tmp);
|
||||
return static_cast<half>(static_cast<float>(a));
|
||||
}
|
||||
template <> inline half safe_cast(double a) {
|
||||
return static_cast<half>(static_cast<float>(a));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1140,10 +1141,10 @@ private:
|
|||
value = applyGamma(value, invDestGamma);
|
||||
|
||||
if (format_traits<DestFmt>::is_float)
|
||||
return (DestFmt) value;
|
||||
return detail::safe_cast<DestFmt> (value);
|
||||
else /* Round to nearest value and clamp to representable range */
|
||||
return (DestFmt) std::min(static_cast<Float>(std::numeric_limits<DestFmt>::max()),
|
||||
std::max((Float) 0, value * (Float) std::numeric_limits<DestFmt>::max() + (Float) 0.5f));
|
||||
return detail::safe_cast<DestFmt> (std::min(static_cast<Float>(std::numeric_limits<DestFmt>::max()),
|
||||
std::max((Float) 0, value * (Float) std::numeric_limits<DestFmt>::max() + (Float) 0.5f)));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -115,8 +115,8 @@ public:
|
|||
m_distortion = false;
|
||||
} else if (kc_tokens.size() == 2) {
|
||||
char *end_ptr0, *end_ptr1;
|
||||
m_kc[0] = std::strtod(kc_tokens[0].c_str(), &end_ptr0);
|
||||
m_kc[1] = std::strtod(kc_tokens[1].c_str(), &end_ptr1);
|
||||
m_kc[0] = (Float) std::strtod(kc_tokens[0].c_str(), &end_ptr0);
|
||||
m_kc[1] = (Float) std::strtod(kc_tokens[1].c_str(), &end_ptr1);
|
||||
if (*end_ptr0 != '\0' || *end_ptr1 != 0)
|
||||
Log(EError, "Invalid input to the 'kc' parameter!");
|
||||
m_distortion = m_kc[0] != 0 || m_kc[1] != 0;
|
||||
|
|
|
@ -299,6 +299,10 @@ public:
|
|||
value[0] = a; value[1] = b; value[2] = c;
|
||||
}
|
||||
|
||||
inline explicit float3(double a, double b, double c) {
|
||||
value[0] = (float) a; value[1] = (float) b; value[2] = (float) c;
|
||||
}
|
||||
|
||||
inline float3 operator*(Float v) const {
|
||||
return float3((float) (value[0]*v), (float) (value[1]*v), (float) (value[2]*v));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue