22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
24 * THE SOFTWARE. |
24 * THE SOFTWARE. |
25 */ |
25 */ |
26 |
26 |
27 #ifdef PTHREADS |
|
28 #include <pthread.h> |
27 #include <pthread.h> |
29 #endif |
|
30 |
|
31 #include <stdio.h> |
28 #include <stdio.h> |
32 #include <malloc.h> |
29 #include <malloc.h> |
33 #include "raytracer.h" |
30 #include "raytracer.h" |
34 |
31 |
35 int pyrit_verbosity = 2; |
32 int pyrit_verbosity = 4; |
36 |
33 |
37 // Hammersley spherical point distribution |
34 // Hammersley spherical point distribution |
38 // http://www.cse.cuhk.edu.hk/~ttwong/papers/udpoint/udpoints.html |
35 // http://www.cse.cuhk.edu.hk/~ttwong/papers/udpoint/udpoints.html |
39 Vector3 Raytracer::SphereDistribute(int i, int n, Float extent, Vector3 &normal) |
36 Vector3 Raytracer::SphereDistribute(int i, int n, Float extent, Vector3 &normal) |
40 { |
37 { |
405 for (;;) |
402 for (;;) |
406 { |
403 { |
407 pthread_mutex_lock(&rt->sample_queue_mutex); |
404 pthread_mutex_lock(&rt->sample_queue_mutex); |
408 pthread_cond_signal(&rt->worker_ready_cond); |
405 pthread_cond_signal(&rt->worker_ready_cond); |
409 |
406 |
410 while (rt->sample_queue.empty()) { |
407 while (rt->sample_queue_count == 0) |
|
408 { |
411 if (rt->sample_queue_end) |
409 if (rt->sample_queue_end) |
412 { |
410 { |
|
411 dbgmsg(4, "T thread [%d] exiting\n", pthread_self()); |
413 pthread_mutex_unlock(&rt->sample_queue_mutex); |
412 pthread_mutex_unlock(&rt->sample_queue_mutex); |
414 pthread_exit(NULL); |
413 pthread_exit(NULL); |
415 } |
414 } |
416 pthread_cond_wait(&rt->sample_queue_cond, &rt->sample_queue_mutex); |
415 pthread_cond_wait(&rt->sample_queue_cond, &rt->sample_queue_mutex); |
417 } |
416 } |
418 |
417 |
419 sample = rt->sample_queue.front(); |
418 sample = rt->sample_queue[rt->sample_queue_pos++]; |
420 rt->sample_queue.pop(); |
419 rt->sample_queue_count--; |
|
420 if (rt->sample_queue_pos > rt->sample_queue_max) |
|
421 rt->sample_queue_pos = 0; |
421 |
422 |
422 pthread_mutex_unlock(&rt->sample_queue_mutex); |
423 pthread_mutex_unlock(&rt->sample_queue_mutex); |
423 |
424 |
424 // do the work |
425 // do the work |
425 pthread_mutex_lock(&rt->sampler_mutex); |
426 pthread_mutex_lock(&rt->sampler_mutex); |
441 { |
442 { |
442 if (!sampler || !camera || !top) |
443 if (!sampler || !camera || !top) |
443 return; |
444 return; |
444 |
445 |
445 sample_queue_end = false; |
446 sample_queue_end = false; |
|
447 sample_queue_max = 2000; |
|
448 sample_queue = new Sample* [sample_queue_max+1]; |
|
449 sample_queue_pos = 0; |
|
450 sample_queue_count = 0; |
446 |
451 |
447 // create workers |
452 // create workers |
448 dbgmsg(1, "* running %d threads\n", num_threads); |
453 dbgmsg(1, "* running %d threads\n", num_threads); |
449 pthread_t threads[num_threads]; |
454 pthread_t threads[num_threads]; |
450 for (int t = 0; t < num_threads; t++) |
455 for (int t = 0; t < num_threads; t++) |
458 |
463 |
459 dbgmsg(1, "* raytracing...\n"); |
464 dbgmsg(1, "* raytracing...\n"); |
460 dbgmsg(2, "- 0%% done"); |
465 dbgmsg(2, "- 0%% done"); |
461 |
466 |
462 sampler->init(); |
467 sampler->init(); |
|
468 Sample *sample; |
463 int sampnum = 0, sampdone; |
469 int sampnum = 0, sampdone; |
464 Sample *sample; |
470 int my_pos = 0, my_count; |
465 |
471 |
466 pthread_mutex_lock(&sampler_mutex); |
472 pthread_mutex_lock(&sampler_mutex); |
467 while ( (sampnum = sampler->initSampleSet()) > 0 ) |
473 while ( (sampnum = sampler->initSampleSet()) > 0 ) |
468 { |
474 { |
469 sampdone = 0; |
475 sampdone = 0; |
470 while ( (sample = sampler->nextSample()) != NULL ) |
476 for (;;) |
471 { |
477 { |
|
478 my_count = 0; |
|
479 while ( (sample = sampler->nextSample()) != NULL ) |
|
480 { |
|
481 sample_queue[my_pos++] = sample; |
|
482 my_count++; |
|
483 if (my_count >= 1000) |
|
484 break; |
|
485 if (my_pos > sample_queue_max) |
|
486 my_pos = 0; |
|
487 } |
|
488 if (sample == NULL) |
|
489 break; |
|
490 |
472 pthread_mutex_unlock(&sampler_mutex); |
491 pthread_mutex_unlock(&sampler_mutex); |
473 pthread_mutex_lock(&sample_queue_mutex); |
492 pthread_mutex_lock(&sample_queue_mutex); |
474 sample_queue.push(sample); |
493 sample_queue_count += my_count; |
475 |
494 |
476 // wait for workers if there is enough samples ready on queue |
495 // wait for workers if there is enough samples ready on queue |
477 if (sample_queue.size() > 1000) |
496 while (sample_queue_count > 1000) |
478 { |
497 { |
479 while (sample_queue.size() > 100) |
498 pthread_cond_signal(&sample_queue_cond); |
480 { |
499 pthread_cond_wait(&worker_ready_cond, &sample_queue_mutex); |
481 pthread_cond_signal(&sample_queue_cond); |
500 } |
482 pthread_cond_wait(&worker_ready_cond, &sample_queue_mutex); |
501 |
483 } |
502 sampdone += my_count; |
484 } |
503 dbgmsg(2, "\b\b\b\b\b\b\b\b%2d%% done", (sampdone - sample_queue_count)*100/sampnum); |
485 |
|
486 sampdone++; |
|
487 if ((sampdone & 0xfff) == 0) |
|
488 dbgmsg(2, "\b\b\b\b\b\b\b\b%2d%% done", (sampdone - sample_queue.size())*100/sampnum); |
|
489 |
504 |
490 pthread_cond_signal(&sample_queue_cond); |
505 pthread_cond_signal(&sample_queue_cond); |
491 pthread_mutex_unlock(&sample_queue_mutex); |
506 pthread_mutex_unlock(&sample_queue_mutex); |
492 pthread_mutex_lock(&sampler_mutex); |
507 pthread_mutex_lock(&sampler_mutex); |
493 } |
508 } |
498 // wait for workers |
513 // wait for workers |
499 dbgmsg(2, "- waiting for threads to finish\n"); |
514 dbgmsg(2, "- waiting for threads to finish\n"); |
500 |
515 |
501 pthread_mutex_lock(&sample_queue_mutex); |
516 pthread_mutex_lock(&sample_queue_mutex); |
502 sample_queue_end = true; |
517 sample_queue_end = true; |
503 while (!sample_queue.empty()) |
518 while (sample_queue_count) |
504 { |
519 { |
505 pthread_cond_broadcast(&sample_queue_cond); |
520 pthread_cond_broadcast(&sample_queue_cond); |
506 pthread_mutex_unlock(&sample_queue_mutex); |
521 pthread_mutex_unlock(&sample_queue_mutex); |
507 pthread_mutex_lock(&sample_queue_mutex); |
522 pthread_mutex_lock(&sample_queue_mutex); |
508 } |
523 } |
510 pthread_mutex_unlock(&sample_queue_mutex); |
525 pthread_mutex_unlock(&sample_queue_mutex); |
511 |
526 |
512 for (int t = 0; t < num_threads; t++) |
527 for (int t = 0; t < num_threads; t++) |
513 pthread_join(threads[t], NULL); |
528 pthread_join(threads[t], NULL); |
514 |
529 |
|
530 delete[] sample_queue; |
|
531 |
515 #if 0 |
532 #if 0 |
516 |
|
517 RenderrowData *d; |
533 RenderrowData *d; |
518 |
534 |
519 Float S = 0.5/w; |
535 Float S = 0.5/w; |
520 Vector3 dfix = camera->u*(-w/2.0*S/camera->f) |
536 Vector3 dfix = camera->u*(-w/2.0*S/camera->f) |
521 + camera->v*(h/2.0*S/camera->f) + camera->p; |
537 + camera->v*(h/2.0*S/camera->f) + camera->p; |