Revision: 14418
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=14418
Author:   blendix
Date:     2008-04-14 12:14:59 +0200 (Mon, 14 Apr 2008)

Log Message:
-----------

Attempted fix for bug #8349: QMC raytracing being very slow on some
computers, probably due to slow multithreaded malloc. Now each render
thread keeps a list of qmc samplers that it fills as needed while
rendering (since it is hard to predict the actual amount needed in
advance due to ray recursion).

Modified Paths:
--------------
    trunk/blender/source/blender/render/intern/include/render_types.h
    trunk/blender/source/blender/render/intern/include/rendercore.h
    trunk/blender/source/blender/render/intern/source/convertblender.c
    trunk/blender/source/blender/render/intern/source/rayshade.c

Modified: trunk/blender/source/blender/render/intern/include/render_types.h
===================================================================
--- trunk/blender/source/blender/render/intern/include/render_types.h   
2008-04-14 10:09:44 UTC (rev 14417)
+++ trunk/blender/source/blender/render/intern/include/render_types.h   
2008-04-14 10:14:59 UTC (rev 14418)
@@ -64,8 +64,10 @@
 
 typedef struct QMCSampler
 {
+       struct QMCSampler *next, *prev;
        int type;
        int tot;
+       int used;
        double *samp2d;
        double offs[BLENDER_MAX_THREADS][2];
 } QMCSampler;
@@ -150,7 +152,7 @@
        /* samples */
        SampleTables *samples;
        float jit[32][2];
-       QMCSampler *qsa;
+       ListBase *qmcsamplers;
        
        /* shadow counter, detect shadow-reuse for shaders */
        int shadowsamplenr[BLENDER_MAX_THREADS];
@@ -455,7 +457,6 @@
 
        struct ShadBuf *shb;
        float *jitter;
-       QMCSampler *qsa;
        
        float imat[3][3];
        float spottexfac;

Modified: trunk/blender/source/blender/render/intern/include/rendercore.h
===================================================================
--- trunk/blender/source/blender/render/intern/include/rendercore.h     
2008-04-14 10:09:44 UTC (rev 14417)
+++ trunk/blender/source/blender/render/intern/include/rendercore.h     
2008-04-14 10:14:59 UTC (rev 14418)
@@ -104,9 +104,7 @@
 extern void ray_ao(ShadeInput *, float *);
 extern void init_jitter_plane(LampRen *lar);
 extern void init_ao_sphere(struct World *wrld);
-extern void init_lamp_hammersley(LampRen *lar);
-extern void free_lamp_qmcsampler(LampRen *lar);
-extern void init_render_hammersley(Render *re);
+extern void init_render_qmcsampler(Render *re);
 extern void free_render_qmcsampler(Render *re);
 
 #endif /* RENDER_EXT_H */

Modified: trunk/blender/source/blender/render/intern/source/convertblender.c
===================================================================
--- trunk/blender/source/blender/render/intern/source/convertblender.c  
2008-04-14 10:09:44 UTC (rev 14417)
+++ trunk/blender/source/blender/render/intern/source/convertblender.c  
2008-04-14 10:14:59 UTC (rev 14418)
@@ -3684,9 +3684,6 @@
 
                if(re->r.mode & R_SHADOW) {
                        
-                       if ((lar->mode & LA_SHAD_RAY) && (lar->ray_samp_method 
== LA_SAMP_HAMMERSLEY)) {
-                               init_lamp_hammersley(lar);
-                       }
                        if(la->type==LA_AREA && (lar->mode & LA_SHAD_RAY) && 
(lar->ray_samp_method == LA_SAMP_CONSTANT)) {
                                init_jitter_plane(lar);
                        }
@@ -4372,7 +4369,6 @@
                freeshadowbuf(lar);
                if(lar->jitter) MEM_freeN(lar->jitter);
                if(lar->shadsamp) MEM_freeN(lar->shadsamp);
-               if(lar->qsa) free_lamp_qmcsampler(lar);
                curvemapping_free(lar->curfalloff);
        }
        
@@ -4410,8 +4406,7 @@
                re->wrld.aotables= NULL;
                re->scene->world->aotables= NULL;
        }
-       if((re->r.mode & R_RAYTRACE) && (re->wrld.mode & WO_AMB_OCC) &&
-           (re->wrld.ao_samp_method == WO_AOSAMP_HAMMERSLEY) && (re->qsa))
+       if(re->r.mode & R_RAYTRACE)
                free_render_qmcsampler(re);
        
        if(re->r.mode & R_RAYTRACE) freeraytree(re);
@@ -4786,11 +4781,12 @@
        }
        
        init_render_world(re);  /* do first, because of ambient. also requires 
re->osa set correct */
-       if((re->r.mode & R_RAYTRACE) && (re->wrld.mode & WO_AMB_OCC)) {
-               if (re->wrld.ao_samp_method == WO_AOSAMP_HAMMERSLEY)
-                       init_render_hammersley(re);
-               else if (re->wrld.ao_samp_method == WO_AOSAMP_CONSTANT)
-                       init_ao_sphere(&re->wrld);
+       if(re->r.mode & R_RAYTRACE) {
+               init_render_qmcsampler(re);
+
+               if(re->wrld.mode & WO_AMB_OCC)
+                       if (re->wrld.ao_samp_method == WO_AOSAMP_CONSTANT)
+                               init_ao_sphere(&re->wrld);
        }
        
        /* still bad... doing all */
@@ -5439,11 +5435,12 @@
        }
        
        init_render_world(re);  /* do first, because of ambient. also requires 
re->osa set correct */
-       if((re->r.mode & R_RAYTRACE) && (re->wrld.mode & WO_AMB_OCC)) {
-               if (re->wrld.ao_samp_method == WO_AOSAMP_HAMMERSLEY)
-                       init_render_hammersley(re);
-               else if (re->wrld.ao_samp_method == WO_AOSAMP_CONSTANT)
-                       init_ao_sphere(&re->wrld);
+       if(re->r.mode & R_RAYTRACE) {
+               init_render_qmcsampler(re);
+               
+               if(re->wrld.mode & WO_AMB_OCC)
+                       if (re->wrld.ao_samp_method == WO_AOSAMP_CONSTANT)
+                               init_ao_sphere(&re->wrld);
        }
        
        /* still bad... doing all */

Modified: trunk/blender/source/blender/render/intern/source/rayshade.c
===================================================================
--- trunk/blender/source/blender/render/intern/source/rayshade.c        
2008-04-14 10:09:44 UTC (rev 14417)
+++ trunk/blender/source/blender/render/intern/source/rayshade.c        
2008-04-14 10:14:59 UTC (rev 14418)
@@ -40,8 +40,9 @@
 #include "BKE_utildefines.h"
 
 #include "BLI_arithb.h"
+#include "BLI_blenlib.h"
+#include "BLI_jitter.h"
 #include "BLI_rand.h"
-#include "BLI_jitter.h"
 
 #include "PIL_time.h"
 
@@ -729,8 +730,8 @@
 
 struct QMCSampler *QMC_initSampler(int type, int tot)
 {      
-       QMCSampler *qsa = MEM_mallocN(sizeof(QMCSampler), "qmc sampler");
-       qsa->samp2d = MEM_mallocN(2*sizeof(double)*tot, "qmc sample table");
+       QMCSampler *qsa = MEM_callocN(sizeof(QMCSampler), "qmc sampler");
+       qsa->samp2d = MEM_callocN(2*sizeof(double)*tot, "qmc sample table");
 
        qsa->tot = tot;
        qsa->type = type;
@@ -871,27 +872,55 @@
 #endif
 
 /* called from convertBlenderScene.c */
-/* samples don't change per pixel, so build the samples in advance for 
efficiency */
-void init_lamp_hammersley(LampRen *lar)
+void init_render_qmcsampler(Render *re)
 {
-       lar->qsa = QMC_initSampler(SAMP_TYPE_HAMMERSLEY, lar->ray_totsamp);
+       re->qmcsamplers= MEM_callocN(sizeof(ListBase)*BLENDER_MAX_THREADS, 
"QMCListBase");
 }
 
-void init_render_hammersley(Render *re)
+QMCSampler *get_thread_qmcsampler(Render *re, int thread, int type, int tot)
 {
-       re->qsa = QMC_initSampler(SAMP_TYPE_HAMMERSLEY, (re->wrld.aosamp * 
re->wrld.aosamp));
+       QMCSampler *qsa;
+
+       /* create qmc samplers as needed, since recursion makes it hard to
+        * predict how many are needed */
+
+       for(qsa=re->qmcsamplers[thread].first; qsa; qsa=qsa->next) {
+               if(qsa->type == type && qsa->tot == tot && !qsa->used) {
+                       qsa->used= 1;
+                       return qsa;
+               }
+       }
+
+       qsa= QMC_initSampler(type, tot);
+       qsa->used= 1;
+       BLI_addtail(&re->qmcsamplers[thread], qsa);
+
+       return qsa;
 }
 
-void free_lamp_qmcsampler(LampRen *lar)
+void release_thread_qmcsampler(Render *re, int thread, QMCSampler *qsa)
 {
-       QMC_freeSampler(lar->qsa);
-       lar->qsa = NULL;
+       qsa->used= 0;
 }
 
 void free_render_qmcsampler(Render *re)
 {
-       QMC_freeSampler(re->qsa);
-       re->qsa = NULL;
+       QMCSampler *qsa, *next;
+       int a;
+
+       if(re->qmcsamplers) {
+               for(a=0; a<BLENDER_MAX_THREADS; a++) {
+                       for(qsa=re->qmcsamplers[a].first; qsa; qsa=next) {
+                               next= qsa->next;
+                               QMC_freeSampler(qsa);
+                       }
+
+                       re->qmcsamplers[a].first= re->qmcsamplers[a].last= NULL;
+               }
+
+               MEM_freeN(re->qmcsamplers);
+               re->qmcsamplers= NULL;
+       }
 }
 
 static int adaptive_sample_variance(int samples, float *col, float *colsq, 
float thresh)
@@ -968,7 +997,7 @@
                else samp_type = SAMP_TYPE_HAMMERSLEY;
                        
                /* all samples are generated per pixel */
-               qsa = QMC_initSampler(samp_type, max_samples);
+               qsa = get_thread_qmcsampler(&R, shi->thread, samp_type, 
max_samples);
                QMC_initPixel(qsa, shi->thread);
        } else 
                max_samples = 1;
@@ -1026,7 +1055,8 @@
        col[2] /= (float)samples;
        col[3] /= (float)samples;
        
-       if (qsa) QMC_freeSampler(qsa);
+       if (qsa)
+               release_thread_qmcsampler(&R, shi->thread, qsa);
 }
 
 static void trace_reflect(float *col, ShadeInput *shi, ShadeResult *shr, float 
fresnelfac)
@@ -1053,7 +1083,7 @@
                else samp_type = SAMP_TYPE_HAMMERSLEY;
                        
                /* all samples are generated per pixel */
-               qsa = QMC_initSampler(samp_type, max_samples);
+               qsa = get_thread_qmcsampler(&R, shi->thread, samp_type, 
max_samples);
                QMC_initPixel(qsa, shi->thread);
        } else 
                max_samples = 1;
@@ -1131,7 +1161,8 @@
        col[1] /= (float)samples;
        col[2] /= (float)samples;
        
-       if (qsa) QMC_freeSampler(qsa);
+       if (qsa)
+               release_thread_qmcsampler(&R, shi->thread, qsa);
 }
 
 /* extern call from render loop */
@@ -1546,9 +1577,9 @@
                max_samples /= speedfac;
                if (max_samples < 5) max_samples = 5;
                
-               qsa = QMC_initSampler(SAMP_TYPE_HALTON, max_samples);
+               qsa = get_thread_qmcsampler(&R, shi->thread, SAMP_TYPE_HALTON, 
max_samples);
        } else if (R.wrld.ao_samp_method==WO_AOSAMP_HAMMERSLEY)
-               qsa = R.qsa;
+               qsa = get_thread_qmcsampler(&R, shi->thread, 
SAMP_TYPE_HAMMERSLEY, max_samples);
 
        QMC_initPixel(qsa, shi->thread);
        
@@ -1621,7 +1652,8 @@
                shadfac[0]= shadfac[1]= shadfac[2]= 1.0f - fac/(float)samples;
        }
        
-       if ((qsa) && (qsa->type == SAMP_TYPE_HALTON)) QMC_freeSampler(qsa);
+       if (qsa)
+               release_thread_qmcsampler(&R, shi->thread, qsa);
 }
 
 /* extern call from shade_lamp_loop, ambient occlusion calculus */
@@ -1787,11 +1819,11 @@
 
        /* sampling init */
        if (lar->ray_samp_method==LA_SAMP_HALTON) {
-               qsa = QMC_initSampler(SAMP_TYPE_HALTON, max_samples);
-               qsa_jit = QMC_initSampler(SAMP_TYPE_HALTON, max_samples);
+               qsa = get_thread_qmcsampler(&R, shi->thread, SAMP_TYPE_HALTON, 
max_samples);
+               qsa_jit = get_thread_qmcsampler(&R, shi->thread, 
SAMP_TYPE_HALTON, max_samples);
        } else if (lar->ray_samp_method==LA_SAMP_HAMMERSLEY) {
-               qsa = lar->qsa;
-               qsa_jit = QMC_initSampler(SAMP_TYPE_HAMMERSLEY, max_samples);
+               qsa = get_thread_qmcsampler(&R, shi->thread, 
SAMP_TYPE_HAMMERSLEY, max_samples);
+               qsa_jit = get_thread_qmcsampler(&R, shi->thread, 
SAMP_TYPE_HAMMERSLEY, max_samples);
        }
        
        QMC_initPixel(qsa, shi->thread);
@@ -1921,8 +1953,10 @@
        } else
                shadfac[3]= 1.0f-fac/samples;
 
-       if (qsa_jit) QMC_freeSampler(qsa_jit);
-       if ((qsa) && (qsa->type == SAMP_TYPE_HALTON)) QMC_freeSampler(qsa);
+       if (qsa_jit)
+               release_thread_qmcsampler(&R, shi->thread, qsa_jit);
+       if (qsa)
+               release_thread_qmcsampler(&R, shi->thread, qsa);
 }
 
 static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, float *lampco, 
float *shadfac, Isect *isec)


_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to