Plowing straight ahead

This commit is contained in:
Wito Wiala 2026-05-19 22:54:27 +01:00
parent 050698c1d0
commit 44099dffa9
14 changed files with 87 additions and 126 deletions

View file

@ -1045,7 +1045,7 @@ const SRGB_TO_LINEAR_LUT: [Float; 256] = [
pub const RES: u32 = 64; pub const RES: u32 = 64;
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug, Default)] #[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct Coeffs { pub struct Coeffs {
pub c0: Float, pub c0: Float,
pub c1: Float, pub c1: Float,
@ -1099,10 +1099,10 @@ impl Mul<Float> for Coeffs {
} }
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct RGBToSpectrumTable { pub struct RGBToSpectrumTable {
pub z_nodes: Ptr<Float>, pub z_nodes: GVec<Float>,
pub coeffs: Ptr<Coeffs>, pub coeffs: GVec<Coeffs>,
pub n_nodes: u32, pub n_nodes: u32,
} }
@ -1113,7 +1113,7 @@ impl RGBToSpectrumTable {
#[inline(always)] #[inline(always)]
fn get_coeffs(&self, bucket: u32, z: u32, y: u32, x: u32) -> Coeffs { 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; 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 { pub fn evaluate(&self, rgb: RGB) -> RGBSigmoidPolynomial {
@ -1153,7 +1153,7 @@ impl RGBToSpectrumTable {
let x = coord_a / z; let x = coord_a / z;
let y = coord_b / 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 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 dz = (z - z_nodes[zi]) / (z_nodes[zi + 1] - z_nodes[zi]);
let x_float = x * (RES - 1) as Float; let x_float = x * (RES - 1) as Float;

View file

@ -18,5 +18,5 @@ pub mod textures;
pub mod utils; pub mod utils;
pub use core::pbrt::*; 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}; pub use utils::{Array2D, PBRTOptions, Ptr, Transform};

View file

@ -62,7 +62,7 @@ impl ColorSpaceId {
} }
#[repr(C)] #[repr(C)]
#[derive(Debug, Clone)] #[derive(Debug, Clone, Copy)]
pub struct RGBColorSpace { pub struct RGBColorSpace {
pub r: Point2f, pub r: Point2f,
pub g: Point2f, pub g: Point2f,
@ -71,7 +71,7 @@ pub struct RGBColorSpace {
pub xyz_from_rgb: SquareMatrix3f, pub xyz_from_rgb: SquareMatrix3f,
pub rgb_from_xyz: SquareMatrix3f, pub rgb_from_xyz: SquareMatrix3f,
pub illuminant: Ptr<DenselySampledSpectrum>, pub illuminant: Ptr<DenselySampledSpectrum>,
pub rgb_to_spectrum_table: RGBToSpectrumTable, pub rgb_to_spectrum_table: Ptr<RGBToSpectrumTable>,
} }
unsafe impl Send for RGBColorSpace {} unsafe impl Send for RGBColorSpace {}

View file

@ -1,8 +1,9 @@
extern crate alloc; extern crate alloc;
use crate::utils::ptr::Ptr;
use alloc::alloc::Global; use alloc::alloc::Global;
use alloc::vec::Vec;
use alloc::boxed::Box; use alloc::boxed::Box;
use alloc::vec::Vec;
use core::alloc::{AllocError, Allocator, Layout}; use core::alloc::{AllocError, Allocator, Layout};
use core::ptr::NonNull; 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> { pub fn gbox<T>(value: T) -> GBox<T> {
Box::new_in(value, GpuAlloc::default()) 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)
}

View file

@ -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 { pub fn scrambled_radical_inverse(base_index: u32, mut a: u64, perm: &DigitPermutation) -> Float {
let base = PRIMES[base_index as usize] as u64; let base = PRIMES[base_index as usize] as u64;

View file

@ -40,6 +40,7 @@ pub enum FloatTexture {
Mix(FloatMixTexture), Mix(FloatMixTexture),
DirectionMix(FloatDirectionMixTexture), DirectionMix(FloatDirectionMixTexture),
// #[device(custom = "upload_image", variant_type = "GPUFloatImageTexture")] // #[device(custom = "upload_image", variant_type = "GPUFloatImageTexture")]
Scaled(FloatScaledTexture)
Image(FloatImageTexture), Image(FloatImageTexture),
Bilerp(FloatBilerpTexture), Bilerp(FloatBilerpTexture),
} }
@ -105,6 +106,7 @@ impl FloatTexture {
} }
} }
#[derive(Clone, Debug)]
pub enum SpectrumTexture { pub enum SpectrumTexture {
Constant(SpectrumConstantTexture), Constant(SpectrumConstantTexture),
Checkerboard(SpectrumCheckerboardTexture), Checkerboard(SpectrumCheckerboardTexture),

View file

@ -1,6 +1,6 @@
use super::*; use super::*;
use crate::globals::get_options; 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 anyhow::{Result, anyhow};
use shared::core::geometry::Point2i; use shared::core::geometry::Point2i;
use shared::core::sampler::{HaltonSampler, MAX_HALTON_RESOLUTION, RandomizeStrategy}; use shared::core::sampler::{HaltonSampler, MAX_HALTON_RESOLUTION, RandomizeStrategy};

View file

@ -258,12 +258,12 @@ impl TriQuadMesh {
TriangleMesh::new( TriangleMesh::new(
render_from_object, render_from_object,
reverse_orientation, reverse_orientation,
self.tri_indices, &self.tri_indices,
self.p, &self.p,
self.n, &self.n,
Vec::new(), &Vec::new(),
self.uv, &self.uv,
self.face_indices, &self.face_indices,
) )
} }
} }

View file

@ -12,8 +12,8 @@ pub trait CreateRGBColorSpace {
r: Point2f, r: Point2f,
g: Point2f, g: Point2f,
b: Point2f, b: Point2f,
illuminant: Arc<DenselySampledSpectrum>, illuminant: &DenselySampledSpectrum,
rgb_to_spectrum_table: Ptr<RGBToSpectrumTable>, rgb_to_spectrum_table: &RGBToSpectrumTable,
) -> Self; ) -> Self;
} }
@ -22,11 +22,12 @@ impl CreateRGBColorSpace for RGBColorSpace {
r: Point2f, r: Point2f,
g: Point2f, g: Point2f,
b: Point2f, b: Point2f,
illuminant: Arc<DenselySampledSpectrum>, illuminant: &DenselySampledSpectrum,
rgb_to_spectrum_table: Ptr<RGBToSpectrumTable>, rgb_to_spectrum_table: &RGBToSpectrumTable,
) -> Self { ) -> Self {
let stdspec = get_spectra_context(); 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_xyz: XYZ = illum_spectrum.to_xyz(&stdspec);
let w = w_xyz.xy(); let w = w_xyz.xy();
@ -49,8 +50,8 @@ impl CreateRGBColorSpace for RGBColorSpace {
g, g,
b, b,
w, w,
illuminant: Ptr::from(illuminant.as_ref()), illuminant: illum_ptr,
rgb_to_spectrum_table, rgb_to_spectrum_table: Ptr::from(rgb_to_spectrum_table),
xyz_from_rgb, xyz_from_rgb,
rgb_from_xyz, rgb_from_xyz,
} }

View file

@ -1,7 +1,7 @@
use shared::Float;
use shared::core::spectrum::Spectrum; use shared::core::spectrum::Spectrum;
use shared::spectra::cie::*; 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::collections::HashMap;
use std::sync::LazyLock; use std::sync::LazyLock;
@ -17,7 +17,7 @@ pub fn create_cie(data: &[Float]) -> DenselySampledSpectrum {
.collect(); .collect();
let buffer = PiecewiseLinearSpectrum::new(lambdas, data.to_vec()); let buffer = PiecewiseLinearSpectrum::new(lambdas, data.to_vec());
let spec = Spectrum::Piecewise(buffer); let spec = Spectrum::Piecewise(Ptr::from(&*buffer));
DenselySampledSpectrum::from_spectrum(&spec) DenselySampledSpectrum::from_spectrum(&spec)
} }
@ -27,7 +27,7 @@ pub static NAMED_SPECTRA: LazyLock<HashMap<String, Spectrum>> = LazyLock::new(||
macro_rules! add { macro_rules! add {
($name:expr, $data:expr, $norm:expr) => { ($name:expr, $data:expr, $norm:expr) => {
let buffer = PiecewiseLinearSpectrum::from_interleaved($data, $norm); let buffer = PiecewiseLinearSpectrum::from_interleaved($data, $norm);
let spectrum = Spectrum::Piecewise(buffer); let spectrum = Spectrum::Piecewise(leak(buffer));
m.insert($name.to_string(), spectrum); 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!("stdillum-F12", &CIE_ILLUM_F12, true);
add!("illum-acesD60", &ACES_ILLUM_D60, true); add!("illum-acesD60", &ACES_ILLUM_D60, true);
// --- Glasses ---
add!("glass-BK7", &GLASS_BK7_ETA, false); add!("glass-BK7", &GLASS_BK7_ETA, false);
add!("glass-BAF10", &GLASS_BAF10_ETA, false); add!("glass-BAF10", &GLASS_BAF10_ETA, false);
add!("glass-FK51A", &GLASS_FK51A_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-F10", &GLASS_SF10_ETA, false);
add!("glass-F11", &GLASS_SF11_ETA, false); add!("glass-F11", &GLASS_SF11_ETA, false);
// --- Metals ---
add!("metal-Ag-eta", &AG_ETA, false); add!("metal-Ag-eta", &AG_ETA, false);
add!("metal-Ag-k", &AG_K, false); add!("metal-Ag-k", &AG_K, false);
add!("metal-Al-eta", &AL_ETA, 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-eta", &TIO2_ETA, false);
add!("metal-TiO2-k", &TIO2_K, 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_r", &CANON_EOS_100D_R, false);
add!("canon_eos_100d_g", &CANON_EOS_100D_G, false); add!("canon_eos_100d_g", &CANON_EOS_100D_G, false);
add!("canon_eos_100d_b", &CANON_EOS_100D_B, 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_r", &CANON_EOS_1DX_MKII_R, false);
add!("canon_eos_1dx_mkii_g", &CANON_EOS_1DX_MKII_G, 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); 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_r", &CANON_EOS_200D_R, false);
add!("canon_eos_200d_g", &CANON_EOS_200D_G, false); add!("canon_eos_200d_g", &CANON_EOS_200D_G, false);
add!("canon_eos_200d_b", &CANON_EOS_200D_B, 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_r", &CANON_EOS_200D_MKII_R, false);
add!("canon_eos_200d_mkii_g", &CANON_EOS_200D_MKII_G, 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); 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_r", &CANON_EOS_5D_R, false);
add!("canon_eos_5d_g", &CANON_EOS_5D_G, false); add!("canon_eos_5d_g", &CANON_EOS_5D_G, false);
add!("canon_eos_5d_b", &CANON_EOS_5D_B, 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_r", &CANON_EOS_5D_MKII_R, false);
add!("canon_eos_5d_mkii_g", &CANON_EOS_5D_MKII_G, 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); 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_r", &CANON_EOS_5D_MKIII_R, false);
add!("canon_eos_5d_mkiii_g", &CANON_EOS_5D_MKIII_G, 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); 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_r", &CANON_EOS_5D_MKIV_R, false);
add!("canon_eos_5d_mkiv_g", &CANON_EOS_5D_MKIV_G, 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); 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_r", &CANON_EOS_5DS_R, false);
add!("canon_eos_5ds_g", &CANON_EOS_5DS_G, false); add!("canon_eos_5ds_g", &CANON_EOS_5DS_G, false);
add!("canon_eos_5ds_b", &CANON_EOS_5DS_B, 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_r", &CANON_EOS_M_R, false);
add!("canon_eos_m_g", &CANON_EOS_M_G, false); add!("canon_eos_m_g", &CANON_EOS_M_G, false);
add!("canon_eos_m_b", &CANON_EOS_M_B, 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_r", &HASSELBLAD_L1D_20C_R, false);
add!("hasselblad_l1d_20c_g", &HASSELBLAD_L1D_20C_G, false); add!("hasselblad_l1d_20c_g", &HASSELBLAD_L1D_20C_G, false);
add!("hasselblad_l1d_20c_b", &HASSELBLAD_L1D_20C_B, false); add!("hasselblad_l1d_20c_b", &HASSELBLAD_L1D_20C_B, false);
// --- Nikon D810 ---
add!("nikon_d810_r", &NIKON_D810_R, false); add!("nikon_d810_r", &NIKON_D810_R, false);
add!("nikon_d810_g", &NIKON_D810_G, false); add!("nikon_d810_g", &NIKON_D810_G, false);
add!("nikon_d810_b", &NIKON_D810_B, false); add!("nikon_d810_b", &NIKON_D810_B, false);
// --- Nikon D850 ---
add!("nikon_d850_r", &NIKON_D850_R, false); add!("nikon_d850_r", &NIKON_D850_R, false);
add!("nikon_d850_g", &NIKON_D850_G, false); add!("nikon_d850_g", &NIKON_D850_G, false);
add!("nikon_d850_b", &NIKON_D850_B, 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_r", &SONY_ILCE_6400_R, false);
add!("sony_ilce_6400_g", &SONY_ILCE_6400_G, false); add!("sony_ilce_6400_g", &SONY_ILCE_6400_G, false);
add!("sony_ilce_6400_b", &SONY_ILCE_6400_B, 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_r", &SONY_ILCE_7M3_R, false);
add!("sony_ilce_7m3_g", &SONY_ILCE_7M3_G, false); add!("sony_ilce_7m3_g", &SONY_ILCE_7M3_G, false);
add!("sony_ilce_7m3_b", &SONY_ILCE_7M3_B, 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_r", &SONY_ILCE_7RM3_R, false);
add!("sony_ilce_7rm3_g", &SONY_ILCE_7RM3_G, false); add!("sony_ilce_7rm3_g", &SONY_ILCE_7RM3_G, false);
add!("sony_ilce_7rm3_b", &SONY_ILCE_7RM3_B, 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_r", &SONY_ILCE_9_R, false);
add!("sony_ilce_9_g", &SONY_ILCE_9_G, false); add!("sony_ilce_9_g", &SONY_ILCE_9_G, false);
add!("sony_ilce_9_b", &SONY_ILCE_9_B, false); add!("sony_ilce_9_b", &SONY_ILCE_9_B, false);

View file

@ -28,19 +28,16 @@ fn get_d65_illuminant_buffer() -> Arc<DenselySampledSpectrum> {
} }
pub fn cie_x() -> Spectrum { pub fn cie_x() -> Spectrum {
Spectrum::Dense(CIE_X_DATA) Spectrum::Dense(Ptr::from(&*CIE_X_DATA))
} }
pub fn cie_y() -> Spectrum { pub fn cie_y() -> Spectrum {
Spectrum::Dense(CIE_Y_DATA) Spectrum::Dense(Ptr::from(&*CIE_Y_DATA))
} }
pub fn cie_z() -> Spectrum { pub fn cie_z() -> Spectrum {
Spectrum::Dense(CIE_Z_DATA) Spectrum::Dense(Ptr::from(&*CIE_Z_DATA))
} }
pub fn cie_d65() -> Spectrum { pub fn cie_d65() -> Spectrum {
Spectrum::Dense(CIE_D65_DATA) Spectrum::Dense(Ptr::from(&*CIE_D65_DATA))
} }
pub fn get_spectra_context() -> StandardSpectra { pub fn get_spectra_context() -> StandardSpectra {
@ -52,6 +49,7 @@ pub fn get_spectra_context() -> StandardSpectra {
} }
} }
pub static SRGB: LazyLock<Arc<RGBColorSpace>> = LazyLock::new(|| { pub static SRGB: LazyLock<Arc<RGBColorSpace>> = LazyLock::new(|| {
let illum = get_d65_illuminant_buffer(); let illum = get_d65_illuminant_buffer();
let r = Point2f::new(0.64, 0.33); 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 r = Point2f::new(0.7347, 0.2653);
let g = Point2f::new(0.0000, 1.0000); let g = Point2f::new(0.0000, 1.0000);
let b = Point2f::new(0.0001, -0.0770); 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)) 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 { pub fn get_colorspace_device() -> DeviceStandardColorSpaces {
DeviceStandardColorSpaces { DeviceStandardColorSpaces {
srgb: Ptr::from(&*SRGB), srgb: Ptr::from(&**SRGB),
dci_p3: Ptr::from(&*DCI_P3), dci_p3: Ptr::from(&**DCI_P3),
rec2020: Ptr::from(&*REC2020), rec2020: Ptr::from(&**REC2020),
aces2065_1: Ptr::from(&*ACES), aces2065_1: Ptr::from(&**ACES),
} }
} }

View file

@ -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)
}

View file

@ -28,3 +28,28 @@ pub type Arena = arena::Arena<backend::cuda::CudaAllocator>;
#[cfg(not(any(feature = "cuda", feature = "vulkan")))] #[cfg(not(any(feature = "cuda", feature = "vulkan")))]
pub type Arena = arena::Arena<backend::SystemAllocator>; 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()
}
}

View file

@ -1,7 +1,7 @@
use crate::core::spectrum::SPECTRUM_FILE_CACHE; use crate::core::spectrum::SPECTRUM_FILE_CACHE;
use crate::spectra::piecewise::ReadFromFile;
use crate::core::texture::{FloatTexture, SpectrumTexture}; use crate::core::texture::{FloatTexture, SpectrumTexture};
use crate::spectra::data::get_named_spectrum; use crate::spectra::data::get_named_spectrum;
use crate::spectra::piecewise::ReadFromFile;
use crate::utils::FileLoc; use crate::utils::FileLoc;
use anyhow::{bail, Result}; use anyhow::{bail, Result};
use shared::core::color::RGB; use shared::core::color::RGB;
@ -655,11 +655,11 @@ impl ParameterDictionary {
}) })
.unzip(); .unzip();
vec![Spectrum::Piecewise(PiecewiseLinearSpectrum { vec![Spectrum::Piecewise(leak(PiecewiseLinearSpectrum {
lambdas: lambdas.as_ptr().into(), lambdas: gvec_from_slice(lambdas),
values: values.as_ptr().into(), values: gvec_from_slice(values),
count: lambdas.len() as u32, count: lambdas.len() as u32,
})] }))]
} }
fn extract_file_spectrum(&self, param: &ParsedParameter) -> Vec<Spectrum> { 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(); let cache = SPECTRUM_FILE_CACHE.lock();
if let Some(s) = cache.get(&fn_key) { 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) let pls = PiecewiseLinearSpectrum::read(&fn_key)
.ok_or_else(|| format!("unable to read or parse spectrum file '{}'", 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(); let mut cache = SPECTRUM_FILE_CACHE.lock();
cache.insert(fn_key, spectrum.clone()); cache.insert(fn_key, spectrum);
} }
Ok(spectrum) Ok(spectrum)