diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2007-12-18 00:04:22 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2007-12-18 00:04:22 +0300 |
commit | 25a434fd250a740ef23263af11d0a53a2539007b (patch) | |
tree | 3c644b792f82bbf50832f5084853ab9c54b25376 /source/blender | |
parent | 5dfef1ae3580aeef8601fca4883bf186be82f29d (diff) |
Threaded Shadowbuffers Creation
===============================
- One shadowbuffer per thread.
- Added more break tests in shadow buffer code.
- Removed R.clipcrop global, solution is not nice yet, but at
least threadsafe.
- Fixed bug in strand render shadow buffer code.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/render/intern/include/render_types.h | 4 | ||||
-rw-r--r-- | source/blender/render/intern/include/shadbuf.h | 2 | ||||
-rw-r--r-- | source/blender/render/intern/include/zbuf.h | 4 | ||||
-rw-r--r-- | source/blender/render/intern/source/convertblender.c | 29 | ||||
-rw-r--r-- | source/blender/render/intern/source/pipeline.c | 2 | ||||
-rw-r--r-- | source/blender/render/intern/source/rendercore.c | 2 | ||||
-rw-r--r-- | source/blender/render/intern/source/shadbuf.c | 109 | ||||
-rw-r--r-- | source/blender/render/intern/source/strand.c | 2 | ||||
-rw-r--r-- | source/blender/render/intern/source/zbuf.c | 51 |
9 files changed, 151 insertions, 54 deletions
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index 84230bd4f6d..4a731878ffb 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -446,6 +446,10 @@ typedef struct LampRen { ObjectInstanceRen *obi_last[BLENDER_MAX_THREADS]; struct MTex *mtex[MAX_MTEX]; + + /* threading */ + int thread_assigned; + int thread_ready; } LampRen; /* **************** defines ********************* */ diff --git a/source/blender/render/intern/include/shadbuf.h b/source/blender/render/intern/include/shadbuf.h index b4f196a89fa..20a266f8579 100644 --- a/source/blender/render/intern/include/shadbuf.h +++ b/source/blender/render/intern/include/shadbuf.h @@ -46,6 +46,8 @@ struct ObjectRen; void makeshadowbuf(struct Render *re, LampRen *lar); void freeshadowbuf(struct LampRen *lar); +void threaded_makeshadowbufs(struct Render *re); + /** * Determines the shadow factor for a face and lamp. There is some * communication with global variables here. diff --git a/source/blender/render/intern/include/zbuf.h b/source/blender/render/intern/include/zbuf.h index 5f1aa5679bf..4d30c1e0dfb 100644 --- a/source/blender/render/intern/include/zbuf.h +++ b/source/blender/render/intern/include/zbuf.h @@ -91,6 +91,8 @@ typedef struct ZSpan { float shad_alpha; /* copy from material, used by irregular shadbuf */ int mask, apsmcounter; /* in use by apixbuf */ + float clipcrop; /* for shadow, was in R global before */ + void *sss_handle; /* used by sss */ void (*sss_func)(void *, int, int, int, int, int); @@ -108,7 +110,7 @@ void zspan_scanconvert(struct ZSpan *zpan, void *handle, float *v1, float *v2, f /* exported to edge render... */ void zbufclip(struct ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3, int c1, int c2, int c3); -void zbuf_alloc_span(struct ZSpan *zspan, int rectx, int recty); +void zbuf_alloc_span(struct ZSpan *zspan, int rectx, int recty, float clipcrop); void zbufclipwire(struct ZSpan *zspan, int obi, int zvlnr, int ec, float *ho1, float *ho2, float *ho3, float *ho4, int c1, int c2, int c3, int c4); /* exported to shadeinput.c */ diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 4b683441833..c18409c1d00 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -4209,7 +4209,6 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view) database_init_objects(re, lay, 0, 0, 0, 0); if(!re->test_break()) { - LampRen *lar; int tothalo; set_material_lightgroups(re); @@ -4237,13 +4236,7 @@ void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view) re->stats_draw(&re->i); /* SHADOW BUFFER */ - for(lar=re->lampren.first; lar; lar= lar->next) { - if(re->test_break()) break; - if(lar->shb) { - /* if type is irregular, this only sets the perspective matrix and autoclips */ - makeshadowbuf(re, lar); - } - } + threaded_makeshadowbufs(re); /* yafray: 'direct' radiosity, environment maps and raytree init not needed for yafray render */ /* although radio mode could be useful at some point, later */ @@ -4767,22 +4760,10 @@ void RE_Database_Baking(Render *re, Scene *scene, int type, Object *actob) set_material_lightgroups(re); - if(type!=RE_BAKE_LIGHT) { - if(re->r.mode & R_SHADOW) { - LampRen *lar; - - /* SHADOW BUFFER */ - for(lar=re->lampren.first; lar; lar= lar->next) { - - if(re->test_break()) break; - if(lar->shb) { - /* if type is irregular, this only sets the perspective matrix and autoclips */ - /* but, that's not supported for bake... */ - makeshadowbuf(re, lar); - } - } - } - } + /* SHADOW BUFFER */ + if(type!=RE_BAKE_LIGHT) + if(re->r.mode & R_SHADOW) + threaded_makeshadowbufs(re); /* raytree */ if(!re->test_break()) diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 1c3867a702c..da2542aabaa 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -1251,7 +1251,6 @@ static void render_tile_processor(Render *re, int firsttile) } freeparts(re); - R.strandbuckets= NULL; } /* calculus for how much 1 pixel rendered should rotate the 3d geometry */ @@ -1485,7 +1484,6 @@ static void threaded_tile_processor(Render *re) BLI_end_threads(&threads); freeparts(re); re->viewplane= viewplane; /* restore viewplane, modified by pano render */ - R.strandbuckets= NULL; } /* currently only called by preview renders and envmap */ diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 631a2c184ed..0a9078b32f0 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -2090,7 +2090,7 @@ static void shade_tface(BakeShade *bs) bs->ibuf= BKE_image_get_ibuf(ima, NULL); /* note, these calls only free/fill contents of zspan struct, not zspan itself */ zbuf_free_span(bs->zspan); - zbuf_alloc_span(bs->zspan, bs->ibuf->x, bs->ibuf->y); + zbuf_alloc_span(bs->zspan, bs->ibuf->x, bs->ibuf->y, R.clipcrop); } bs->rectx= bs->ibuf->x; diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c index b424a0688fd..8e37606cdf9 100644 --- a/source/blender/render/intern/source/shadbuf.c +++ b/source/blender/render/intern/source/shadbuf.c @@ -42,6 +42,8 @@ #include "BLI_memarena.h" #include "BLI_rand.h" +#include "PIL_time.h" + #include "renderpipeline.h" #include "render_types.h" #include "renderdatabase.h" @@ -379,9 +381,6 @@ void makeshadowbuf(Render *re, LampRen *lar) float wsize, *jitbuf, twozero[2]= {0.0f, 0.0f}, angle, temp; int *rectz, samples; - /* XXXX EVIL! this global is used in clippyra(), zbuf.c */ - R.clipcrop= 1.0f; - if(lar->bufflag & (LA_SHADBUF_AUTO_START|LA_SHADBUF_AUTO_END)) shadowbuf_autoclip(re, lar); @@ -402,8 +401,10 @@ void makeshadowbuf(Render *re, LampRen *lar) if(ELEM(lar->buftype, LA_SHADBUF_REGULAR, LA_SHADBUF_HALFWAY)) { /* jitter, weights - not threadsafe! */ + BLI_lock_thread(LOCK_CUSTOM1); shb->jit= give_jitter_tab(shb->samp); make_jitter_weight_tab(shb, lar->filtertype); + BLI_unlock_thread(LOCK_CUSTOM1); shb->totbuf= lar->buffers; if(shb->totbuf==4) jitbuf= give_jitter_tab(2); @@ -417,6 +418,9 @@ void makeshadowbuf(Render *re, LampRen *lar) zbuffer_shadow(re, shb->persmat, lar, rectz, shb->size, jitbuf[2*samples], jitbuf[2*samples+1]); /* create Z tiles (for compression): this system is 24 bits!!! */ compress_shadowbuf(shb, rectz, lar->mode & LA_SQUARE); + + if(re->test_break()) + break; } MEM_freeN(rectz); @@ -425,6 +429,103 @@ void makeshadowbuf(Render *re, LampRen *lar) } } +static void *do_shadow_thread(void *re_v) +{ + Render *re= (Render*)re_v; + LampRen *lar; + + do { + BLI_lock_thread(LOCK_CUSTOM1); + for(lar=re->lampren.first; lar; lar=lar->next) { + if(lar->shb && !lar->thread_assigned) { + lar->thread_assigned= 1; + break; + } + } + BLI_unlock_thread(LOCK_CUSTOM1); + + /* if type is irregular, this only sets the perspective matrix and autoclips */ + if(lar) { + makeshadowbuf(re, lar); + BLI_lock_thread(LOCK_CUSTOM1); + lar->thread_ready= 1; + BLI_unlock_thread(LOCK_CUSTOM1); + } + } while(lar && !re->test_break()); + + return NULL; +} + +static volatile int g_break= 0; +static int thread_break(void) +{ + return g_break; +} + +void threaded_makeshadowbufs(Render *re) +{ + ListBase threads; + LampRen *lar; + int a, totthread= 0; + int (*test_break)(void); + + /* count number of threads to use */ + if(G.rendering) { + for(lar=re->lampren.first; lar; lar= lar->next) + if(lar->shb) + totthread++; + + totthread= MIN2(totthread, re->r.threads); + } + else + totthread= 1; /* preview render */ + + if(totthread <= 1) { + for(lar=re->lampren.first; lar; lar= lar->next) { + if(re->test_break()) break; + if(lar->shb) { + /* if type is irregular, this only sets the perspective matrix and autoclips */ + makeshadowbuf(re, lar); + } + } + } + else { + /* swap test break function */ + test_break= re->test_break; + re->test_break= thread_break; + + for(lar=re->lampren.first; lar; lar= lar->next) { + lar->thread_assigned= 0; + lar->thread_ready= 0; + } + + BLI_init_threads(&threads, do_shadow_thread, totthread); + + for(a=0; a<totthread; a++) + BLI_insert_thread(&threads, re); + + /* keep rendering as long as there are shadow buffers not ready */ + do { + if((g_break=test_break())) + break; + + PIL_sleep_ms(50); + + BLI_lock_thread(LOCK_CUSTOM1); + for(lar=re->lampren.first; lar; lar= lar->next) + if(lar->shb && !lar->thread_ready) + break; + BLI_unlock_thread(LOCK_CUSTOM1); + } while(lar); + + BLI_end_threads(&threads); + + /* unset threadsafety */ + re->test_break= test_break; + g_break= 0; + } +} + void freeshadowbuf(LampRen *lar) { if(lar->shb) { @@ -1413,7 +1514,7 @@ static void isb_bsp_fillfaces(Render *re, LampRen *lar, ISBBranch *root) if(lar->mode & LA_LAYER) lay= lar->lay; /* (ab)use zspan, since we use zbuffer clipping code */ - zbuf_alloc_span(&zspan, size, size); + zbuf_alloc_span(&zspan, size, size, re->clipcrop); zspan.zmulx= ((float)size)/2.0f; zspan.zmuly= ((float)size)/2.0f; diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c index bbc2b62536f..cadde9530ed 100644 --- a/source/blender/render/intern/source/strand.c +++ b/source/blender/render/intern/source/strand.c @@ -965,7 +965,7 @@ unsigned short *zbuffer_strands_shade(Render *re, RenderPart *pa, RenderLayer *r spart.ssamp2.tot= 1; spart.ssamp.tot= 1; - zbuf_alloc_span(&zspan, pa->rectx, pa->recty); + zbuf_alloc_span(&zspan, pa->rectx, pa->recty, re->clipcrop); /* needed for transform from hoco to zbuffer co */ zspan.zmulx= ((float)re->winx)/2.0; diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index 9e9a407472c..57d2bbb3489 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -84,7 +84,7 @@ extern struct Render R; /* ****************** Spans ******************************* */ /* each zbuffer has coordinates transformed to local rect coordinates, so we can simply clip */ -void zbuf_alloc_span(ZSpan *zspan, int rectx, int recty) +void zbuf_alloc_span(ZSpan *zspan, int rectx, int recty, float clipcrop) { memset(zspan, 0, sizeof(ZSpan)); @@ -93,6 +93,8 @@ void zbuf_alloc_span(ZSpan *zspan, int rectx, int recty) zspan->span1= MEM_mallocN(recty*sizeof(float), "zspan"); zspan->span2= MEM_mallocN(recty*sizeof(float), "zspan"); + + zspan->clipcrop= clipcrop; } void zbuf_free_span(ZSpan *zspan) @@ -1550,7 +1552,7 @@ void zspan_scanconvert(ZSpan *zspan, void *handle, float *v1, float *v2, float * * @param a index for coordinate (x, y, or z) */ -static void clippyra(float *labda, float *v1, float *v2, int *b2, int *b3, int a) +static void clippyra(float *labda, float *v1, float *v2, int *b2, int *b3, int a, float clipcrop) { float da,dw,u1=0.0,u2=1.0; float v13; @@ -1566,9 +1568,8 @@ static void clippyra(float *labda, float *v1, float *v2, int *b2, int *b3, int a v13= v1[3]; } else { - /* XXXXX EVIL! this is a R global, whilst this function can be called for shadow, before R was set */ - dw= R.clipcrop*(v2[3]-v1[3]); - v13= R.clipcrop*v1[3]; + dw= clipcrop*(v2[3]-v1[3]); + v13= clipcrop*v1[3]; } /* according the original article by Liang&Barsky, for clipping of * homogenous coordinates with viewplane, the value of "0" is used instead of "-w" . @@ -1826,9 +1827,9 @@ void zbufclip(ZSpan *zspan, int obi, int zvlnr, float *f1, float *f2, float *f3, else if (b==1) arg= 0; else arg= 1; - clippyra(labda[0], vlzp[v][0],vlzp[v][1], &b2,&b3, arg); - clippyra(labda[1], vlzp[v][1],vlzp[v][2], &b2,&b3, arg); - clippyra(labda[2], vlzp[v][2],vlzp[v][0], &b2,&b3, arg); + clippyra(labda[0], vlzp[v][0],vlzp[v][1], &b2,&b3, arg, zspan->clipcrop); + clippyra(labda[1], vlzp[v][1],vlzp[v][2], &b2,&b3, arg, zspan->clipcrop); + clippyra(labda[2], vlzp[v][2],vlzp[v][0], &b2,&b3, arg, zspan->clipcrop); if(b2==0 && b3==1) { /* completely 'in', but we copy because of last for() loop in this section */; @@ -1944,7 +1945,7 @@ void zbuffer_solid(RenderPart *pa, unsigned int lay, short layflag, void(*fillfu zspan= &zspans[zsample]; zbuffer_part_bounds(&R, pa, bounds); - zbuf_alloc_span(zspan, pa->rectx, pa->recty); + zbuf_alloc_span(zspan, pa->rectx, pa->recty, R.clipcrop); /* needed for transform from hoco to zbuffer co */ zspan->zmulx= ((float)R.winx)/2.0; @@ -2142,10 +2143,8 @@ void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem, Re /* needed for projectvert */ MTC_Mat4MulMat4(winmat, vw->viewmat, vw->winmat); - /* for clipping... bad stuff actually */ - R.clipcrop= 1.0f; - - zbuf_alloc_span(&zspan, vw->rectx, vw->recty); + /* 1.0f for clipping in clippyra()... bad stuff actually */ + zbuf_alloc_span(&zspan, vw->rectx, vw->recty, 1.0f); zspan.zmulx= ((float)vw->rectx)/2.0; zspan.zmuly= ((float)vw->recty)/2.0; zspan.zofsx= -0.5f; @@ -2249,7 +2248,8 @@ void zbuffer_shadow(Render *re, float winmat[][4], LampRen *lar, int *rectz, int if(lar->mode & LA_LAYER) lay= lar->lay; - zbuf_alloc_span(&zspan, size, size); + /* 1.0f for clipping in clippyra()... bad stuff actually */ + zbuf_alloc_span(&zspan, size, size, 1.0f); zspan.zmulx= ((float)size)/2.0; zspan.zmuly= ((float)size)/2.0; zspan.zofsx= jitx; @@ -2315,6 +2315,9 @@ void zbuffer_shadow(Render *re, float winmat[][4], LampRen *lar, int *rectz, int zbufclip(&zspan, 0, 0, ho1, ho2, ho3, c1, c2, c3); } } + + if((a & 255)==255 && re->test_break()) + break; } /* strands */ @@ -2345,16 +2348,22 @@ void zbuffer_shadow(Render *re, float winmat[][4], LampRen *lar, int *rectz, int sseg.v[2]= svert+1; sseg.v[3]= (b < strand->totvert-2)? svert+2: svert+1; - c1= zbuf_shadow_project(cache, strand->vert-sseg.v[0], obwinmat, sseg.v[0]->co, ho1); - c2= zbuf_shadow_project(cache, strand->vert-sseg.v[1], obwinmat, sseg.v[1]->co, ho2); - c3= zbuf_shadow_project(cache, strand->vert-sseg.v[2], obwinmat, sseg.v[2]->co, ho3); - c4= zbuf_shadow_project(cache, strand->vert-sseg.v[3], obwinmat, sseg.v[3]->co, ho4); + c1= zbuf_shadow_project(cache, sseg.v[0]-strand->vert, obwinmat, sseg.v[0]->co, ho1); + c2= zbuf_shadow_project(cache, sseg.v[1]-strand->vert, obwinmat, sseg.v[1]->co, ho2); + c3= zbuf_shadow_project(cache, sseg.v[2]-strand->vert, obwinmat, sseg.v[2]->co, ho3); + c4= zbuf_shadow_project(cache, sseg.v[3]-strand->vert, obwinmat, sseg.v[3]->co, ho4); if(!(c1 & c2 & c3 & c4)) render_strand_segment(NULL, winmat, NULL, &zspan, &sseg); } } + + if((a & 255)==255 && re->test_break()) + break; } + + if(re->test_break()) + break; } /* merge buffers */ @@ -2455,7 +2464,7 @@ void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(vo short nofill=0, env=0, wire=0; zbuffer_part_bounds(&R, pa, bounds); - zbuf_alloc_span(&zspan, pa->rectx, pa->recty); + zbuf_alloc_span(&zspan, pa->rectx, pa->recty, R.clipcrop); zspan.sss_handle= handle; zspan.sss_func= func; @@ -2766,7 +2775,7 @@ void RE_zbuf_accumulate_vecblur(NodeBlurData *nbd, int xsize, int ysize, float * static int firsttime= 1; char *rectmove, *dm; - zbuf_alloc_span(&zspan, xsize, ysize); + zbuf_alloc_span(&zspan, xsize, ysize, 1.0f); zspan.zmulx= ((float)xsize)/2.0; zspan.zmuly= ((float)ysize)/2.0; zspan.zofsx= 0.0f; @@ -3096,7 +3105,7 @@ static int zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, un for(zsample=0; zsample<samples; zsample++) { zspan= &zspans[zsample]; - zbuf_alloc_span(zspan, pa->rectx, pa->recty); + zbuf_alloc_span(zspan, pa->rectx, pa->recty, R.clipcrop); /* needed for transform from hoco to zbuffer co */ zspan->zmulx= ((float)R.winx)/2.0; |