()
| 21 | } |
| 22 | |
| 23 | fn main() -> Result<(), Box<dyn Error>> { |
| 24 | let opt = Opt::from_args(); |
| 25 | let name = opt |
| 26 | .input |
| 27 | .file_name() |
| 28 | .expect("input was not a file") |
| 29 | .to_string_lossy() |
| 30 | .to_string(); |
| 31 | let img = Reader::open(opt.input)?.decode()?; |
| 32 | |
| 33 | let mut rgb = img.into_rgb8(); |
| 34 | let mut linear = vec![Vec3::<f32>::zero(); rgb.as_raw().len()]; |
| 35 | |
| 36 | let width = rgb.width(); |
| 37 | let height = rgb.height(); |
| 38 | |
| 39 | rgb.pixels() |
| 40 | .zip(linear.iter_mut()) |
| 41 | .for_each(|(rgb, linear)| { |
| 42 | let rgbvec = Vec3::<u8>::from(rgb.0); |
| 43 | *linear = rgbvec.numcast::<f32>().unwrap().map(|x| x / 255.0); |
| 44 | }); |
| 45 | |
| 46 | // set up CUDA and OptiX then make the needed structs/contexts. |
| 47 | let cuda_ctx = cust::quick_init()?; |
| 48 | optix::init()?; |
| 49 | let optix_ctx = DeviceContext::new(&cuda_ctx, false)?; |
| 50 | |
| 51 | let stream = Stream::new(StreamFlags::NON_BLOCKING, None)?; |
| 52 | |
| 53 | // set up the denoiser, choosing Ldr as our model because our colors are in |
| 54 | // the 0.0 - 1.0 range. |
| 55 | let mut denoiser = Denoiser::new(&optix_ctx, DenoiserModelKind::Ldr, Default::default())?; |
| 56 | |
| 57 | // setup the optix state for our required image dimensions. this allocates the required |
| 58 | // state and scratch memory for further invocations. |
| 59 | denoiser.setup_state(&stream, width, height, false)?; |
| 60 | |
| 61 | // allocate the buffer for the noisy image and copy the data to the GPU. |
| 62 | let in_buf = linear.as_slice().as_dbuf()?; |
| 63 | |
| 64 | let mut out_buf = DeviceBuffer::<Vec3<f32>>::zeroed((width * height) as usize)?; |
| 65 | |
| 66 | // make an image to tell OptiX about how our image buffer is represented |
| 67 | let input_image = Image::new(&in_buf, ImageFormat::Float3, width, height); |
| 68 | |
| 69 | // Invoke the denoiser on the image. OptiX will queue up the work on the |
| 70 | // CUDA stream. |
| 71 | denoiser.invoke( |
| 72 | &stream, |
| 73 | Default::default(), |
| 74 | input_image, |
| 75 | DenoiserParams::default(), |
| 76 | &mut out_buf, |
| 77 | )?; |
| 78 | |
| 79 | // Finally, synchronize the stream to wait until the denoiser is finished doing its work. |
| 80 | stream.synchronize()?; |
nothing calls this directly
no test coverage detected