Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2007-12-18 00:04:22 +0300
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2007-12-18 00:04:22 +0300
commit25a434fd250a740ef23263af11d0a53a2539007b (patch)
tree3c644b792f82bbf50832f5084853ab9c54b25376
parent5dfef1ae3580aeef8601fca4883bf186be82f29d (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.
-rw-r--r--source/blender/render/intern/include/render_types.h4
-rw-r--r--source/blender/render/intern/include/shadbuf.h2
-rw-r--r--source/blender/render/intern/include/zbuf.h4
-rw-r--r--source/blender/render/intern/source/convertblender.c29
-rw-r--r--source/blender/render/intern/source/pipeline.c2
-rw-r--r--source/blender/render/intern/source/rendercore.c2
-rw-r--r--source/blender/render/intern/source/shadbuf.c109
-rw-r--r--source/blender/render/intern/source/strand.c2
-rw-r--r--source/blender/render/intern/source/zbuf.c51
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;