@@ -68,6 +68,7 @@ static void print_stats(const struct world *scene) {
6868
6969void * render_thread (void * arg );
7070void * render_thread_interactive (void * arg );
71+ void * render_single_iteration (void * arg );
7172
7273//FIXME: Statistics computation is a gigantic mess. It will also break in the case
7374//where a worker node disconnects during a render, so maybe fix that next.
@@ -495,6 +496,73 @@ void *render_thread(void *arg) {
495496 return 0 ;
496497}
497498
499+ void * render_single_iteration (void * arg ) {
500+ struct worker * threadState = arg ;
501+ struct renderer * r = threadState -> renderer ;
502+ struct texture * * buf = threadState -> buf ;
503+ // FIXME: persist this
504+ sampler * sampler = sampler_new ();
505+
506+ struct camera * cam = threadState -> cam ;
507+
508+ //First time setup for each thread
509+ struct render_tile * tile = tile_next (threadState -> tiles );
510+ if (!tile ) {
511+ threadState -> thread_complete = true;
512+ return NULL ;
513+ }
514+ threadState -> currentTile = tile ;
515+
516+ struct timeval timer = { 0 };
517+ size_t samples = 1 ;
518+
519+ long total_us = 0 ;
520+
521+ while (samples < r -> prefs .sampleCount + 1 && r -> state .s == r_rendering ) {
522+ timer_start (& timer );
523+ for (int y = tile -> end .y - 1 ; y > tile -> begin .y - 1 ; -- y ) {
524+ for (int x = tile -> begin .x ; x < tile -> end .x ; ++ x ) {
525+ if (r -> state .s != r_rendering ) goto exit ;
526+ uint32_t pixIdx = (uint32_t )(y * (* buf )-> width + x );
527+ sampler_init (sampler , SAMPLING_STRATEGY , samples - 1 , r -> prefs .sampleCount , pixIdx );
528+
529+ struct color output = tex_get_px (* buf , x , y , false);
530+ thread_rwlock_rdlock (& r -> scene -> bvh_lock );
531+ struct color sample = path_trace (cam_get_ray (cam , x , y , sampler ), r -> scene , r -> prefs .bounces , sampler );
532+ thread_rwlock_unlock (& r -> scene -> bvh_lock );
533+
534+ // Clamp out fireflies - This is probably not a good way to do that.
535+ nan_clamp (& sample , & output );
536+
537+ //And process the running average
538+ output = colorCoef ((float )(samples - 1 ), output );
539+ output = colorAdd (output , sample );
540+ float t = 1.0f / samples ;
541+ output = colorCoef (t , output );
542+
543+ //Store internal render buffer (float precision)
544+ tex_set_px (* buf , output , x , y );
545+ }
546+ }
547+ //For performance metrics
548+ total_us += timer_get_us (timer );
549+ threadState -> totalSamples ++ ;
550+ samples ++ ;
551+ tile -> completed_samples ++ ;
552+ //Pause rendering when bool is set
553+ // while (threadState->paused && r->state.s == r_rendering) {
554+ // timer_sleep_ms(100);
555+ // }
556+ threadState -> avg_per_sample_us = total_us / samples ;
557+ }
558+ tile -> state = finished ;
559+ threadState -> currentTile = NULL ;
560+ exit :
561+ sampler_destroy (sampler );
562+ threadState -> currentTile = NULL ;
563+ return 0 ;
564+ }
565+
498566struct prefs default_prefs (void ) {
499567 return (struct prefs ){
500568 .tileOrder = ro_from_middle ,
0 commit comments