Plowing straight ahead
This commit is contained in:
parent
050698c1d0
commit
44099dffa9
14 changed files with 87 additions and 126 deletions
|
|
@ -1045,7 +1045,7 @@ const SRGB_TO_LINEAR_LUT: [Float; 256] = [
|
|||
pub const RES: u32 = 64;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq)]
|
||||
pub struct Coeffs {
|
||||
pub c0: Float,
|
||||
pub c1: Float,
|
||||
|
|
@ -1099,10 +1099,10 @@ impl Mul<Float> for Coeffs {
|
|||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct RGBToSpectrumTable {
|
||||
pub z_nodes: Ptr<Float>,
|
||||
pub coeffs: Ptr<Coeffs>,
|
||||
pub z_nodes: GVec<Float>,
|
||||
pub coeffs: GVec<Coeffs>,
|
||||
pub n_nodes: u32,
|
||||
}
|
||||
|
||||
|
|
@ -1113,7 +1113,7 @@ impl RGBToSpectrumTable {
|
|||
#[inline(always)]
|
||||
fn get_coeffs(&self, bucket: u32, z: u32, y: u32, x: u32) -> Coeffs {
|
||||
let offset = bucket * (RES * RES * RES) + z * (RES * RES) + y * (RES) + x;
|
||||
unsafe { *self.coeffs.add(offset as usize) }
|
||||
unsafe { *self.coeffs.as_ptr().add(offset as usize) }
|
||||
}
|
||||
|
||||
pub fn evaluate(&self, rgb: RGB) -> RGBSigmoidPolynomial {
|
||||
|
|
@ -1153,7 +1153,7 @@ impl RGBToSpectrumTable {
|
|||
let x = coord_a / z;
|
||||
let y = coord_b / z;
|
||||
|
||||
let z_nodes = unsafe { core::slice::from_raw_parts(self.z_nodes.as_raw(), RES as usize) };
|
||||
let z_nodes = &self.z_nodes;
|
||||
let zi = find_interval(RES, |i| z_nodes[i as usize] < z) as usize;
|
||||
let dz = (z - z_nodes[zi]) / (z_nodes[zi + 1] - z_nodes[zi]);
|
||||
let x_float = x * (RES - 1) as Float;
|
||||
|
|
|
|||
|
|
@ -18,5 +18,5 @@ pub mod textures;
|
|||
pub mod utils;
|
||||
|
||||
pub use core::pbrt::*;
|
||||
pub use utils::alloc::{gbox, gvec, gvec_from_slice, gvec_with_capacity, GVec, GBox};
|
||||
pub use utils::alloc::{gbox, gvec, gvec_from_slice, gvec_with_capacity, leak, GBox, GVec};
|
||||
pub use utils::{Array2D, PBRTOptions, Ptr, Transform};
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ impl ColorSpaceId {
|
|||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct RGBColorSpace {
|
||||
pub r: Point2f,
|
||||
pub g: Point2f,
|
||||
|
|
@ -71,7 +71,7 @@ pub struct RGBColorSpace {
|
|||
pub xyz_from_rgb: SquareMatrix3f,
|
||||
pub rgb_from_xyz: SquareMatrix3f,
|
||||
pub illuminant: Ptr<DenselySampledSpectrum>,
|
||||
pub rgb_to_spectrum_table: RGBToSpectrumTable,
|
||||
pub rgb_to_spectrum_table: Ptr<RGBToSpectrumTable>,
|
||||
}
|
||||
|
||||
unsafe impl Send for RGBColorSpace {}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
extern crate alloc;
|
||||
|
||||
use crate::utils::ptr::Ptr;
|
||||
use alloc::alloc::Global;
|
||||
use alloc::vec::Vec;
|
||||
use alloc::boxed::Box;
|
||||
use alloc::vec::Vec;
|
||||
use core::alloc::{AllocError, Allocator, Layout};
|
||||
use core::ptr::NonNull;
|
||||
|
||||
|
|
@ -200,3 +201,9 @@ pub fn gvec_from_slice<T: Clone>(slice: &[T]) -> GVec<T> {
|
|||
pub fn gbox<T>(value: T) -> GBox<T> {
|
||||
Box::new_in(value, GpuAlloc::default())
|
||||
}
|
||||
|
||||
pub fn leak<T: 'static>(val: T) -> Ptr<T> {
|
||||
let b = gbox(val);
|
||||
let leaked: &'static T = Box::leak(b);
|
||||
Ptr::from(leaked)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -827,6 +827,12 @@ impl DigitPermutation {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn compute_radical_inverse_permutations(seed: u64) -> GVec<DigitPermutation> {
|
||||
let mut result = gvec();
|
||||
result.extend(PRIMES.iter().map(|&base| DigitPermutation::new(base as i32, seed)));
|
||||
result
|
||||
}
|
||||
|
||||
pub fn scrambled_radical_inverse(base_index: u32, mut a: u64, perm: &DigitPermutation) -> Float {
|
||||
let base = PRIMES[base_index as usize] as u64;
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ pub enum FloatTexture {
|
|||
Mix(FloatMixTexture),
|
||||
DirectionMix(FloatDirectionMixTexture),
|
||||
// #[device(custom = "upload_image", variant_type = "GPUFloatImageTexture")]
|
||||
Scaled(FloatScaledTexture)
|
||||
Image(FloatImageTexture),
|
||||
Bilerp(FloatBilerpTexture),
|
||||
}
|
||||
|
|
@ -105,6 +106,7 @@ impl FloatTexture {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum SpectrumTexture {
|
||||
Constant(SpectrumConstantTexture),
|
||||
Checkerboard(SpectrumCheckerboardTexture),
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use super::*;
|
||||
use crate::globals::get_options;
|
||||
use crate::utils::math::compute_radical_inverse_permutations;
|
||||
use shared::utils::math::compute_radical_inverse_permutations;
|
||||
use anyhow::{Result, anyhow};
|
||||
use shared::core::geometry::Point2i;
|
||||
use shared::core::sampler::{HaltonSampler, MAX_HALTON_RESOLUTION, RandomizeStrategy};
|
||||
|
|
|
|||
|
|
@ -258,12 +258,12 @@ impl TriQuadMesh {
|
|||
TriangleMesh::new(
|
||||
render_from_object,
|
||||
reverse_orientation,
|
||||
self.tri_indices,
|
||||
self.p,
|
||||
self.n,
|
||||
Vec::new(),
|
||||
self.uv,
|
||||
self.face_indices,
|
||||
&self.tri_indices,
|
||||
&self.p,
|
||||
&self.n,
|
||||
&Vec::new(),
|
||||
&self.uv,
|
||||
&self.face_indices,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ pub trait CreateRGBColorSpace {
|
|||
r: Point2f,
|
||||
g: Point2f,
|
||||
b: Point2f,
|
||||
illuminant: Arc<DenselySampledSpectrum>,
|
||||
rgb_to_spectrum_table: Ptr<RGBToSpectrumTable>,
|
||||
illuminant: &DenselySampledSpectrum,
|
||||
rgb_to_spectrum_table: &RGBToSpectrumTable,
|
||||
) -> Self;
|
||||
}
|
||||
|
||||
|
|
@ -22,11 +22,12 @@ impl CreateRGBColorSpace for RGBColorSpace {
|
|||
r: Point2f,
|
||||
g: Point2f,
|
||||
b: Point2f,
|
||||
illuminant: Arc<DenselySampledSpectrum>,
|
||||
rgb_to_spectrum_table: Ptr<RGBToSpectrumTable>,
|
||||
illuminant: &DenselySampledSpectrum,
|
||||
rgb_to_spectrum_table: &RGBToSpectrumTable,
|
||||
) -> Self {
|
||||
let stdspec = get_spectra_context();
|
||||
let illum_spectrum = Spectrum::Dense(illuminant.as_ref().clone());
|
||||
let illum_ptr = Ptr::from(illuminant);
|
||||
let illum_spectrum = Spectrum::Dense(illuminant);
|
||||
let w_xyz: XYZ = illum_spectrum.to_xyz(&stdspec);
|
||||
let w = w_xyz.xy();
|
||||
|
||||
|
|
@ -49,8 +50,8 @@ impl CreateRGBColorSpace for RGBColorSpace {
|
|||
g,
|
||||
b,
|
||||
w,
|
||||
illuminant: Ptr::from(illuminant.as_ref()),
|
||||
rgb_to_spectrum_table,
|
||||
illuminant: illum_ptr,
|
||||
rgb_to_spectrum_table: Ptr::from(rgb_to_spectrum_table),
|
||||
xyz_from_rgb,
|
||||
rgb_from_xyz,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use shared::Float;
|
||||
use shared::core::spectrum::Spectrum;
|
||||
use shared::spectra::cie::*;
|
||||
use shared::spectra::{PiecewiseLinearSpectrum, DenselySampledSpectrum};
|
||||
use shared::spectra::{DenselySampledSpectrum, PiecewiseLinearSpectrum};
|
||||
use shared::{gbox, leak, Float, Ptr};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::LazyLock;
|
||||
|
||||
|
|
@ -17,7 +17,7 @@ pub fn create_cie(data: &[Float]) -> DenselySampledSpectrum {
|
|||
.collect();
|
||||
|
||||
let buffer = PiecewiseLinearSpectrum::new(lambdas, data.to_vec());
|
||||
let spec = Spectrum::Piecewise(buffer);
|
||||
let spec = Spectrum::Piecewise(Ptr::from(&*buffer));
|
||||
DenselySampledSpectrum::from_spectrum(&spec)
|
||||
}
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ pub static NAMED_SPECTRA: LazyLock<HashMap<String, Spectrum>> = LazyLock::new(||
|
|||
macro_rules! add {
|
||||
($name:expr, $data:expr, $norm:expr) => {
|
||||
let buffer = PiecewiseLinearSpectrum::from_interleaved($data, $norm);
|
||||
let spectrum = Spectrum::Piecewise(buffer);
|
||||
let spectrum = Spectrum::Piecewise(leak(buffer));
|
||||
m.insert($name.to_string(), spectrum);
|
||||
};
|
||||
}
|
||||
|
|
@ -49,7 +49,6 @@ pub static NAMED_SPECTRA: LazyLock<HashMap<String, Spectrum>> = LazyLock::new(||
|
|||
add!("stdillum-F12", &CIE_ILLUM_F12, true);
|
||||
add!("illum-acesD60", &ACES_ILLUM_D60, true);
|
||||
|
||||
// --- Glasses ---
|
||||
add!("glass-BK7", &GLASS_BK7_ETA, false);
|
||||
add!("glass-BAF10", &GLASS_BAF10_ETA, false);
|
||||
add!("glass-FK51A", &GLASS_FK51A_ETA, false);
|
||||
|
|
@ -58,7 +57,6 @@ pub static NAMED_SPECTRA: LazyLock<HashMap<String, Spectrum>> = LazyLock::new(||
|
|||
add!("glass-F10", &GLASS_SF10_ETA, false);
|
||||
add!("glass-F11", &GLASS_SF11_ETA, false);
|
||||
|
||||
// --- Metals ---
|
||||
add!("metal-Ag-eta", &AG_ETA, false);
|
||||
add!("metal-Ag-k", &AG_K, false);
|
||||
add!("metal-Al-eta", &AL_ETA, false);
|
||||
|
|
@ -74,87 +72,70 @@ pub static NAMED_SPECTRA: LazyLock<HashMap<String, Spectrum>> = LazyLock::new(||
|
|||
add!("metal-TiO2-eta", &TIO2_ETA, false);
|
||||
add!("metal-TiO2-k", &TIO2_K, false);
|
||||
|
||||
// --- Canon EOS 100D ---
|
||||
add!("canon_eos_100d_r", &CANON_EOS_100D_R, false);
|
||||
add!("canon_eos_100d_g", &CANON_EOS_100D_G, false);
|
||||
add!("canon_eos_100d_b", &CANON_EOS_100D_B, false);
|
||||
|
||||
// --- Canon EOS 1DX MkII ---
|
||||
add!("canon_eos_1dx_mkii_r", &CANON_EOS_1DX_MKII_R, false);
|
||||
add!("canon_eos_1dx_mkii_g", &CANON_EOS_1DX_MKII_G, false);
|
||||
add!("canon_eos_1dx_mkii_b", &CANON_EOS_1DX_MKII_B, false);
|
||||
|
||||
// --- Canon EOS 200D ---
|
||||
add!("canon_eos_200d_r", &CANON_EOS_200D_R, false);
|
||||
add!("canon_eos_200d_g", &CANON_EOS_200D_G, false);
|
||||
add!("canon_eos_200d_b", &CANON_EOS_200D_B, false);
|
||||
|
||||
// --- Canon EOS 200D MkII ---
|
||||
add!("canon_eos_200d_mkii_r", &CANON_EOS_200D_MKII_R, false);
|
||||
add!("canon_eos_200d_mkii_g", &CANON_EOS_200D_MKII_G, false);
|
||||
add!("canon_eos_200d_mkii_b", &CANON_EOS_200D_MKII_B, false);
|
||||
|
||||
// --- Canon EOS 5D ---
|
||||
add!("canon_eos_5d_r", &CANON_EOS_5D_R, false);
|
||||
add!("canon_eos_5d_g", &CANON_EOS_5D_G, false);
|
||||
add!("canon_eos_5d_b", &CANON_EOS_5D_B, false);
|
||||
|
||||
// --- Canon EOS 5D MkII ---
|
||||
add!("canon_eos_5d_mkii_r", &CANON_EOS_5D_MKII_R, false);
|
||||
add!("canon_eos_5d_mkii_g", &CANON_EOS_5D_MKII_G, false);
|
||||
add!("canon_eos_5d_mkii_b", &CANON_EOS_5D_MKII_B, false);
|
||||
|
||||
// --- Canon EOS 5D MkIII ---
|
||||
add!("canon_eos_5d_mkiii_r", &CANON_EOS_5D_MKIII_R, false);
|
||||
add!("canon_eos_5d_mkiii_g", &CANON_EOS_5D_MKIII_G, false);
|
||||
add!("canon_eos_5d_mkiii_b", &CANON_EOS_5D_MKIII_B, false);
|
||||
|
||||
// --- Canon EOS 5D MkIV ---
|
||||
add!("canon_eos_5d_mkiv_r", &CANON_EOS_5D_MKIV_R, false);
|
||||
add!("canon_eos_5d_mkiv_g", &CANON_EOS_5D_MKIV_G, false);
|
||||
add!("canon_eos_5d_mkiv_b", &CANON_EOS_5D_MKIV_B, false);
|
||||
|
||||
// --- Canon EOS 5DS ---
|
||||
add!("canon_eos_5ds_r", &CANON_EOS_5DS_R, false);
|
||||
add!("canon_eos_5ds_g", &CANON_EOS_5DS_G, false);
|
||||
add!("canon_eos_5ds_b", &CANON_EOS_5DS_B, false);
|
||||
|
||||
// --- Canon EOS M ---
|
||||
add!("canon_eos_m_r", &CANON_EOS_M_R, false);
|
||||
add!("canon_eos_m_g", &CANON_EOS_M_G, false);
|
||||
add!("canon_eos_m_b", &CANON_EOS_M_B, false);
|
||||
|
||||
// --- Hasselblad L1D 20C ---
|
||||
add!("hasselblad_l1d_20c_r", &HASSELBLAD_L1D_20C_R, false);
|
||||
add!("hasselblad_l1d_20c_g", &HASSELBLAD_L1D_20C_G, false);
|
||||
add!("hasselblad_l1d_20c_b", &HASSELBLAD_L1D_20C_B, false);
|
||||
|
||||
// --- Nikon D810 ---
|
||||
add!("nikon_d810_r", &NIKON_D810_R, false);
|
||||
add!("nikon_d810_g", &NIKON_D810_G, false);
|
||||
add!("nikon_d810_b", &NIKON_D810_B, false);
|
||||
|
||||
// --- Nikon D850 ---
|
||||
add!("nikon_d850_r", &NIKON_D850_R, false);
|
||||
add!("nikon_d850_g", &NIKON_D850_G, false);
|
||||
add!("nikon_d850_b", &NIKON_D850_B, false);
|
||||
|
||||
// --- Sony ILCE 6400 ---
|
||||
add!("sony_ilce_6400_r", &SONY_ILCE_6400_R, false);
|
||||
add!("sony_ilce_6400_g", &SONY_ILCE_6400_G, false);
|
||||
add!("sony_ilce_6400_b", &SONY_ILCE_6400_B, false);
|
||||
|
||||
// --- Sony ILCE 7M3 ---
|
||||
add!("sony_ilce_7m3_r", &SONY_ILCE_7M3_R, false);
|
||||
add!("sony_ilce_7m3_g", &SONY_ILCE_7M3_G, false);
|
||||
add!("sony_ilce_7m3_b", &SONY_ILCE_7M3_B, false);
|
||||
|
||||
// --- Sony ILCE 7RM3 ---
|
||||
add!("sony_ilce_7rm3_r", &SONY_ILCE_7RM3_R, false);
|
||||
add!("sony_ilce_7rm3_g", &SONY_ILCE_7RM3_G, false);
|
||||
add!("sony_ilce_7rm3_b", &SONY_ILCE_7RM3_B, false);
|
||||
|
||||
// --- Sony ILCE 9 ---
|
||||
add!("sony_ilce_9_r", &SONY_ILCE_9_R, false);
|
||||
add!("sony_ilce_9_g", &SONY_ILCE_9_G, false);
|
||||
add!("sony_ilce_9_b", &SONY_ILCE_9_B, false);
|
||||
|
|
|
|||
|
|
@ -28,19 +28,16 @@ fn get_d65_illuminant_buffer() -> Arc<DenselySampledSpectrum> {
|
|||
}
|
||||
|
||||
pub fn cie_x() -> Spectrum {
|
||||
Spectrum::Dense(CIE_X_DATA)
|
||||
Spectrum::Dense(Ptr::from(&*CIE_X_DATA))
|
||||
}
|
||||
|
||||
pub fn cie_y() -> Spectrum {
|
||||
Spectrum::Dense(CIE_Y_DATA)
|
||||
Spectrum::Dense(Ptr::from(&*CIE_Y_DATA))
|
||||
}
|
||||
|
||||
pub fn cie_z() -> Spectrum {
|
||||
Spectrum::Dense(CIE_Z_DATA)
|
||||
Spectrum::Dense(Ptr::from(&*CIE_Z_DATA))
|
||||
}
|
||||
|
||||
pub fn cie_d65() -> Spectrum {
|
||||
Spectrum::Dense(CIE_D65_DATA)
|
||||
Spectrum::Dense(Ptr::from(&*CIE_D65_DATA))
|
||||
}
|
||||
|
||||
pub fn get_spectra_context() -> StandardSpectra {
|
||||
|
|
@ -52,6 +49,7 @@ pub fn get_spectra_context() -> StandardSpectra {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
pub static SRGB: LazyLock<Arc<RGBColorSpace>> = LazyLock::new(|| {
|
||||
let illum = get_d65_illuminant_buffer();
|
||||
let r = Point2f::new(0.64, 0.33);
|
||||
|
|
@ -85,7 +83,7 @@ pub static ACES: LazyLock<Arc<RGBColorSpaceData>> = LazyLock::new(|| {
|
|||
let r = Point2f::new(0.7347, 0.2653);
|
||||
let g = Point2f::new(0.0000, 1.0000);
|
||||
let b = Point2f::new(0.0001, -0.0770);
|
||||
let table_ptr = Ptr::from(&ACES_TABLE.view);
|
||||
let table_ptr = Ptr::from(&ACES_TABLE);
|
||||
Arc::new(RGBColorSpace::new(r, g, b, illum, table_ptr))
|
||||
});
|
||||
|
||||
|
|
@ -120,10 +118,10 @@ pub fn get_colorspace_context() -> StandardColorSpaces {
|
|||
|
||||
pub fn get_colorspace_device() -> DeviceStandardColorSpaces {
|
||||
DeviceStandardColorSpaces {
|
||||
srgb: Ptr::from(&*SRGB),
|
||||
dci_p3: Ptr::from(&*DCI_P3),
|
||||
rec2020: Ptr::from(&*REC2020),
|
||||
aces2065_1: Ptr::from(&*ACES),
|
||||
srgb: Ptr::from(&**SRGB),
|
||||
dci_p3: Ptr::from(&**DCI_P3),
|
||||
rec2020: Ptr::from(&**REC2020),
|
||||
aces2065_1: Ptr::from(&**ACES),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,59 +0,0 @@
|
|||
use half::f16;
|
||||
use shared::utils::hash::hash_buffer;
|
||||
use shared::utils::math::{permutation_element, DigitPermutation, PRIMES};
|
||||
use shared::Float;
|
||||
|
||||
#[inline(always)]
|
||||
pub fn f16_to_f32(bits: u16) -> f32 {
|
||||
#[cfg(feature = "cuda")]
|
||||
{
|
||||
// Use hardware intrinsic on CUDA
|
||||
// Cast bits to cuda_f16, then cast to f32
|
||||
let half_val = unsafe { core::mem::transmute::<u16, cuda_std::f16>(bits) };
|
||||
half_val.to_f32()
|
||||
}
|
||||
|
||||
#[cfg(feature = "vulkan")]
|
||||
{
|
||||
// Use shared logic or spirv-std intrinsics if available.
|
||||
// Sadly, f16 support in rust-gpu is still maturing.
|
||||
// A manual bit-conversion function is often safest here.
|
||||
f16_to_f32_software(bits)
|
||||
}
|
||||
|
||||
#[cfg(not(any(feature = "cuda", feature = "vulkan")))]
|
||||
{
|
||||
f16::from_bits(bits).to_f32()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn compute_radical_inverse_permutations(seed: u64) -> (Vec<u16>, Vec<DigitPermutation>) {
|
||||
let temp_data: Vec<Vec<u16>> = PRIMES
|
||||
.iter()
|
||||
.map(|&base| DigitPermutation::new(base as i32, seed).permutations)
|
||||
.collect();
|
||||
let mut storage: Vec<u16> = Vec::with_capacity(temp_data.iter().map(|v| v.len()).sum());
|
||||
|
||||
for vec in &temp_data {
|
||||
storage.extend_from_slice(vec);
|
||||
}
|
||||
|
||||
let mut views = Vec::with_capacity(PRIMES.len());
|
||||
// let mut current_offset = 0;
|
||||
|
||||
// let storage_base_ptr = storage.as_ptr();
|
||||
|
||||
for (i, &base) in PRIMES.iter().enumerate() {
|
||||
let len = temp_data[i].len();
|
||||
let n_digits = len as u32 / base as u32;
|
||||
|
||||
// let ptr_to_data = storage_base_ptr.add(current_offset);
|
||||
|
||||
views.push(DigitPermutation::new(base as i32, n_digits as u64));
|
||||
|
||||
// current_offset += len;
|
||||
}
|
||||
|
||||
(storage, views)
|
||||
}
|
||||
|
|
@ -28,3 +28,28 @@ pub type Arena = arena::Arena<backend::cuda::CudaAllocator>;
|
|||
|
||||
#[cfg(not(any(feature = "cuda", feature = "vulkan")))]
|
||||
pub type Arena = arena::Arena<backend::SystemAllocator>;
|
||||
|
||||
use half::f16;
|
||||
|
||||
#[inline(always)]
|
||||
pub fn f16_to_f32(bits: u16) -> f32 {
|
||||
#[cfg(feature = "cuda")]
|
||||
{
|
||||
// Use hardware intrinsic on CUDA
|
||||
// Cast bits to cuda_f16, then cast to f32
|
||||
let half_val = unsafe { core::mem::transmute::<u16, cuda_std::f16>(bits) };
|
||||
half_val.to_f32()
|
||||
}
|
||||
|
||||
#[cfg(feature = "vulkan")]
|
||||
{
|
||||
// Use shared logic or spirv-std intrinsics if available.
|
||||
// Keep an eye on rust-gpu
|
||||
f16_to_f32_software(bits)
|
||||
}
|
||||
|
||||
#[cfg(not(any(feature = "cuda", feature = "vulkan")))]
|
||||
{
|
||||
f16::from_bits(bits).to_f32()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use crate::core::spectrum::SPECTRUM_FILE_CACHE;
|
||||
use crate::spectra::piecewise::ReadFromFile;
|
||||
use crate::core::texture::{FloatTexture, SpectrumTexture};
|
||||
use crate::spectra::data::get_named_spectrum;
|
||||
use crate::spectra::piecewise::ReadFromFile;
|
||||
use crate::utils::FileLoc;
|
||||
use anyhow::{bail, Result};
|
||||
use shared::core::color::RGB;
|
||||
|
|
@ -655,11 +655,11 @@ impl ParameterDictionary {
|
|||
})
|
||||
.unzip();
|
||||
|
||||
vec![Spectrum::Piecewise(PiecewiseLinearSpectrum {
|
||||
lambdas: lambdas.as_ptr().into(),
|
||||
values: values.as_ptr().into(),
|
||||
vec![Spectrum::Piecewise(leak(PiecewiseLinearSpectrum {
|
||||
lambdas: gvec_from_slice(lambdas),
|
||||
values: gvec_from_slice(values),
|
||||
count: lambdas.len() as u32,
|
||||
})]
|
||||
}))]
|
||||
}
|
||||
|
||||
fn extract_file_spectrum(&self, param: &ParsedParameter) -> Vec<Spectrum> {
|
||||
|
|
@ -681,18 +681,18 @@ fn read_spectrum_from_file(filename: &str) -> Result<Spectrum, String> {
|
|||
{
|
||||
let cache = SPECTRUM_FILE_CACHE.lock();
|
||||
if let Some(s) = cache.get(&fn_key) {
|
||||
return Ok(s.clone());
|
||||
return Ok(*s); // Spectrum is Copy, so just copy it
|
||||
}
|
||||
}
|
||||
|
||||
let pls = PiecewiseLinearSpectrum::read(&fn_key)
|
||||
.ok_or_else(|| format!("unable to read or parse spectrum file '{}'", fn_key))?;
|
||||
|
||||
let spectrum = Spectrum::Piecewise(*pls);
|
||||
let spectrum = Spectrum::Piecewise(leak(pls));
|
||||
|
||||
{
|
||||
let mut cache = SPECTRUM_FILE_CACHE.lock();
|
||||
cache.insert(fn_key, spectrum.clone());
|
||||
cache.insert(fn_key, spectrum);
|
||||
}
|
||||
|
||||
Ok(spectrum)
|
||||
|
|
|
|||
Loading…
Reference in a new issue