From 93044b469b3ba6ef3d3adc49bfa719d582c7b19b Mon Sep 17 00:00:00 2001 From: Raph Levien Date: Fri, 15 May 2020 20:09:39 -0700 Subject: [PATCH] Fix prefix sum First, add decoupled lookback. Second, fix problem with monoid that was overly aggressive in resetting the bbox. --- piet-gpu/bin/cli.rs | 2 +- piet-gpu/shader/elements.comp | 94 +++++++++++++++++++++++++++++----- piet-gpu/shader/elements.spv | Bin 35448 -> 43616 bytes piet-gpu/src/lib.rs | 3 +- 4 files changed, 84 insertions(+), 15 deletions(-) diff --git a/piet-gpu/bin/cli.rs b/piet-gpu/bin/cli.rs index 672b42d..f37f0cd 100644 --- a/piet-gpu/bin/cli.rs +++ b/piet-gpu/bin/cli.rs @@ -70,7 +70,7 @@ fn main() -> Result<(), Error> { piet_gpu::dump_k1_data(&data); let mut data: Vec = Default::default(); - device.read_buffer(&renderer.ptcl_buf, &mut data).unwrap(); + device.read_buffer(&renderer.anno_buf, &mut data).unwrap(); piet_gpu::dump_k1_data(&data); */ diff --git a/piet-gpu/shader/elements.comp b/piet-gpu/shader/elements.comp index 94084c8..76d56b6 100644 --- a/piet-gpu/shader/elements.comp +++ b/piet-gpu/shader/elements.comp @@ -18,10 +18,10 @@ layout(set = 0, binding = 0) readonly buffer SceneBuf { uint[] scene; }; -// This will be used for inter-workgroup aggregates. In the -// meantime, for development, it has been used to store the -// scan of the state objects. -layout(set = 0, binding = 1) buffer StateBuf { +// It would be better to use the Vulkan memory model than +// "volatile" but shooting for compatibility here rather +// than doing things right. +layout(set = 0, binding = 1) volatile buffer StateBuf { uint[] state; }; @@ -34,8 +34,28 @@ layout(set = 0, binding = 2) buffer AnnotatedBuf { #include "state.h" #include "annotated.h" +#define StateBuf_stride (4 + 2 * State_size) + +StateRef state_aggregate_ref(uint partition_ix) { + return StateRef(8 + partition_ix * StateBuf_stride); +} + +StateRef state_prefix_ref(uint partition_ix) { + return StateRef(8 + partition_ix * StateBuf_stride + State_size); +} + +uint state_flag_index(uint partition_ix) { + return 1 + partition_ix * (StateBuf_stride / 4); +} + +// These correspond to X, A, P respectively in the prefix sum paper. +#define FLAG_NOT_READY 0 +#define FLAG_AGGREGATE_READY 1 +#define FLAG_PREFIX_READY 2 + #define FLAG_SET_LINEWIDTH 1 -#define FLAG_RESET_BBOX 2 +#define FLAG_SET_BBOX 2 +#define FLAG_RESET_BBOX 4 // This is almost like a monoid (the interaction between transformation and // bounding boxes is approximate) @@ -47,7 +67,9 @@ State combine_state(State a, State b) { c.bbox.w = max(a.mat.y * b.bbox.x, a.mat.y * b.bbox.z) + max(a.mat.w * b.bbox.y, a.mat.w * b.bbox.w) + a.translate.y; if ((a.flags & FLAG_RESET_BBOX) == 0 && b.bbox.z <= b.bbox.x && b.bbox.w <= b.bbox.y) { c.bbox = a.bbox; - } else if ((a.flags & FLAG_RESET_BBOX) == 0 && (a.bbox.z > a.bbox.x || a.bbox.w > a.bbox.y)) { + } else if ((a.flags & FLAG_RESET_BBOX) == 0 && (b.flags & FLAG_SET_BBOX) == 0 && + (a.bbox.z > a.bbox.x || a.bbox.w > a.bbox.y)) + { c.bbox.xy = min(a.bbox.xy, c.bbox.xy); c.bbox.zw = max(a.bbox.zw, c.bbox.zw); } @@ -59,7 +81,7 @@ State combine_state(State a, State b) { c.translate.x = a.mat.x * b.translate.x + a.mat.z * b.translate.y + a.translate.x; c.translate.y = a.mat.y * b.translate.x + a.mat.w * b.translate.y + a.translate.y; c.linewidth = (b.flags & FLAG_SET_LINEWIDTH) == 0 ? a.linewidth : b.linewidth; - c.flags = a.flags | b.flags; + c.flags = (a.flags & (FLAG_SET_LINEWIDTH | FLAG_SET_BBOX)) | b.flags; return c; } @@ -122,10 +144,18 @@ shared vec4 sh_bbox[WG_SIZE]; shared float sh_width[WG_SIZE]; shared uint sh_flags[WG_SIZE]; +shared uint sh_tile_ix; +shared State sh_prefix; + void main() { State th_state[N_ROWS]; - // this becomes an atomic counter - uint tile_ix = gl_WorkGroupID.x; + // Determine partition to process by atomic counter (described in Section + // 4.4 of prefix sum paper). + if (gl_LocalInvocationID.x == 0) { + sh_tile_ix = atomicAdd(state[0], 1); + } + barrier(); + uint tile_ix = sh_tile_ix; uint ix = tile_ix * TILE_SIZE + gl_LocalInvocationID.x * N_ROWS; ElementRef ref = ElementRef(ix * Element_size); @@ -162,16 +192,54 @@ void main() { sh_flags[gl_LocalInvocationID.x] = agg.flags; } - // TODO: if last invocation in wg, publish agg. - - barrier(); State exclusive; exclusive.bbox = vec4(0.0, 0.0, 0.0, 0.0); exclusive.mat = vec4(1.0, 0.0, 0.0, 1.0); exclusive.translate = vec2(0.0, 0.0); exclusive.linewidth = 1.0; //TODO should be 0.0 exclusive.flags = 0; - // TODO: do decoupled look-back + + // Publish aggregate for this partition + if (gl_LocalInvocationID.x == WG_SIZE - 1) { + // Note: with memory model, we'd want to generate the atomic store version of this. + State_write(state_aggregate_ref(tile_ix), agg); + uint flag = FLAG_AGGREGATE_READY; + memoryBarrierBuffer(); + if (tile_ix == 0) { + State_write(state_prefix_ref(tile_ix), agg); + flag = FLAG_PREFIX_READY; + } + state[state_flag_index(tile_ix)] = flag; + if (tile_ix != 0) { + // step 4 of paper: decoupled lookback + uint look_back_ix = tile_ix - 1; + while (true) { + flag = state[state_flag_index(look_back_ix)]; + if (flag == FLAG_PREFIX_READY) { + State their_prefix = State_read(state_prefix_ref(look_back_ix)); + exclusive = combine_state(their_prefix, exclusive); + break; + } else if (flag == FLAG_AGGREGATE_READY) { + State their_agg = State_read(state_aggregate_ref(look_back_ix)); + exclusive = combine_state(their_agg, exclusive); + look_back_ix--; + } + // else spin + } + + // step 5 of paper: compute inclusive prefix + State inclusive_prefix = combine_state(exclusive, agg); + sh_prefix = exclusive; + State_write(state_prefix_ref(tile_ix), inclusive_prefix); + memoryBarrierBuffer(); + flag = FLAG_PREFIX_READY; + state[state_flag_index(tile_ix)] = flag; + } + } + barrier(); + if (tile_ix != 0) { + exclusive = sh_prefix; + } State row = exclusive; if (gl_LocalInvocationID.x > 0) { diff --git a/piet-gpu/shader/elements.spv b/piet-gpu/shader/elements.spv index f8581291afe66b3857e17afb0579e5de40d76d18..a19b5f82bbdd333d0d9161ab31e49d2ab49648f2 100644 GIT binary patch literal 43616 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¬OSg#+9{x3fHf!^)oc})cQGC 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 T+VlU{u|8Pc`MHL2*YJM;Sds-H literal 35448 zcma)^1%O?}*@h3<-QW(vA;Fyj!8KTr;I7M(Y#%=^8c&YYRK=iJ?-t=}S3SJhP2H2n8YN7cAyt@^=K)$~>W zMn81e_QRH+*fV1J!K-{vgPE$fhMhJuS5sHIwbRCQjT)~Vs}pkGeb4w6uZt*V@Gr! zvgE{`36qBREH}k@xk)RoxYnc<*TTMyd8w)i1T^Oi;D!&qIcKIHM(x{o@7tSG&TC4} z_G)(I+O9E6%3kA{VP{R*xf;Ksai^~afNT5C3Ef>IQsR_cjS{hKtLDVESzkvrH+b7g zT_ehR87%4LnpsWJAh-0>?n@B5>YVF&qMX+zy z-CivY-elD1(U?$6M?;1xYHqKVtZn4`^PjTUgnjqv>Ks09^tcJeovvC2&RBhFsDqdJ zm)5tj?mDXFz}xps7O)n0C7XI$h|BwH$!hhSszp-8ZO902cP2s;|;on?j|91fWcPRXKE&RW=cmBip zcj@(?x!SYv|BvhJKg8LiH_l8|R}rW8ZvWpyVa>Evd-ulZUkwKj89R2|l(W3KFXX+- zb?TZcY#ZxT&MW7jvg_2(4)>R`=itP~dEr_ZQ03xJ`Y~POJG-0D_{sLIQ`>uTIkwGpHdA#Cc;D`x#ydu1U&Zsk z)NwU_6C3XgZPgv%QJgxy1KbOq&~f@%|8~3kGxi{{o zO}UQSUVYJ&2h%n3x=^TVm8RTQO^uwq3xJb%P}8nA@8V6lH}5h{xi|0knsRU6Rhn{d z-Zh(YowvPOuPHYk6`k{qoAPR@YZ!9s8U;>WW14n#U2WCG!tT(*?#LFq;|se}3%fI0 z?9MOjE-&n^?qk@=i`>9+&dq4Hs#*=xUVVq&d0+|x%WOif!rK#d-XneeAk4o zG4(zBs73yBi~L!O{7sA8pF^OGH&Y+Et(pzFIluj@xxl^We(!p3^4^=Sd?qw%YpdqL z-plpBZf~5ns~XuxDVi_V((7KDO=EKadaPIXe1JTJ$qMDD5m*6O2cuXa^8iZ4vKAsw7Fe)qEP=+2$TO*mlagmII`Z?;i$oO{DJ@7Xks z?`E(WHg0&==*`9+MAtKF+*mD}wxh6Zo|PTdIB?H?&EveOZ?DF~m9_UE`>bc}NB7aS zSI4%7y(#Ar z3Z|oapvmRq3#P4l46Zqjw(1peeZId59@n#9_k?DV$TdWVcfwDJOG^7^McFRDtoYiozxA5j$cr>secBovM^eMz=Z=MYb?uGkkU@n!fb(%m z{Eo&Mueyxqxu1BR>18}+E&#LkmsP6Glp@!r-|$QSd-j>)Zu)_ zH~!A4ytexLU26OXg7ueM5OxrK>7N+RrMiJMV=PXe7)yYSA*XK1T4(J`ft9sU=l7BE zTOO>RoI1aURHvU0XUf{B8%!TRA9(bWQ|AMq^QWH=f6CgZTZ=w^YlHQZbKcjX*UvrU zy!+jrT*kZ}SWZ7)}(jw$la;3W%rcd)fb-w8Iq zvSS%epRtSpI~F5ZqKI^#{EPrQS`+RIrZk21aSn(M#4;^VYoqt2Lz(i>A>b;k6&g~U7>Y)m=t z!7=pO%j+TTrcdT{8@^Ys?J>ru}9%03&(t;(9QCsgBdP5cuEb;H)@8s9CwfBGu# zUC5q$z9&ZSz4l!(vU=YWBkSK&$m)GpEcL!CMpl19A$zX+t{Aq^=8x>EL?F0%Os6teMsw~Jocce_&d-7d2Jg9}-E-|wPV_8qU3 z*Dqw}%Xhr!l{YSAR+6Sk80!m^#*e$i`D=ZuhcWa_=R5h%2Aj`kxs2f)WO@BP%ayfvFI`9*K`Yn&MK!OD&uteY>*ty>rq2nN zAj@lWDg9-%3uyY9M_HTXxeDBx=V~~4Z9I3b0h`CMn#bpfYmw!(@i}8M?Mj-y=26xr zd2Rr==D870UK_`A6WBby7i2s)Bg<>!cy6IxPt(^t%GxB)9pKhHcf!eQnkF+9c*Lz=>&{@6)cQ$*0Z_YCd)T64{vUKVvFulbHVlPE7a6hcx$yyf*HmU)8)Z z-D|%_Hl};cn9ABD=5N4>>3;Z#=6;Zm&2MYonC`3JAsf?uWlUvlwD-*aL# z@Y=X0r$WA+USIPlYm+?vz^!@O;N-P&eYJzlQ=Z!$aPr!?PWyvhr}~;lSsT~MQ}CWw z_RhQK-qh$GL(cQVG{|zYbyRYJK*g^26}iXS39L=f?L&Wqn<{vw~ai!EA8y zw`1ey!t7ubNy}H5lu0eIHfL(9)K7*}BzdFrJ{Tj92KI2*wY>YgE ztp%3LyP5K;G-DZC9N%@o`et0~fiq^m8&P(?e7_t59><*O6Z;L+(;Ub8^vaos4Z+TX zanxz!_b>AL`@XgbcoZ?!Z46dUZJUCvP2Es>Wn=5N8QAwcebi~Q5xso;w*c>Lz2x$I z9ENPXoR3?AwUN&|`qp6it!TcZ`*V_Q!1CtUT%MNtw+EY7-FEcKzGs?m2k^%9^6Iyx zmrFf6g5^AWcBA+Dl9egHD~)Ae?L^NIs-5ZiQ|-e4yoc(IV|_mYTbDUrrdPHGzl(eY zd>p;J>&HC$8#iOv6Pz*l{gbl(v*WiHcr$u=*n8@kWIWHUE@b(wxl^7w z`+((aUe+~)8FF6_hcl-B?g3-C|3|>7JBvDu(G50^d~%Njx8~j#PCmK!1IyW*PmcZG z+@s)J%g1jVSYP@0jR$wq za;__Dr`~h_Kyd3gC&0;PoD;!vHm`Dyd*B?Wb(M2G2~J(cc@Wq*^2vQLxHb17aPrB0 zC|J(cI>(2>C3iW;hr_E&?jyj)kF>$(a7@gI|i(;eEg0DJIDID zj+M3ZK6%z34>qp4Sv%voCr<`vPo4x;R@aU0RItA0 zI)z@@bIp5p8u(;-ebkkE)-%8uo_}Y7H=-HiOnPPO^=EWvgLkBtSAPb*oVEM8cP>~i zd)Bk+JY@OUoDV*ywlRjXHkq%Bz?rWL!OEGhi^10rQ(oT-=;e&j(SKNRspR@4B+NSj^ya`@i>~1dX{JFAo z;vC!pukJ*0D&Gp$S3bVCfvv+F<$k;!PF?KoDD0jua@+~8E;;T3>nneJo%e3Axz)|U zy0(^kz|QYNH1+Yn7wkN!&s^OHb}qBGl(lo5?yU#F*<1I6mDTw>5D$U%b=^HkubjR0 zF!&5?^ifyttzD3f;of=-yb;Y9kJ2lq)R&xwoD|mXFQT z;3sMuV<>B*-u>|m*n3p&k7tqPWAhx?7+G)1+GLJ?0L~me4^~#^@1DE}*4NxG&?{$- zUIL$sjXvtiIohq3SEu(G!rqvkAFqK2)ADTf6R=$BQzvJw zOy}kAgRMq={tU_AV-q{SGtl&%i9YjrJy@G^&Tl}LPklFn_04nM&0x8kXsP)Yuzu?D z^O;-0^52kCoLYT08bI@!gJylR(9cP;zPaf0Gu}JEjxF-NE%M_n^0O`SONH#u3}36| zjQ>t#^Oobk3t9dd=GFUi4^1w6%9`XdKM#TBG8f+m%RNl6EPlFTpDR6wB0jo2vbEF*IbKo-W50K@arzP$S;KWrQ-xtB^ zjO$!0NB2W;8TUuXa-Oq^`wBR5)yMb8V0Fgzo+(H76R>mRcfzyMzfO~j{td8WjQ&lq z+&0|5+34S*=_Bubf1Catnrp%PVNPZ367#2E$CsEt1ItDKbFg(r{~lN_Ie!7xM?N{< z2b(kdT3I_|x+gxMsdvAKvtRt(qy=bR^U>Td^U%*vbH6M|pZ)P6xZE!vwa6d0$bW5- zKW&k}Xp#LOO8my}PStYu)330%F6T9K^=q(v_S0{`a(C05dux`9{cpi?*-yU%%a!}- z_sCgC>f`$dusY*9cID{)2rlFP30bb(Pk%;ET=nt&3s{|TokQj5{su1N{vBDa+)w{N zPF(fz{RFJexZVrp=sp9NaX&|vEBDhskrP*aeE$VjXI$^8a&%vU%eY@7%Y8-5KK%xq zxa#BkZ?HP!x;B)fn~Jqi#%)8E>qkr6c5vdVk8cN9opD`b%F#^&_FiVMO^YlS{d8dO zN%Yer%VjUl0M$S-K-Mi@h{Y?MvopR2k1(B`Wd!4yl2u?m{(m=3W=E*V1#eQM1T+XCLz;fl8v?y}c zw)*%k23F@fb8eKQTLN6hT@qQYJd>6}PF(fzT^g*;xX!V1bjyOvxXU5Sm1olO$cd{y zzAJ#$8P|KI9NmiGGVV&qa^;z{GIHXokMCfxI^%lJm7`k~T*h4uS*|>jR!2@;_3>Q; ztj@Tu9p&iO0+(^uMwaVG%bBzeIC0g-cU>{fxURv5%)aT*I$9sOjJpA{+z?y+%(o#p zan&d8MqqWubuBALw+Xn6yD75VP+H<{22Nb{@!cG(&baOg<>K5do5?EvUZ8NJ=pb=m^*;wqTdnhI*5KJuv~KP4Aw_JId=h@ zGiRu>c8R$w*fo%tyMg7R-yQ6|jD8QWTypLS)<-@$_X3+UXM?hKiMcn}`i0)BPI-%*9x+T+Y#PV7c-f z9gm##tvP6Ath)~2#H+B-)F)q3YoocUV;-AXjC@6nvU<>^b97RzcmBkgzg5w#LGxOz(KwUoSEo6D zYtm=_PQ|aBzcUN@Jn;FooSIHUHcmNzr^Cr-{>}i)W&X?|mvNp2mdpH|4VEkC?;PaJ zpZfTo3s&d+S*vn%7l7rm$1eoSS^Guw7t&KCK;7Wv^qejNNnE$9ARfoxsn{kalOKKJJ; zuw3qsHOplluK~;D{#*-|EAP*B$hkl2<2xCw&imuom7}`>T*kc-S+0D}x(PXP)yMZ{ zusY*9hsx323NGW`hAdY;XWfpRxa#A32UwkPy%);S-32b=-i<6*K4;y7oVe=adoNg> zalNO?(cKR&<34~aS3YMwh@80U{Yy0WK=!n<_KE#Nu=AAIFN5Wx{}I^nM*j*}F3$x&2J0hl&bQfHuY%3_F4*}} z*3Ouo6|dEL&k=FX5uaH%rg?2h^BkFmej}Ra$R_mJ$8X>#U+&{K;pDTA-vZ0Ik8^+D zM$Y|JpK-neR%cD()Z}+wo6)?6(o)l=U~Af(-m`5M`uFkkY)g$lL)NaW@#k>zIXm71 z%el7wPI_kgUm(jncg9rq=M&cQ0eAqtytOK)R^OGkqNBEVs zeu%7HS?jOhq6N730dA+jj3#{gV6m2yl9=vT9s3)&k{S* zytb#M)*Zmsx)Z&%`V96Ner2tHN7k;a^&fEZsr3`ETxwko`%jVOt<{*y)@m)EgMI#! zw^rrU>T~0+G_Rd$sdX2yweCi5txM2-2E) zsdWahTxwkl`x%ktt<{*y)@m&?gNM+|TdQ(v1vdVzLb}G^X}8u9;QeUgk@TZz)_nlI zb^Gq*zfn}yJv*{KW!-bY$>)rn6D;Q$Yn{fB%egu)ST5t74=ndE_MXWXu^#3}wjT4y z>pLs`0`Thm?D4ZUrxK^UmaZLUjtdLA9<61P2}V+$G;Z5y5wIQESLQ2 zfRo?2=9km1{JA$`lYy6uK?!htO18L%M^b=_A#~%9ZNB^y_azCzztWUWg*N2nO zejEap%YHP5T;^i~uw3@zhG048JJ9E~i~`4V9-Q*QQ{( za_?=1Y_8U|zd5|R%>5Q%x#S-PPJZK>UrxK^-%_5I{9A$L%DuNWa`Kn=ej9jo$-gaF zF8Q|uC%9h7biBqoqy^-}P*JKx*eAfOxV7aV)W5{JbhJ)oYA0xnW<=XE?ww^N2NI3b7 zeP3|KZVbmRr(JUG2QG7sLY6Dn{{G13YF+yWz^lvLj|R&n{}^!c8`u1D+9m&3aG8G` zvRt|L$0H|yx%Ll)SC{+~z;eky5uE(SHNTv8$=?Gm^G`ySE7$%($jM)>{e$7vCI2B{ zx#T|-oczW$znpf-e;ByTe>k#Sx%Q7hPX2Q39|^B6`Huq2CI8Xj}ELYZjCUWXlZ{2duz1jRZ!db|zvCoE+ z&-rl zayCp$%o~wgW8VZPpZU8PESLEkjo&TE^2W4&W#?}!y4%5yQ=MZ`&ivg0o`_B#b>;k> z4}S^G>q46IcLDuH1-=;U{9Q`#{Hec_IGI16^Y3qK%AOy}ccC|i^XHk7Gw^PBb+Nk# zY<%aiw7VBxU4Ga2KCr&>@x34XT{#|rR~Nen!O8J_QOiT{>XPGOu)gv$Fgnld?}Hgm zt%R#vHKA?V=n7>1zugo{9~}b^6`BY{9QR-gI5>3pMaC2yvMJ@ zt4oeI!1~H(Uf%>~Uadi!#C;2#{N??68(v-P-T^0nIT!E3t4sc$g7uY;@6W*BmE-5| z>SFgEI62B%egUs8Io=2BE1xlb0L~b#L7UwFUxJ+jZIbJMz}Dp2DaZ36yt?@Q3ar0; ze18qj+R@jwBd2X_egn>!%Qf*4yt>%^7MwAccE5vHmofhytgn20{{a5393R80i`^f= z$x*JIKf$X@jz5F-mCwBX1?;@~J*zcnlem8cCx03DZ}943_jhpemvj9Ocy-DD30PnG z_l4boD-ZeT7x#Z{{z6zfi}rC7dUID z9M9bF>f$>OSbzEW&I``ku};^HoVG*wob;J)0kHAQe-mOsIQbW_>5pz9u$=evRyhA1 zgMl=8*U{(1T^Q`;zhj_o5KYeKFL7#G1f01m*TSDK8VOOrz#o^UGR@bovSYLVn zo=KrwONWLXU*c&vJ5yim-l;Fcy+N`uCOcb)$;J_ zQu7L6edVn=Iqg&P_rTWVIJCDOYhH;yHEXjXZB?2zi@mS@jD2OW_tobWpJCUb9}FiS zn^nMBAFd5$ZLG;W#x!=;%4*=&wX!;#eAdbuV7YRwtcfh2wX!zY%XwF~7ER84;>_nd z;EbVME9=6mi`{yKUAb1)hgbJVy;g>R^_9Pw+^&rcX!6eOM)avmenXm^b%~R2V{qy! z*TW|8>S8yvuq)TYrts=g*JfaS<(>QFw9k6j9BiG=kM`E1ZRX8Bwp)OmSMQyE#&LXG z(r0|y45P_8K5^E?R^W^;YiDaX`TYIsZNzmmre|9Gw}sETivMC%toZK^*ILsaaPslr6D((of5y8Poa6PG$voO7b|<(s_TF&v8E+R@&NyDi%DCOv z+G^u^$^Eu3_qqE$>vkWo^D&uL?x*4K>S8wn?77%#*A1^OpMxX8`pU<5UvP4idwV~4 zb+H=-PL6U9?GLXmISv5pD}O9^+;_myU~{WWyfI+sb8nk7MiQwcY&yXH?b+MZSPL8scgW%OA$H8EIB ze&acQIc;Ne7&x_+<2oE(UF?nkr?&DQ9tp25wH*c4S3bT+gOj85JqBJ~?2ZK|M>$W& z!K+J-5@r)_M`1E;p~ z{+|!8E_N4yt?gY}X?G#Ky3}?NSYP@0UJOo-a_%mHR~NfWmFpbky|@fsU2l5` zzXEJ-b%}SS+;`M`6}-CmUJce?KEBt0ox6%k3{H-+mRsP}CC9B`edRO$+rZ{lmw2~>Gk0aYJK)vD z_fD|>^6|Y3oVnB2xodC@o94U7-C*mTpWf#N-#zXD%jfy>Ua*`o@-A{8vb^)?bIyZc zFP|^fJwW?D&F38P5Y7j`>wO69csjx6^E2aNIC<;4pI+I|Nn`47ocKQiw%*eJQ8@Yd zE0_MpNv_Ah=19E9!OoHK^jFqKz3*yIfUUQjpC{quWAhZabq=3~lYgE#&gnB?{p92K zEZE$}Hn*~N*6Mfd&((T=uS=ZY>r!_G&FeDSYWPk=e>u(hx{}`S-mU)y{PNwqHZK;k z-_5^V$gd*5U&z{jP{{q6qkj~#`cDdZ3-mMb5LD)yxscC8zhWWlzfvJTj(*KTR=-v) zJ153{iF}UJ`Eo4E{w|zz{6p}@^z!N*yPWgw``M4dj@S1y^~$dl`k&PL$+cejwOao+ z+#9vtvq*pC*K56N`^{RPwWR!Nt@mEMRqJ!Vm2(bR|J%sc?0)(Mz1NrQ5P4-%RPWHU zWU6=R`BVLr|8>y+jGn1#^v3!*vh(#Gy=y|h%;7J=nM3cdvU4~)_WuLkj9%U`x*p`5 zL+9W_u-s&@@qBmq6|#J6eht>fd5X<%kmd9I{SnylELQug&wctWIQL0^-!Fa#C!go< z--G3h;4!{J~n@>ZOXd;1Sg-m{|vV7C29JrPu+h3x7Phv zIQi85H?W*>yo{Cloo{Wm@%-|hd+)s0xp$v}bMM@H%HF$qiSrqFOL}=@xmV>fzR$sO zld;Kt`6se`Z2kq-rksN>kmWN6UxIV*^j9DMufY1}I}q2$*U0km{{|d?W2w&^{u|sn zhfa`u=5Q(}jAoq7U3u@d)h0Fd1GkR54Ng8b?X^ug?hZKl)ZHJPd#}Ix_)iUP9rrYF z^6{S*9Die}&$y=pw~l*yIQfiw2C$rQyo@Du?R&qq)uvoKo)1|&v!Kh`@myAR?F_qJq^~xhX_vU$f?MNm2PdDn+k@q7#$ZZ%x=e{M%HO@02Y P%$>mUj?Xz%b`Jj+f*SW7 diff --git a/piet-gpu/src/lib.rs b/piet-gpu/src/lib.rs index 0ac8299..bf7a7c7 100644 --- a/piet-gpu/src/lib.rs +++ b/piet-gpu/src/lib.rs @@ -158,7 +158,7 @@ impl Renderer { .unwrap(); device.write_buffer(&scene_buf, &scene)?; - let state_buf = device.create_buffer(64 * 1024 * 1024, dev)?; + let state_buf = device.create_buffer(1 * 1024 * 1024, dev)?; let anno_buf = device.create_buffer(64 * 1024 * 1024, dev)?; let bin_buf = device.create_buffer(64 * 1024 * 1024, dev)?; let ptcl_buf = device.create_buffer(48 * 1024 * 1024, dev)?; @@ -245,6 +245,7 @@ impl Renderer { cmd_buf.copy_buffer(&self.scene_buf, &self.scene_dev); cmd_buf.copy_buffer(&self.bin_alloc_buf_host, &self.bin_alloc_buf_dev); cmd_buf.copy_buffer(&self.coarse_alloc_buf_host, &self.coarse_alloc_buf_dev); + cmd_buf.clear_buffer(&self.state_buf); cmd_buf.memory_barrier(); cmd_buf.image_barrier( &self.image_dev,