From 0f91149b49db9751dc64bcff4dc5a35c681bba34 Mon Sep 17 00:00:00 2001 From: Raph Levien Date: Thu, 17 Mar 2022 15:00:08 -0700 Subject: [PATCH] Radial gradients This patch adds radial gradients, including both the piet API and some new methods specifically to support COLRv1, including the ability to transform the gradient separately from the path. --- piet-gpu-types/src/ptcl.rs | 14 +- piet-gpu/shader/coarse.comp | 20 + piet-gpu/shader/draw_leaf.comp | 36 +- piet-gpu/shader/drawtag.h | 5 +- piet-gpu/shader/gen/coarse.dxil | Bin 10544 -> 11628 bytes piet-gpu/shader/gen/coarse.hlsl | 496 +++++++++++++++--------- piet-gpu/shader/gen/coarse.msl | 535 ++++++++++++++++---------- piet-gpu/shader/gen/coarse.spv | Bin 52244 -> 58852 bytes piet-gpu/shader/gen/draw_leaf.dxil | Bin 6072 -> 6764 bytes piet-gpu/shader/gen/draw_leaf.hlsl | 128 +++--- piet-gpu/shader/gen/draw_leaf.msl | 112 ++++-- piet-gpu/shader/gen/draw_leaf.spv | Bin 16412 -> 20104 bytes piet-gpu/shader/gen/draw_reduce.dxil | Bin 4256 -> 4260 bytes piet-gpu/shader/gen/draw_reduce.hlsl | 26 +- piet-gpu/shader/gen/draw_reduce.msl | 18 +- piet-gpu/shader/gen/draw_reduce.spv | Bin 7124 -> 7140 bytes piet-gpu/shader/gen/kernel4.dxil | Bin 14236 -> 15112 bytes piet-gpu/shader/gen/kernel4.hlsl | 288 +++++++++----- piet-gpu/shader/gen/kernel4.msl | 335 ++++++++++------ piet-gpu/shader/gen/kernel4.spv | Bin 58596 -> 65556 bytes piet-gpu/shader/gen/kernel4_gray.dxil | Bin 14140 -> 15016 bytes piet-gpu/shader/gen/kernel4_gray.hlsl | 286 +++++++++----- piet-gpu/shader/gen/kernel4_gray.msl | 333 ++++++++++------ piet-gpu/shader/gen/kernel4_gray.spv | Bin 58352 -> 65312 bytes piet-gpu/shader/kernel4.comp | 19 +- piet-gpu/shader/ptcl.h | 77 +++- piet-gpu/src/encoder.rs | 30 +- piet-gpu/src/gradient.rs | 51 ++- piet-gpu/src/lib.rs | 1 + piet-gpu/src/render_ctx.rs | 25 +- piet-gpu/src/test_scenes.rs | 22 +- 31 files changed, 1886 insertions(+), 971 deletions(-) diff --git a/piet-gpu-types/src/ptcl.rs b/piet-gpu-types/src/ptcl.rs index e8c29c3..14831ca 100644 --- a/piet-gpu-types/src/ptcl.rs +++ b/piet-gpu-types/src/ptcl.rs @@ -24,6 +24,14 @@ piet_gpu! { line_y: f32, line_c: f32, } + struct CmdRadGrad { + index: u32, + mat: [f32; 4], + xlat: [f32; 2], + c1: [f32; 2], + ra: f32, + roff: f32, + } struct CmdImage { index: u32, offset: [i16; 2], @@ -31,6 +39,9 @@ piet_gpu! { struct CmdAlpha { alpha: f32, } + struct CmdEndClip { + blend: u32, + } struct CmdJump { new_ref: u32, } @@ -42,9 +53,10 @@ piet_gpu! { Alpha(CmdAlpha), Color(CmdColor), LinGrad(CmdLinGrad), + RadGrad(CmdRadGrad), Image(CmdImage), BeginClip, - EndClip, + EndClip(CmdEndClip), Jump(CmdJump), } } diff --git a/piet-gpu/shader/coarse.comp b/piet-gpu/shader/coarse.comp index 454371c..3abb2e0 100644 --- a/piet-gpu/shader/coarse.comp +++ b/piet-gpu/shader/coarse.comp @@ -229,6 +229,7 @@ void main() { case Drawtag_FillColor: case Drawtag_FillImage: case Drawtag_FillLinGradient: + case Drawtag_FillRadGradient: case Drawtag_BeginClip: case Drawtag_EndClip: uint drawmonoid_base = drawmonoid_start + 4 * element_ix; @@ -373,6 +374,25 @@ void main() { Cmd_LinGrad_write(cmd_alloc, cmd_ref, cmd_lin); cmd_ref.offset += 4 + CmdLinGrad_size; break; + case Drawtag_FillRadGradient: + if (!alloc_cmd(cmd_alloc, cmd_ref, cmd_limit)) { + break; + } + linewidth = uintBitsToFloat(memory[di]); + write_fill(cmd_alloc, cmd_ref, tile, linewidth); + CmdRadGrad cmd_rad; + cmd_rad.index = scene[dd]; + // Given that this is basically a memcpy, we might consider + // letting the fine raster read the info itself. + cmd_rad.mat = uintBitsToFloat(uvec4(memory[di + 1], memory[di + 2], + memory[di + 3], memory[di + 4])); + cmd_rad.xlat = uintBitsToFloat(uvec2(memory[di + 5], memory[di + 6])); + cmd_rad.c1 = uintBitsToFloat(uvec2(memory[di + 7], memory[di + 8])); + cmd_rad.ra = uintBitsToFloat(memory[di + 9]); + cmd_rad.roff = uintBitsToFloat(memory[di + 10]); + Cmd_RadGrad_write(cmd_alloc, cmd_ref, cmd_rad); + cmd_ref.offset += 4 + CmdRadGrad_size; + break; case Drawtag_FillImage: linewidth = uintBitsToFloat(memory[di]); if (!alloc_cmd(cmd_alloc, cmd_ref, cmd_limit)) { diff --git a/piet-gpu/shader/draw_leaf.comp b/piet-gpu/shader/draw_leaf.comp index 1cee0ef..ef369c9 100644 --- a/piet-gpu/shader/draw_leaf.comp +++ b/piet-gpu/shader/draw_leaf.comp @@ -94,8 +94,8 @@ void main() { // pipeline. However, going forward we'll get rid of that, and have // later stages read scene + bbox etc. tag_word = scene[drawtag_base + ix + i]; - if (tag_word == Drawtag_FillColor || tag_word == Drawtag_FillLinGradient || tag_word == Drawtag_FillImage || - tag_word == Drawtag_BeginClip) { + if (tag_word == Drawtag_FillColor || tag_word == Drawtag_FillLinGradient || tag_word == Drawtag_FillRadGradient || + tag_word == Drawtag_FillImage || tag_word == Drawtag_BeginClip) { uint bbox_offset = (conf.path_bbox_alloc.offset >> 2) + 6 * m.path_ix; float bbox_l = float(memory[bbox_offset]) - 32768.0; float bbox_t = float(memory[bbox_offset + 1]) - 32768.0; @@ -106,11 +106,11 @@ void main() { uint fill_mode = uint(linewidth >= 0.0); vec4 mat; vec2 translate; - if (linewidth >= 0.0 || tag_word == Drawtag_FillLinGradient) { + if (linewidth >= 0.0 || tag_word == Drawtag_FillLinGradient || tag_word == Drawtag_FillRadGradient) { uint trans_ix = memory[bbox_offset + 5]; uint t = (conf.trans_alloc.offset >> 2) + 6 * trans_ix; mat = uintBitsToFloat(uvec4(memory[t], memory[t + 1], memory[t + 2], memory[t + 3])); - if (tag_word == Drawtag_FillLinGradient) { + if (tag_word == Drawtag_FillLinGradient || tag_word == Drawtag_FillRadGradient) { translate = uintBitsToFloat(uvec2(memory[t + 4], memory[t + 5])); } } @@ -125,7 +125,6 @@ void main() { break; case Drawtag_FillLinGradient: memory[di] = floatBitsToUint(linewidth); - uint index = scene[dd]; vec2 p0 = uintBitsToFloat(uvec2(scene[dd + 1], scene[dd + 2])); vec2 p1 = uintBitsToFloat(uvec2(scene[dd + 3], scene[dd + 4])); p0 = mat.xy * p0.x + mat.zw * p0.y + translate; @@ -139,6 +138,33 @@ void main() { memory[di + 2] = floatBitsToUint(line_y); memory[di + 3] = floatBitsToUint(line_c); break; + case Drawtag_FillRadGradient: + p0 = uintBitsToFloat(uvec2(scene[dd + 1], scene[dd + 2])); + p1 = uintBitsToFloat(uvec2(scene[dd + 3], scene[dd + 4])); + float r0 = uintBitsToFloat(scene[dd + 5]); + float r1 = uintBitsToFloat(scene[dd + 6]); + float inv_det = 1.0 / (mat.x * mat.w - mat.y * mat.z); + vec4 inv_mat = inv_det * vec4(mat.w, -mat.y, -mat.z, mat.x); + vec2 inv_tr = inv_mat.xz * translate.x + inv_mat.yw * translate.y; + inv_tr += p0; + vec2 center1 = p1 - p0; + float rr = r1 / (r1 - r0); + float rainv = rr / (r1 * r1 - dot(center1, center1)); + vec2 c1 = center1 * rainv; + float ra = rr * rainv; + float roff = rr - 1.0; + memory[di] = floatBitsToUint(linewidth); + memory[di + 1] = floatBitsToUint(inv_mat.x); + memory[di + 2] = floatBitsToUint(inv_mat.y); + memory[di + 3] = floatBitsToUint(inv_mat.z); + memory[di + 4] = floatBitsToUint(inv_mat.w); + memory[di + 5] = floatBitsToUint(inv_tr.x); + memory[di + 6] = floatBitsToUint(inv_tr.y); + memory[di + 7] = floatBitsToUint(c1.x); + memory[di + 8] = floatBitsToUint(c1.y); + memory[di + 9] = floatBitsToUint(ra); + memory[di + 10] = floatBitsToUint(roff); + break; case Drawtag_BeginClip: break; } diff --git a/piet-gpu/shader/drawtag.h b/piet-gpu/shader/drawtag.h index 7f73546..1e35318 100644 --- a/piet-gpu/shader/drawtag.h +++ b/piet-gpu/shader/drawtag.h @@ -4,11 +4,12 @@ // Design of draw tag: & 0x1c gives scene size in bytes // & 1 gives clip -// (tag >> 4) & 0x1c is info size in bytes +// (tag >> 4) & 0x3c is info size in bytes #define Drawtag_Nop 0 #define Drawtag_FillColor 0x44 #define Drawtag_FillLinGradient 0x114 +#define Drawtag_FillRadGradient 0x2dc #define Drawtag_FillImage 0x48 #define Drawtag_BeginClip 0x05 #define Drawtag_EndClip 0x25 @@ -36,5 +37,5 @@ DrawMonoid combine_draw_monoid(DrawMonoid a, DrawMonoid b) { DrawMonoid map_tag(uint tag_word) { // TODO: at some point, EndClip should not generate a path uint has_path = uint(tag_word != Drawtag_Nop); - return DrawMonoid(has_path, tag_word & 1, tag_word & 0x1c, (tag_word >> 4) & 0x1c); + return DrawMonoid(has_path, tag_word & 1, tag_word & 0x1c, (tag_word >> 4) & 0x3c); } diff --git a/piet-gpu/shader/gen/coarse.dxil b/piet-gpu/shader/gen/coarse.dxil index 12e88dde300ffb33e17ea6c31c7c14b60812b006..fdab4447a616541a0a7e5cdb26669e8801989c34 100644 GIT binary patch delta 7631 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 fOWc+b6DX+JfRKIfR58$QGif~3d7@A|Td5G052 z5Q>4IsN{`t5LiP2%P3%89BKT~n*>4d6@NGkgKvdv*JM}z1^XH7R0-pJSDYO~yU(!g zBer!ym#VMT2~0O1By8X>*NSf@;3$q9j;8k$yTY5WnU_CvX>K~tKQyKg$zUs zB_F)m-`^icQSFKhVmtgwBEh>TZrK_p@)zObSZ#EcMt;0<6vu6y+rA*t3}J$~rUy&Jcy-=?Snn`K(yOo-`GUFe)Y^tqDTxII5ndWsGGIQDZ7Z z({<%y&Wx#84FfULFjL)Q9bSTvCVqw-ViJ)Uzicp6S%wd}6R?`_F<*It0@2H0nF38# zd()X#X{z76`Z0QjZxI?`83j%Ll$REIQSqQ%UE^$@Y=VBqB^F$w6K%^^wrXx7ZIk72=sojekXc;Y;Cig5soT4OsdFJ{4p6PAaW~DR@58GBIuaw!^bA zYh)f{*w%D@$w8u)TrBiLbWe0k(fFXt9bV4K)7x9gdX0p0|m56$g@3=e=glbDw-xjVC zCsoI!Il(d&HB~J!T2~27)GkVA9|#cb64e&uIP9cSjLJqL&V340gI?n7vwO_@2qQb~!4Deb*@O z^q#Tf*KU`W$!pH+HtLXI6`gbrUh>p(Tn{*IH48y3DL9FbpTs@D@+IVlm@K=`)u>Rh zO9V{aWjcdTSL!fAk5ozy?MGPajtOJrk0a^Kd@80biMY20K7n~okdwj~CPrMCIqH2J z-Q1U2?!rtq$=!8MQmAYkS`3nsibyyrr2QhldiG1WfxzI_bSh7>J zRVByg?>9sXVZPSgASa!3M_GC(L|5>IN=YY8db`7TBO`Z46Ih$eF4JMYS5c#|N&HSi zE{+Cm>r|7h0?nw3dJqWAMIS5(MC3(*9FIL*ykSB4D3g(IuhRRd#jq(~%sfL;f zw#;uhVA)b5bkjox{hqqZ`OGB#^oEZ;lr*RwdC^HVV!0HZX2$G<#X%yzc{+dXV;}y} zdj(LkN$2zXxC=;ECJ6*1WRXb*l(V-!7>?;9lrcO&EaBh0bWX)$ysuL)89r2Q^22Vy z_mU$yal7>zS)AfjuE2JeZ%2v7V*c+ogs!9-T65`+N zw&MOc@sKK7?ge;*AFCqEpn;pLZ-sbanqMaQKBP`UQam!xls^zHC#2Xd%cGyd%j7=q zs1MunH=xI>+3D5SAb-mkOiQjItUr&r&A~nv9*R`P*ugT$Cskc+ELJWu(kijfC8yec zOTq{G*b@H8DdJyooFI_!A65~qif*yEdG7Eh7LxM(*O|fwVvUnm>er<@yC@JJfEIgtFL;O`%wG(tpep=D|{l4TO~g&Uq&4)=5#n| zobs_C4Dzvp^_URXz|{~1hg}{Yzs%sYEtiF3Aq0@u#=+a4;C2ROC@geNI<1c>XGJgb zPBu}vxp_+$!-Z<4e{-I-5K9)6#4kWkHGB=M^TWz-QZ*>b;Z~r_m3k=dLMKRuQv;`s z7AXqx#<)rpKb9L7jiq32V8KG_PR#CA_e767BvTj8kNqQfPs z>7-}Rc?)PX+d%ien))6d#5T5T0d%kpjhH=Z>bF2J`AzqNz+@EwsDE`mc0u{D4UKdX zCvqiFs~1M=FbBGl0j4{PrJ53)u7D|5aN9u{3rx?^}j{L1M#|Jea0Z*U`b`WAb5y;nn@r{bxx z4cp|<@{|3jzioY=V?>{0cv<|)d5Qo00B<&$J9~@W8s*jcpXK%cb9t*nM5{x%;)d}7 z<|UfORn!}Qhd&~uMU0vw`pP33j;x#=w5k>?Aqa|;4uTC1g754F@7N1oqJqy*K^Q9d zjv%mX88k;IrpESsX$Zc?molIlciL{LE>h&MekH9#dR=@By~(B>l8%awIoyn(O-Wyg zciUqNVdlPE{!LSXgL8P?4gQ0kS#&cuuAcw9X)j@OMBG35&Ak)$_x%T{1`u6c7p!Dh z2Fxy)VG!AUxM#6st7aTViF6{UriXG@0Q_z*bC4;r$uBYViNAkpC3L}s`e1l^A+7RX zt^q!#5S~(6-l8x`eS_@3a-DkSD&1;mF zics*(RybyUTC>wxbr;lu;hTbYOy3Cc&-T#g9jxS^wQj;WO#RwI{!Se>ML*wtZGO94 zV9^uxZyi1eoA36F;9u;@Al-+4bgxo-6llEq)ZAgUf4^y^tbE-&qCae>dCv-z2c7#Y z$EC@iDSFw(7|;TZnmho-+XIRho-UtL9U+!T|2=&4kHs3Ht`bi=N4y9IMTuVSD3h*B zy*UqhU}iC>xt_x!eulwP4yx>L-hFy~lijb5Z}etAkta!(EZ9I;#uzmD^?Htoq-}x?>D$2ZyLR3?J8Rktp%FOE`GRziLX{18wKXE?8#pT43@?T`m z>-ez>0@f4SLCEwbWF~;2%MahfKipQ6kPrE0n6Xdpk|%fh5TKRt0h6>L?n>mr_2m?q zP@JkInfxM`&cK1AMkEXe@ba;aU{V4bEG9%Wh_42>N*&tFXq)+8RSI#c2nBDQ1=-p@ zai?>;*}YwA-ywZfr4sY4ra5*|3&I|@_P~mA?}&15*9!07 zy5JGFG-5Q#4G^8mz20^1v`UL}JL~Nxt}A_ym}NI7*I^a2&<|L(ql9dnv@+tFdN;Ig zObZxMM|9VqyJ9vhD%i~O462hCC1w}x%P#t{iR7--pbDFC8*8b!PFGaAbn48~(z+B) z7$a9+^r5A!CcMg*_sK1M&0c-t%xp@1=yPwc?lX&BLiq$+JN%C#%UK#14SF!9Wz3tA zOT-1%Zifn`z;qXj>D??(jh9DWeGs=k{Dd#DP>tIEDKxn#^VijGXW$cv155jfTqesi zFxyf99FCfc4{JgO&V)$nL#FC_2tgWj&}Qd-R_NtA`KKpBQ|m+L>T>o1FGQ#7uwzjs z!Msr*PS^E5UzaemZXNS$CJl*zB55*)miK&WKao3uFZNnQl1+SdAua9}XK1OU-36XCyV*fL86rB(w9uR+YSQRMjjfSU;c zH!8!AJHK^@+TJ59^gRmm#xO zf-+ue3V&*i^B?W;AJGh(d*i43;&rk+0VY2akF*y$#T)yCI~EIu$xPQyObl{f{<+8^ z(DEif;ZDZ#27`<}?!;cF&0bFLJ3YhEJ1c8Un?OafZx@onMxtWW;I4lCHrn#oc+Z(l z{yik|ciE=jl~oeozRD#2CaW(`ZT!BHjel9?{BrN6m+cbYe&@2qV1AVNGDHFk9^nMz z&Voyc{=b22>aaypGVaXrd`;W*x@yzwVF?h((>S+xET(p6)j(6Cc($Zrc4OV_?dmDR ziZ-au3YN}l<-?}U=&Rc+UX|3nva893t|A9*JeYdEE|D{{!c;eZyDqc&>_JV6CY3P> zd88P#M7qMWcGcb1J~m^jE{Q{I25qcf-DvGALrzdR@1QX`psk!@aP;zqy;f^ZMl`3O z(wsUe+9)mkjH@i+=yeV4no8TLdnJv#ILXbKjY&C;hnsQ#nctVwn9Gqj=Qk#oHX55x zR03VQgw7E91 z*-D!Or40u*D$iMX6H~51GbAnhIab~@7jCujW@1Z?TT?a4JJrLva>926@a8wGuv^FO zGnZt!9#AjQNRFP=pt%w&zrWjZI-*I{lw8`hzqDzr`P-k)=`^Q?tcB&_`KBSxO!KX# zg9A+y%_nMrt?wy;M_0c$=9xBjdMjhn&>uX8e@;?}w&a6f5b3=c&$OA-TWhz^6oyf9 zUUBqeO*TJvxwU+R_H$eNOI!QVy7SpQ_Ul?+t?&N)6GuPSj3a;O9l`U7Nl@7CG1T(; ziKg!JymoPm!ENzHS#oh-sq*t7ON_Xk96i+5j$YA#UY`P7r=S$sTxa&-9isBCA85HY z)slkQ&CnZSLWqP9$;R{=wZ|=QHf1+YZ)~&LwfbHKPl-OsX?>D&;mK5kBx)4ps(99_ za-@9{ZP0Y*Or5_l#ce$A4eV7ii_{J(cLIG5Pp5)mY;^wa@_S=TW0xp9q|#2Fe(XYf*^nkhyN6H6urm0!k9k$pxtxx<^B3p1=eYg6Hu*(c zP5ACPuNwW6yY|nii+|>vlbCtdn((Yc`Dace#ym$hWBko$n-gE4S$5`htHu$Ge@&2> zcTsF{+Bu6rhoKCL!iz4GzqRFl7Oy>(%V-0+&lb1qF!yY+-t|p;CUA#UJ*tyOu= zfqJ1i1^I}mu_CuWHvQ@W?$zv_AO*DUNn8tPK2m|mFT4%ge>?AQsA&7a4Lk$Kky^AL zysMTXT)%P8`Be%KlKtgHI*(D%z{Fa!f7{9*#VxvP!!6f9vOLbI5iaF3kt<<-q40kL DS^`sz diff --git a/piet-gpu/shader/gen/coarse.hlsl b/piet-gpu/shader/gen/coarse.hlsl index a702df5..04529bb 100644 --- a/piet-gpu/shader/gen/coarse.hlsl +++ b/piet-gpu/shader/gen/coarse.hlsl @@ -91,6 +91,21 @@ struct CmdLinGrad float line_c; }; +struct CmdRadGradRef +{ + uint offset; +}; + +struct CmdRadGrad +{ + uint index; + float4 mat; + float2 xlat; + float2 c1; + float ra; + float roff; +}; + struct CmdImageRef { uint offset; @@ -160,9 +175,9 @@ struct Config static const uint3 gl_WorkGroupSize = uint3(256u, 1u, 1u); -RWByteAddressBuffer _242 : register(u0, space0); -ByteAddressBuffer _854 : register(t1, space0); -ByteAddressBuffer _1222 : register(t2, space0); +RWByteAddressBuffer _260 : register(u0, space0); +ByteAddressBuffer _1005 : register(t1, space0); +ByteAddressBuffer _1372 : register(t2, space0); static uint3 gl_WorkGroupID; static uint3 gl_LocalInvocationID; @@ -185,8 +200,8 @@ groupshared uint sh_tile_count[256]; Alloc slice_mem(Alloc a, uint offset, uint size) { - Alloc _319 = { a.offset + offset }; - return _319; + Alloc _337 = { a.offset + offset }; + return _337; } bool touch_mem(Alloc alloc, uint offset) @@ -202,7 +217,7 @@ uint read_mem(Alloc alloc, uint offset) { return 0u; } - uint v = _242.Load(offset * 4 + 8); + uint v = _260.Load(offset * 4 + 8); return v; } @@ -215,8 +230,8 @@ Alloc new_alloc(uint offset, uint size, bool mem_ok) BinInstanceRef BinInstance_index(BinInstanceRef ref, uint index) { - BinInstanceRef _328 = { ref.offset + (index * 4u) }; - return _328; + BinInstanceRef _346 = { ref.offset + (index * 4u) }; + return _346; } BinInstance BinInstance_read(Alloc a, BinInstanceRef ref) @@ -244,8 +259,8 @@ Path Path_read(Alloc a, PathRef ref) uint raw2 = read_mem(param_4, param_5); Path s; s.bbox = uint4(raw0 & 65535u, raw0 >> uint(16), raw1 & 65535u, raw1 >> uint(16)); - TileRef _391 = { raw2 }; - s.tiles = _391; + TileRef _409 = { raw2 }; + s.tiles = _409; return s; } @@ -255,11 +270,11 @@ void write_tile_alloc(uint el_ix, Alloc a) Alloc read_tile_alloc(uint el_ix, bool mem_ok) { - uint _741; - _242.GetDimensions(_741); - _741 = (_741 - 8) / 4; + uint _892; + _260.GetDimensions(_892); + _892 = (_892 - 8) / 4; uint param = 0u; - uint param_1 = uint(int(_741) * 4); + uint param_1 = uint(int(_892) * 4); bool param_2 = mem_ok; return new_alloc(param, param_1, param_2); } @@ -273,31 +288,31 @@ Tile Tile_read(Alloc a, TileRef ref) Alloc param_2 = a; uint param_3 = ix + 1u; uint raw1 = read_mem(param_2, param_3); - TileSegRef _416 = { raw0 }; + TileSegRef _434 = { raw0 }; Tile s; - s.tile = _416; + s.tile = _434; s.backdrop = int(raw1); return s; } MallocResult malloc(uint size) { - uint _248; - _242.InterlockedAdd(0, size, _248); - uint offset = _248; - uint _255; - _242.GetDimensions(_255); - _255 = (_255 - 8) / 4; + uint _266; + _260.InterlockedAdd(0, size, _266); + uint offset = _266; + uint _273; + _260.GetDimensions(_273); + _273 = (_273 - 8) / 4; MallocResult r; - r.failed = (offset + size) > uint(int(_255) * 4); + r.failed = (offset + size) > uint(int(_273) * 4); uint param = offset; uint param_1 = size; bool param_2 = !r.failed; r.alloc = new_alloc(param, param_1, param_2); if (r.failed) { - uint _277; - _242.InterlockedMax(4, 1u, _277); + uint _295; + _260.InterlockedMax(4, 1u, _295); return r; } return r; @@ -311,7 +326,7 @@ void write_mem(Alloc alloc, uint offset, uint val) { return; } - _242.Store(offset * 4 + 8, val); + _260.Store(offset * 4 + 8, val); } void CmdJump_write(Alloc a, CmdJumpRef ref, CmdJump s) @@ -327,11 +342,11 @@ void Cmd_Jump_write(Alloc a, CmdRef ref, CmdJump s) { Alloc param = a; uint param_1 = ref.offset >> uint(2); - uint param_2 = 10u; + uint param_2 = 11u; write_mem(param, param_1, param_2); - CmdJumpRef _734 = { ref.offset + 4u }; + CmdJumpRef _885 = { ref.offset + 4u }; Alloc param_3 = a; - CmdJumpRef param_4 = _734; + CmdJumpRef param_4 = _885; CmdJump param_5 = s; CmdJump_write(param_3, param_4, param_5); } @@ -343,22 +358,22 @@ bool alloc_cmd(inout Alloc cmd_alloc, inout CmdRef cmd_ref, inout uint cmd_limit return true; } uint param = 1024u; - MallocResult _762 = malloc(param); - MallocResult new_cmd = _762; + MallocResult _913 = malloc(param); + MallocResult new_cmd = _913; if (new_cmd.failed) { return false; } - CmdJump _772 = { new_cmd.alloc.offset }; - CmdJump jump = _772; + CmdJump _923 = { new_cmd.alloc.offset }; + CmdJump jump = _923; Alloc param_1 = cmd_alloc; CmdRef param_2 = cmd_ref; CmdJump param_3 = jump; Cmd_Jump_write(param_1, param_2, param_3); cmd_alloc = new_cmd.alloc; - CmdRef _784 = { cmd_alloc.offset }; - cmd_ref = _784; - cmd_limit = (cmd_alloc.offset + 1024u) - 60u; + CmdRef _935 = { cmd_alloc.offset }; + cmd_ref = _935; + cmd_limit = (cmd_alloc.offset + 1024u) - 144u; return true; } @@ -381,9 +396,9 @@ void Cmd_Fill_write(Alloc a, CmdRef ref, CmdFill s) uint param_1 = ref.offset >> uint(2); uint param_2 = 1u; write_mem(param, param_1, param_2); - CmdFillRef _604 = { ref.offset + 4u }; + CmdFillRef _742 = { ref.offset + 4u }; Alloc param_3 = a; - CmdFillRef param_4 = _604; + CmdFillRef param_4 = _742; CmdFill param_5 = s; CmdFill_write(param_3, param_4, param_5); } @@ -415,9 +430,9 @@ void Cmd_Stroke_write(Alloc a, CmdRef ref, CmdStroke s) uint param_1 = ref.offset >> uint(2); uint param_2 = 2u; write_mem(param, param_1, param_2); - CmdStrokeRef _622 = { ref.offset + 4u }; + CmdStrokeRef _760 = { ref.offset + 4u }; Alloc param_3 = a; - CmdStrokeRef param_4 = _622; + CmdStrokeRef param_4 = _760; CmdStroke param_5 = s; CmdStroke_write(param_3, param_4, param_5); } @@ -428,8 +443,8 @@ void write_fill(Alloc alloc, inout CmdRef cmd_ref, Tile tile, float linewidth) { if (tile.tile.offset != 0u) { - CmdFill _807 = { tile.tile.offset, tile.backdrop }; - CmdFill cmd_fill = _807; + CmdFill _958 = { tile.tile.offset, tile.backdrop }; + CmdFill cmd_fill = _958; Alloc param = alloc; CmdRef param_1 = cmd_ref; CmdFill param_2 = cmd_fill; @@ -446,8 +461,8 @@ void write_fill(Alloc alloc, inout CmdRef cmd_ref, Tile tile, float linewidth) } else { - CmdStroke _837 = { tile.tile.offset, 0.5f * linewidth }; - CmdStroke cmd_stroke = _837; + CmdStroke _988 = { tile.tile.offset, 0.5f * linewidth }; + CmdStroke cmd_stroke = _988; Alloc param_5 = alloc; CmdRef param_6 = cmd_ref; CmdStroke param_7 = cmd_stroke; @@ -471,9 +486,9 @@ void Cmd_Color_write(Alloc a, CmdRef ref, CmdColor s) uint param_1 = ref.offset >> uint(2); uint param_2 = 5u; write_mem(param, param_1, param_2); - CmdColorRef _649 = { ref.offset + 4u }; + CmdColorRef _786 = { ref.offset + 4u }; Alloc param_3 = a; - CmdColorRef param_4 = _649; + CmdColorRef param_4 = _786; CmdColor param_5 = s; CmdColor_write(param_3, param_4, param_5); } @@ -505,13 +520,75 @@ void Cmd_LinGrad_write(Alloc a, CmdRef ref, CmdLinGrad s) uint param_1 = ref.offset >> uint(2); uint param_2 = 6u; write_mem(param, param_1, param_2); - CmdLinGradRef _668 = { ref.offset + 4u }; + CmdLinGradRef _804 = { ref.offset + 4u }; Alloc param_3 = a; - CmdLinGradRef param_4 = _668; + CmdLinGradRef param_4 = _804; CmdLinGrad param_5 = s; CmdLinGrad_write(param_3, param_4, param_5); } +void CmdRadGrad_write(Alloc a, CmdRadGradRef ref, CmdRadGrad s) +{ + uint ix = ref.offset >> uint(2); + Alloc param = a; + uint param_1 = ix + 0u; + uint param_2 = s.index; + write_mem(param, param_1, param_2); + Alloc param_3 = a; + uint param_4 = ix + 1u; + uint param_5 = asuint(s.mat.x); + write_mem(param_3, param_4, param_5); + Alloc param_6 = a; + uint param_7 = ix + 2u; + uint param_8 = asuint(s.mat.y); + write_mem(param_6, param_7, param_8); + Alloc param_9 = a; + uint param_10 = ix + 3u; + uint param_11 = asuint(s.mat.z); + write_mem(param_9, param_10, param_11); + Alloc param_12 = a; + uint param_13 = ix + 4u; + uint param_14 = asuint(s.mat.w); + write_mem(param_12, param_13, param_14); + Alloc param_15 = a; + uint param_16 = ix + 5u; + uint param_17 = asuint(s.xlat.x); + write_mem(param_15, param_16, param_17); + Alloc param_18 = a; + uint param_19 = ix + 6u; + uint param_20 = asuint(s.xlat.y); + write_mem(param_18, param_19, param_20); + Alloc param_21 = a; + uint param_22 = ix + 7u; + uint param_23 = asuint(s.c1.x); + write_mem(param_21, param_22, param_23); + Alloc param_24 = a; + uint param_25 = ix + 8u; + uint param_26 = asuint(s.c1.y); + write_mem(param_24, param_25, param_26); + Alloc param_27 = a; + uint param_28 = ix + 9u; + uint param_29 = asuint(s.ra); + write_mem(param_27, param_28, param_29); + Alloc param_30 = a; + uint param_31 = ix + 10u; + uint param_32 = asuint(s.roff); + write_mem(param_30, param_31, param_32); +} + +void Cmd_RadGrad_write(Alloc a, CmdRef ref, CmdRadGrad s) +{ + Alloc param = a; + uint param_1 = ref.offset >> uint(2); + uint param_2 = 7u; + write_mem(param, param_1, param_2); + CmdRadGradRef _822 = { ref.offset + 4u }; + Alloc param_3 = a; + CmdRadGradRef param_4 = _822; + CmdRadGrad param_5 = s; + CmdRadGrad_write(param_3, param_4, param_5); +} + void CmdImage_write(Alloc a, CmdImageRef ref, CmdImage s) { uint ix = ref.offset >> uint(2); @@ -529,11 +606,11 @@ void Cmd_Image_write(Alloc a, CmdRef ref, CmdImage s) { Alloc param = a; uint param_1 = ref.offset >> uint(2); - uint param_2 = 7u; + uint param_2 = 8u; write_mem(param, param_1, param_2); - CmdImageRef _687 = { ref.offset + 4u }; + CmdImageRef _840 = { ref.offset + 4u }; Alloc param_3 = a; - CmdImageRef param_4 = _687; + CmdImageRef param_4 = _840; CmdImage param_5 = s; CmdImage_write(param_3, param_4, param_5); } @@ -542,7 +619,7 @@ void Cmd_BeginClip_write(Alloc a, CmdRef ref) { Alloc param = a; uint param_1 = ref.offset >> uint(2); - uint param_2 = 8u; + uint param_2 = 9u; write_mem(param, param_1, param_2); } @@ -559,11 +636,11 @@ void Cmd_EndClip_write(Alloc a, CmdRef ref, CmdEndClip s) { Alloc param = a; uint param_1 = ref.offset >> uint(2); - uint param_2 = 9u; + uint param_2 = 10u; write_mem(param, param_1, param_2); - CmdEndClipRef _715 = { ref.offset + 4u }; + CmdEndClipRef _866 = { ref.offset + 4u }; Alloc param_3 = a; - CmdEndClipRef param_4 = _715; + CmdEndClipRef param_4 = _866; CmdEndClip param_5 = s; CmdEndClip_write(param_3, param_4, param_5); } @@ -578,80 +655,81 @@ void Cmd_End_write(Alloc a, CmdRef ref) void comp_main() { - uint width_in_bins = ((_854.Load(8) + 16u) - 1u) / 16u; + uint width_in_bins = ((_1005.Load(8) + 16u) - 1u) / 16u; uint bin_ix = (width_in_bins * gl_WorkGroupID.y) + gl_WorkGroupID.x; uint partition_ix = 0u; - uint n_partitions = ((_854.Load(0) + 256u) - 1u) / 256u; + uint n_partitions = ((_1005.Load(0) + 256u) - 1u) / 256u; uint th_ix = gl_LocalInvocationID.x; uint bin_tile_x = 16u * gl_WorkGroupID.x; uint bin_tile_y = 16u * gl_WorkGroupID.y; uint tile_x = gl_LocalInvocationID.x % 16u; uint tile_y = gl_LocalInvocationID.x / 16u; - uint this_tile_ix = (((bin_tile_y + tile_y) * _854.Load(8)) + bin_tile_x) + tile_x; - Alloc _919; - _919.offset = _854.Load(24); + uint this_tile_ix = (((bin_tile_y + tile_y) * _1005.Load(8)) + bin_tile_x) + tile_x; + Alloc _1070; + _1070.offset = _1005.Load(24); Alloc param; - param.offset = _919.offset; + param.offset = _1070.offset; uint param_1 = this_tile_ix * 1024u; uint param_2 = 1024u; Alloc cmd_alloc = slice_mem(param, param_1, param_2); - CmdRef _928 = { cmd_alloc.offset }; - CmdRef cmd_ref = _928; - uint cmd_limit = (cmd_ref.offset + 1024u) - 60u; + CmdRef _1079 = { cmd_alloc.offset }; + CmdRef cmd_ref = _1079; + uint cmd_limit = (cmd_ref.offset + 1024u) - 144u; uint clip_depth = 0u; uint clip_zero_depth = 0u; uint rd_ix = 0u; uint wr_ix = 0u; uint part_start_ix = 0u; uint ready_ix = 0u; - uint drawmonoid_start = _854.Load(44) >> uint(2); - uint drawtag_start = _854.Load(100) >> uint(2); - uint drawdata_start = _854.Load(104) >> uint(2); - uint drawinfo_start = _854.Load(68) >> uint(2); - bool mem_ok = _242.Load(4) == 0u; + uint drawmonoid_start = _1005.Load(44) >> uint(2); + uint drawtag_start = _1005.Load(100) >> uint(2); + uint drawdata_start = _1005.Load(104) >> uint(2); + uint drawinfo_start = _1005.Load(68) >> uint(2); + bool mem_ok = _260.Load(4) == 0u; Alloc param_3; Alloc param_5; - uint _1154; + uint _1304; uint element_ix; Alloc param_14; uint tile_count; - uint _1455; + uint _1605; float linewidth; CmdLinGrad cmd_lin; + CmdRadGrad cmd_rad; while (true) { for (uint i = 0u; i < 8u; i++) { sh_bitmaps[i][th_ix] = 0u; } - bool _1206; + bool _1356; for (;;) { if ((ready_ix == wr_ix) && (partition_ix < n_partitions)) { part_start_ix = ready_ix; uint count = 0u; - bool _1003 = th_ix < 256u; - bool _1011; - if (_1003) + bool _1154 = th_ix < 256u; + bool _1162; + if (_1154) { - _1011 = (partition_ix + th_ix) < n_partitions; + _1162 = (partition_ix + th_ix) < n_partitions; } else { - _1011 = _1003; + _1162 = _1154; } - if (_1011) + if (_1162) { - uint in_ix = (_854.Load(20) >> uint(2)) + ((((partition_ix + th_ix) * 256u) + bin_ix) * 2u); - Alloc _1029; - _1029.offset = _854.Load(20); - param_3.offset = _1029.offset; + uint in_ix = (_1005.Load(20) >> uint(2)) + ((((partition_ix + th_ix) * 256u) + bin_ix) * 2u); + Alloc _1179; + _1179.offset = _1005.Load(20); + param_3.offset = _1179.offset; uint param_4 = in_ix; count = read_mem(param_3, param_4); - Alloc _1040; - _1040.offset = _854.Load(20); - param_5.offset = _1040.offset; + Alloc _1190; + _1190.offset = _1005.Load(20); + param_5.offset = _1190.offset; uint param_6 = in_ix + 1u; uint offset = read_mem(param_5, param_6); uint param_7 = offset; @@ -697,16 +775,16 @@ void comp_main() } if (part_ix > 0u) { - _1154 = sh_part_count[part_ix - 1u]; + _1304 = sh_part_count[part_ix - 1u]; } else { - _1154 = part_start_ix; + _1304 = part_start_ix; } - ix -= _1154; + ix -= _1304; Alloc bin_alloc = sh_part_elements[part_ix]; - BinInstanceRef _1173 = { bin_alloc.offset }; - BinInstanceRef inst_ref = _1173; + BinInstanceRef _1323 = { bin_alloc.offset }; + BinInstanceRef inst_ref = _1323; BinInstanceRef param_10 = inst_ref; uint param_11 = ix; Alloc param_12 = bin_alloc; @@ -716,16 +794,16 @@ void comp_main() } GroupMemoryBarrierWithGroupSync(); wr_ix = min((rd_ix + 256u), ready_ix); - bool _1196 = (wr_ix - rd_ix) < 256u; - if (_1196) + bool _1346 = (wr_ix - rd_ix) < 256u; + if (_1346) { - _1206 = (wr_ix < ready_ix) || (partition_ix < n_partitions); + _1356 = (wr_ix < ready_ix) || (partition_ix < n_partitions); } else { - _1206 = _1196; + _1356 = _1346; } - if (_1206) + if (_1356) { continue; } @@ -738,23 +816,24 @@ void comp_main() if ((th_ix + rd_ix) < wr_ix) { element_ix = sh_elements[th_ix]; - tag = _1222.Load((drawtag_start + element_ix) * 4 + 0); + tag = _1372.Load((drawtag_start + element_ix) * 4 + 0); } switch (tag) { case 68u: case 72u: case 276u: + case 732u: case 5u: case 37u: { uint drawmonoid_base = drawmonoid_start + (4u * element_ix); - uint path_ix = _242.Load(drawmonoid_base * 4 + 8); - PathRef _1247 = { _854.Load(16) + (path_ix * 12u) }; - Alloc _1250; - _1250.offset = _854.Load(16); - param_14.offset = _1250.offset; - PathRef param_15 = _1247; + uint path_ix = _260.Load(drawmonoid_base * 4 + 8); + PathRef _1397 = { _1005.Load(16) + (path_ix * 12u) }; + Alloc _1400; + _1400.offset = _1005.Load(16); + param_14.offset = _1400.offset; + PathRef param_15 = _1397; Path path = Path_read(param_14, param_15); uint stride = path.bbox.z - path.bbox.x; sh_tile_stride[th_ix] = stride; @@ -810,16 +889,16 @@ void comp_main() } } uint element_ix_1 = sh_elements[el_ix]; - uint tag_1 = _1222.Load((drawtag_start + element_ix_1) * 4 + 0); + uint tag_1 = _1372.Load((drawtag_start + element_ix_1) * 4 + 0); if (el_ix > 0u) { - _1455 = sh_tile_count[el_ix - 1u]; + _1605 = sh_tile_count[el_ix - 1u]; } else { - _1455 = 0u; + _1605 = 0u; } - uint seq_ix = ix_1 - _1455; + uint seq_ix = ix_1 - _1605; uint width = sh_tile_width[el_ix]; uint x = sh_tile_x0[el_ix] + (seq_ix % width); uint y = sh_tile_y0[el_ix] + (seq_ix / width); @@ -828,38 +907,38 @@ void comp_main() { uint param_21 = el_ix; bool param_22 = mem_ok; - TileRef _1507 = { sh_tile_base[el_ix] + (((sh_tile_stride[el_ix] * y) + x) * 8u) }; + TileRef _1657 = { sh_tile_base[el_ix] + (((sh_tile_stride[el_ix] * y) + x) * 8u) }; Alloc param_23 = read_tile_alloc(param_21, param_22); - TileRef param_24 = _1507; + TileRef param_24 = _1657; Tile tile = Tile_read(param_23, param_24); bool is_clip = (tag_1 & 1u) != 0u; bool is_blend = false; if (is_clip) { uint drawmonoid_base_1 = drawmonoid_start + (4u * element_ix_1); - uint scene_offset = _242.Load((drawmonoid_base_1 + 2u) * 4 + 8); + uint scene_offset = _260.Load((drawmonoid_base_1 + 2u) * 4 + 8); uint dd = drawdata_start + (scene_offset >> uint(2)); - uint blend = _1222.Load(dd * 4 + 0); + uint blend = _1372.Load(dd * 4 + 0); is_blend = blend != 3u; } - bool _1542 = tile.tile.offset != 0u; - bool _1551; - if (!_1542) + bool _1692 = tile.tile.offset != 0u; + bool _1701; + if (!_1692) { - _1551 = (tile.backdrop == 0) == is_clip; + _1701 = (tile.backdrop == 0) == is_clip; } else { - _1551 = _1542; + _1701 = _1692; } - include_tile = _1551 || is_blend; + include_tile = _1701 || is_blend; } if (include_tile) { uint el_slice = el_ix / 32u; uint el_mask = 1u << (el_ix & 31u); - uint _1573; - InterlockedOr(sh_bitmaps[el_slice][(y * 16u) + x], el_mask, _1573); + uint _1723; + InterlockedOr(sh_bitmaps[el_slice][(y * 16u) + x], el_mask, _1723); } } GroupMemoryBarrierWithGroupSync(); @@ -883,33 +962,33 @@ void comp_main() uint element_ref_ix = (slice_ix * 32u) + uint(int(firstbitlow(bitmap))); uint element_ix_2 = sh_elements[element_ref_ix]; bitmap &= (bitmap - 1u); - uint drawtag = _1222.Load((drawtag_start + element_ix_2) * 4 + 0); + uint drawtag = _1372.Load((drawtag_start + element_ix_2) * 4 + 0); if (clip_zero_depth == 0u) { uint param_25 = element_ref_ix; bool param_26 = mem_ok; - TileRef _1650 = { sh_tile_base[element_ref_ix] + (((sh_tile_stride[element_ref_ix] * tile_y) + tile_x) * 8u) }; + TileRef _1800 = { sh_tile_base[element_ref_ix] + (((sh_tile_stride[element_ref_ix] * tile_y) + tile_x) * 8u) }; Alloc param_27 = read_tile_alloc(param_25, param_26); - TileRef param_28 = _1650; + TileRef param_28 = _1800; Tile tile_1 = Tile_read(param_27, param_28); uint drawmonoid_base_2 = drawmonoid_start + (4u * element_ix_2); - uint scene_offset_1 = _242.Load((drawmonoid_base_2 + 2u) * 4 + 8); - uint info_offset = _242.Load((drawmonoid_base_2 + 3u) * 4 + 8); + uint scene_offset_1 = _260.Load((drawmonoid_base_2 + 2u) * 4 + 8); + uint info_offset = _260.Load((drawmonoid_base_2 + 3u) * 4 + 8); uint dd_1 = drawdata_start + (scene_offset_1 >> uint(2)); uint di = drawinfo_start + (info_offset >> uint(2)); switch (drawtag) { case 68u: { - linewidth = asfloat(_242.Load(di * 4 + 8)); + linewidth = asfloat(_260.Load(di * 4 + 8)); Alloc param_29 = cmd_alloc; CmdRef param_30 = cmd_ref; uint param_31 = cmd_limit; - bool _1697 = alloc_cmd(param_29, param_30, param_31); + bool _1848 = alloc_cmd(param_29, param_30, param_31); cmd_alloc = param_29; cmd_ref = param_30; cmd_limit = param_31; - if (!_1697) + if (!_1848) { break; } @@ -919,11 +998,11 @@ void comp_main() float param_35 = linewidth; write_fill(param_32, param_33, param_34, param_35); cmd_ref = param_33; - uint rgba = _1222.Load(dd_1 * 4 + 0); - CmdColor _1720 = { rgba }; + uint rgba = _1372.Load(dd_1 * 4 + 0); + CmdColor _1871 = { rgba }; Alloc param_36 = cmd_alloc; CmdRef param_37 = cmd_ref; - CmdColor param_38 = _1720; + CmdColor param_38 = _1871; Cmd_Color_write(param_36, param_37, param_38); cmd_ref.offset += 8u; break; @@ -933,25 +1012,25 @@ void comp_main() Alloc param_39 = cmd_alloc; CmdRef param_40 = cmd_ref; uint param_41 = cmd_limit; - bool _1738 = alloc_cmd(param_39, param_40, param_41); + bool _1889 = alloc_cmd(param_39, param_40, param_41); cmd_alloc = param_39; cmd_ref = param_40; cmd_limit = param_41; - if (!_1738) + if (!_1889) { break; } - linewidth = asfloat(_242.Load(di * 4 + 8)); + linewidth = asfloat(_260.Load(di * 4 + 8)); Alloc param_42 = cmd_alloc; CmdRef param_43 = cmd_ref; Tile param_44 = tile_1; float param_45 = linewidth; write_fill(param_42, param_43, param_44, param_45); cmd_ref = param_43; - cmd_lin.index = _1222.Load(dd_1 * 4 + 0); - cmd_lin.line_x = asfloat(_242.Load((di + 1u) * 4 + 8)); - cmd_lin.line_y = asfloat(_242.Load((di + 2u) * 4 + 8)); - cmd_lin.line_c = asfloat(_242.Load((di + 3u) * 4 + 8)); + cmd_lin.index = _1372.Load(dd_1 * 4 + 0); + cmd_lin.line_x = asfloat(_260.Load((di + 1u) * 4 + 8)); + cmd_lin.line_y = asfloat(_260.Load((di + 2u) * 4 + 8)); + cmd_lin.line_c = asfloat(_260.Load((di + 3u) * 4 + 8)); Alloc param_46 = cmd_alloc; CmdRef param_47 = cmd_ref; CmdLinGrad param_48 = cmd_lin; @@ -959,69 +1038,102 @@ void comp_main() cmd_ref.offset += 20u; break; } - case 72u: + case 732u: { - linewidth = asfloat(_242.Load(di * 4 + 8)); Alloc param_49 = cmd_alloc; CmdRef param_50 = cmd_ref; uint param_51 = cmd_limit; - bool _1806 = alloc_cmd(param_49, param_50, param_51); + bool _1953 = alloc_cmd(param_49, param_50, param_51); cmd_alloc = param_49; cmd_ref = param_50; cmd_limit = param_51; - if (!_1806) + if (!_1953) { break; } + linewidth = asfloat(_260.Load(di * 4 + 8)); Alloc param_52 = cmd_alloc; CmdRef param_53 = cmd_ref; Tile param_54 = tile_1; float param_55 = linewidth; write_fill(param_52, param_53, param_54, param_55); cmd_ref = param_53; - uint index = _1222.Load(dd_1 * 4 + 0); - uint raw1 = _1222.Load((dd_1 + 1u) * 4 + 0); - int2 offset_1 = int2(int(raw1 << uint(16)) >> 16, int(raw1) >> 16); - CmdImage _1845 = { index, offset_1 }; + cmd_rad.index = _1372.Load(dd_1 * 4 + 0); + cmd_rad.mat = asfloat(uint4(_260.Load((di + 1u) * 4 + 8), _260.Load((di + 2u) * 4 + 8), _260.Load((di + 3u) * 4 + 8), _260.Load((di + 4u) * 4 + 8))); + cmd_rad.xlat = asfloat(uint2(_260.Load((di + 5u) * 4 + 8), _260.Load((di + 6u) * 4 + 8))); + cmd_rad.c1 = asfloat(uint2(_260.Load((di + 7u) * 4 + 8), _260.Load((di + 8u) * 4 + 8))); + cmd_rad.ra = asfloat(_260.Load((di + 9u) * 4 + 8)); + cmd_rad.roff = asfloat(_260.Load((di + 10u) * 4 + 8)); Alloc param_56 = cmd_alloc; CmdRef param_57 = cmd_ref; - CmdImage param_58 = _1845; - Cmd_Image_write(param_56, param_57, param_58); + CmdRadGrad param_58 = cmd_rad; + Cmd_RadGrad_write(param_56, param_57, param_58); + cmd_ref.offset += 48u; + break; + } + case 72u: + { + linewidth = asfloat(_260.Load(di * 4 + 8)); + Alloc param_59 = cmd_alloc; + CmdRef param_60 = cmd_ref; + uint param_61 = cmd_limit; + bool _2059 = alloc_cmd(param_59, param_60, param_61); + cmd_alloc = param_59; + cmd_ref = param_60; + cmd_limit = param_61; + if (!_2059) + { + break; + } + Alloc param_62 = cmd_alloc; + CmdRef param_63 = cmd_ref; + Tile param_64 = tile_1; + float param_65 = linewidth; + write_fill(param_62, param_63, param_64, param_65); + cmd_ref = param_63; + uint index = _1372.Load(dd_1 * 4 + 0); + uint raw1 = _1372.Load((dd_1 + 1u) * 4 + 0); + int2 offset_1 = int2(int(raw1 << uint(16)) >> 16, int(raw1) >> 16); + CmdImage _2098 = { index, offset_1 }; + Alloc param_66 = cmd_alloc; + CmdRef param_67 = cmd_ref; + CmdImage param_68 = _2098; + Cmd_Image_write(param_66, param_67, param_68); cmd_ref.offset += 12u; break; } case 5u: { - bool _1859 = tile_1.tile.offset == 0u; - bool _1865; - if (_1859) + bool _2112 = tile_1.tile.offset == 0u; + bool _2118; + if (_2112) { - _1865 = tile_1.backdrop == 0; + _2118 = tile_1.backdrop == 0; } else { - _1865 = _1859; + _2118 = _2112; } - if (_1865) + if (_2118) { clip_zero_depth = clip_depth + 1u; } else { - Alloc param_59 = cmd_alloc; - CmdRef param_60 = cmd_ref; - uint param_61 = cmd_limit; - bool _1877 = alloc_cmd(param_59, param_60, param_61); - cmd_alloc = param_59; - cmd_ref = param_60; - cmd_limit = param_61; - if (!_1877) + Alloc param_69 = cmd_alloc; + CmdRef param_70 = cmd_ref; + uint param_71 = cmd_limit; + bool _2130 = alloc_cmd(param_69, param_70, param_71); + cmd_alloc = param_69; + cmd_ref = param_70; + cmd_limit = param_71; + if (!_2130) { break; } - Alloc param_62 = cmd_alloc; - CmdRef param_63 = cmd_ref; - Cmd_BeginClip_write(param_62, param_63); + Alloc param_72 = cmd_alloc; + CmdRef param_73 = cmd_ref; + Cmd_BeginClip_write(param_72, param_73); cmd_ref.offset += 4u; } clip_depth++; @@ -1030,29 +1142,29 @@ void comp_main() case 37u: { clip_depth--; - Alloc param_64 = cmd_alloc; - CmdRef param_65 = cmd_ref; - uint param_66 = cmd_limit; - bool _1905 = alloc_cmd(param_64, param_65, param_66); - cmd_alloc = param_64; - cmd_ref = param_65; - cmd_limit = param_66; - if (!_1905) + Alloc param_74 = cmd_alloc; + CmdRef param_75 = cmd_ref; + uint param_76 = cmd_limit; + bool _2158 = alloc_cmd(param_74, param_75, param_76); + cmd_alloc = param_74; + cmd_ref = param_75; + cmd_limit = param_76; + if (!_2158) { break; } - Alloc param_67 = cmd_alloc; - CmdRef param_68 = cmd_ref; - Tile param_69 = tile_1; - float param_70 = -1.0f; - write_fill(param_67, param_68, param_69, param_70); - cmd_ref = param_68; - uint blend_1 = _1222.Load(dd_1 * 4 + 0); - CmdEndClip _1928 = { blend_1 }; - Alloc param_71 = cmd_alloc; - CmdRef param_72 = cmd_ref; - CmdEndClip param_73 = _1928; - Cmd_EndClip_write(param_71, param_72, param_73); + Alloc param_77 = cmd_alloc; + CmdRef param_78 = cmd_ref; + Tile param_79 = tile_1; + float param_80 = -1.0f; + write_fill(param_77, param_78, param_79, param_80); + cmd_ref = param_78; + uint blend_1 = _1372.Load(dd_1 * 4 + 0); + CmdEndClip _2181 = { blend_1 }; + Alloc param_81 = cmd_alloc; + CmdRef param_82 = cmd_ref; + CmdEndClip param_83 = _2181; + Cmd_EndClip_write(param_81, param_82, param_83); cmd_ref.offset += 8u; break; } @@ -1086,21 +1198,21 @@ void comp_main() break; } } - bool _1975 = (bin_tile_x + tile_x) < _854.Load(8); - bool _1984; - if (_1975) + bool _2228 = (bin_tile_x + tile_x) < _1005.Load(8); + bool _2237; + if (_2228) { - _1984 = (bin_tile_y + tile_y) < _854.Load(12); + _2237 = (bin_tile_y + tile_y) < _1005.Load(12); } else { - _1984 = _1975; + _2237 = _2228; } - if (_1984) + if (_2237) { - Alloc param_74 = cmd_alloc; - CmdRef param_75 = cmd_ref; - Cmd_End_write(param_74, param_75); + Alloc param_84 = cmd_alloc; + CmdRef param_85 = cmd_ref; + Cmd_End_write(param_84, param_85); } } diff --git a/piet-gpu/shader/gen/coarse.msl b/piet-gpu/shader/gen/coarse.msl index 4226352..55812d4 100644 --- a/piet-gpu/shader/gen/coarse.msl +++ b/piet-gpu/shader/gen/coarse.msl @@ -107,6 +107,21 @@ struct CmdLinGrad float line_c; }; +struct CmdRadGradRef +{ + uint offset; +}; + +struct CmdRadGrad +{ + uint index; + float4 mat; + float2 xlat; + float2 c1; + float ra; + float roff; +}; + struct CmdImageRef { uint offset; @@ -211,7 +226,7 @@ bool touch_mem(thread const Alloc& alloc, thread const uint& offset) } static inline __attribute__((always_inline)) -uint read_mem(thread const Alloc& alloc, thread const uint& offset, device Memory& v_242, constant uint& v_242BufferSize) +uint read_mem(thread const Alloc& alloc, thread const uint& offset, device Memory& v_260, constant uint& v_260BufferSize) { Alloc param = alloc; uint param_1 = offset; @@ -219,7 +234,7 @@ uint read_mem(thread const Alloc& alloc, thread const uint& offset, device Memor { return 0u; } - uint v = v_242.memory[offset]; + uint v = v_260.memory[offset]; return v; } @@ -238,30 +253,30 @@ BinInstanceRef BinInstance_index(thread const BinInstanceRef& ref, thread const } static inline __attribute__((always_inline)) -BinInstance BinInstance_read(thread const Alloc& a, thread const BinInstanceRef& ref, device Memory& v_242, constant uint& v_242BufferSize) +BinInstance BinInstance_read(thread const Alloc& a, thread const BinInstanceRef& ref, device Memory& v_260, constant uint& v_260BufferSize) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; - uint raw0 = read_mem(param, param_1, v_242, v_242BufferSize); + uint raw0 = read_mem(param, param_1, v_260, v_260BufferSize); BinInstance s; s.element_ix = raw0; return s; } static inline __attribute__((always_inline)) -Path Path_read(thread const Alloc& a, thread const PathRef& ref, device Memory& v_242, constant uint& v_242BufferSize) +Path Path_read(thread const Alloc& a, thread const PathRef& ref, device Memory& v_260, constant uint& v_260BufferSize) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; - uint raw0 = read_mem(param, param_1, v_242, v_242BufferSize); + uint raw0 = read_mem(param, param_1, v_260, v_260BufferSize); Alloc param_2 = a; uint param_3 = ix + 1u; - uint raw1 = read_mem(param_2, param_3, v_242, v_242BufferSize); + uint raw1 = read_mem(param_2, param_3, v_260, v_260BufferSize); Alloc param_4 = a; uint param_5 = ix + 2u; - uint raw2 = read_mem(param_4, param_5, v_242, v_242BufferSize); + uint raw2 = read_mem(param_4, param_5, v_260, v_260BufferSize); Path s; s.bbox = uint4(raw0 & 65535u, raw0 >> uint(16), raw1 & 65535u, raw1 >> uint(16)); s.tiles = TileRef{ raw2 }; @@ -274,24 +289,24 @@ void write_tile_alloc(thread const uint& el_ix, thread const Alloc& a) } static inline __attribute__((always_inline)) -Alloc read_tile_alloc(thread const uint& el_ix, thread const bool& mem_ok, device Memory& v_242, constant uint& v_242BufferSize) +Alloc read_tile_alloc(thread const uint& el_ix, thread const bool& mem_ok, device Memory& v_260, constant uint& v_260BufferSize) { uint param = 0u; - uint param_1 = uint(int((v_242BufferSize - 8) / 4) * 4); + uint param_1 = uint(int((v_260BufferSize - 8) / 4) * 4); bool param_2 = mem_ok; return new_alloc(param, param_1, param_2); } static inline __attribute__((always_inline)) -Tile Tile_read(thread const Alloc& a, thread const TileRef& ref, device Memory& v_242, constant uint& v_242BufferSize) +Tile Tile_read(thread const Alloc& a, thread const TileRef& ref, device Memory& v_260, constant uint& v_260BufferSize) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; - uint raw0 = read_mem(param, param_1, v_242, v_242BufferSize); + uint raw0 = read_mem(param, param_1, v_260, v_260BufferSize); Alloc param_2 = a; uint param_3 = ix + 1u; - uint raw1 = read_mem(param_2, param_3, v_242, v_242BufferSize); + uint raw1 = read_mem(param_2, param_3, v_260, v_260BufferSize); Tile s; s.tile = TileSegRef{ raw0 }; s.backdrop = int(raw1); @@ -299,26 +314,26 @@ Tile Tile_read(thread const Alloc& a, thread const TileRef& ref, device Memory& } static inline __attribute__((always_inline)) -MallocResult malloc(thread const uint& size, device Memory& v_242, constant uint& v_242BufferSize) +MallocResult malloc(thread const uint& size, device Memory& v_260, constant uint& v_260BufferSize) { - uint _248 = atomic_fetch_add_explicit((device atomic_uint*)&v_242.mem_offset, size, memory_order_relaxed); - uint offset = _248; + uint _266 = atomic_fetch_add_explicit((device atomic_uint*)&v_260.mem_offset, size, memory_order_relaxed); + uint offset = _266; MallocResult r; - r.failed = (offset + size) > uint(int((v_242BufferSize - 8) / 4) * 4); + r.failed = (offset + size) > uint(int((v_260BufferSize - 8) / 4) * 4); uint param = offset; uint param_1 = size; bool param_2 = !r.failed; r.alloc = new_alloc(param, param_1, param_2); if (r.failed) { - uint _277 = atomic_fetch_max_explicit((device atomic_uint*)&v_242.mem_error, 1u, memory_order_relaxed); + uint _295 = atomic_fetch_max_explicit((device atomic_uint*)&v_260.mem_error, 1u, memory_order_relaxed); return r; } return r; } static inline __attribute__((always_inline)) -void write_mem(thread const Alloc& alloc, thread const uint& offset, thread const uint& val, device Memory& v_242, constant uint& v_242BufferSize) +void write_mem(thread const Alloc& alloc, thread const uint& offset, thread const uint& val, device Memory& v_260, constant uint& v_260BufferSize) { Alloc param = alloc; uint param_1 = offset; @@ -326,42 +341,42 @@ void write_mem(thread const Alloc& alloc, thread const uint& offset, thread cons { return; } - v_242.memory[offset] = val; + v_260.memory[offset] = val; } static inline __attribute__((always_inline)) -void CmdJump_write(thread const Alloc& a, thread const CmdJumpRef& ref, thread const CmdJump& s, device Memory& v_242, constant uint& v_242BufferSize) +void CmdJump_write(thread const Alloc& a, thread const CmdJumpRef& ref, thread const CmdJump& s, device Memory& v_260, constant uint& v_260BufferSize) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; uint param_2 = s.new_ref; - write_mem(param, param_1, param_2, v_242, v_242BufferSize); + write_mem(param, param_1, param_2, v_260, v_260BufferSize); } static inline __attribute__((always_inline)) -void Cmd_Jump_write(thread const Alloc& a, thread const CmdRef& ref, thread const CmdJump& s, device Memory& v_242, constant uint& v_242BufferSize) +void Cmd_Jump_write(thread const Alloc& a, thread const CmdRef& ref, thread const CmdJump& s, device Memory& v_260, constant uint& v_260BufferSize) { Alloc param = a; uint param_1 = ref.offset >> uint(2); - uint param_2 = 10u; - write_mem(param, param_1, param_2, v_242, v_242BufferSize); + uint param_2 = 11u; + write_mem(param, param_1, param_2, v_260, v_260BufferSize); Alloc param_3 = a; CmdJumpRef param_4 = CmdJumpRef{ ref.offset + 4u }; CmdJump param_5 = s; - CmdJump_write(param_3, param_4, param_5, v_242, v_242BufferSize); + CmdJump_write(param_3, param_4, param_5, v_260, v_260BufferSize); } static inline __attribute__((always_inline)) -bool alloc_cmd(thread Alloc& cmd_alloc, thread CmdRef& cmd_ref, thread uint& cmd_limit, device Memory& v_242, constant uint& v_242BufferSize) +bool alloc_cmd(thread Alloc& cmd_alloc, thread CmdRef& cmd_ref, thread uint& cmd_limit, device Memory& v_260, constant uint& v_260BufferSize) { if (cmd_ref.offset < cmd_limit) { return true; } uint param = 1024u; - MallocResult _762 = malloc(param, v_242, v_242BufferSize); - MallocResult new_cmd = _762; + MallocResult _913 = malloc(param, v_260, v_260BufferSize); + MallocResult new_cmd = _913; if (new_cmd.failed) { return false; @@ -370,78 +385,78 @@ bool alloc_cmd(thread Alloc& cmd_alloc, thread CmdRef& cmd_ref, thread uint& cmd Alloc param_1 = cmd_alloc; CmdRef param_2 = cmd_ref; CmdJump param_3 = jump; - Cmd_Jump_write(param_1, param_2, param_3, v_242, v_242BufferSize); + Cmd_Jump_write(param_1, param_2, param_3, v_260, v_260BufferSize); cmd_alloc = new_cmd.alloc; cmd_ref = CmdRef{ cmd_alloc.offset }; - cmd_limit = (cmd_alloc.offset + 1024u) - 60u; + cmd_limit = (cmd_alloc.offset + 1024u) - 144u; return true; } static inline __attribute__((always_inline)) -void CmdFill_write(thread const Alloc& a, thread const CmdFillRef& ref, thread const CmdFill& s, device Memory& v_242, constant uint& v_242BufferSize) +void CmdFill_write(thread const Alloc& a, thread const CmdFillRef& ref, thread const CmdFill& s, device Memory& v_260, constant uint& v_260BufferSize) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; uint param_2 = s.tile_ref; - write_mem(param, param_1, param_2, v_242, v_242BufferSize); + write_mem(param, param_1, param_2, v_260, v_260BufferSize); Alloc param_3 = a; uint param_4 = ix + 1u; uint param_5 = uint(s.backdrop); - write_mem(param_3, param_4, param_5, v_242, v_242BufferSize); + write_mem(param_3, param_4, param_5, v_260, v_260BufferSize); } static inline __attribute__((always_inline)) -void Cmd_Fill_write(thread const Alloc& a, thread const CmdRef& ref, thread const CmdFill& s, device Memory& v_242, constant uint& v_242BufferSize) +void Cmd_Fill_write(thread const Alloc& a, thread const CmdRef& ref, thread const CmdFill& s, device Memory& v_260, constant uint& v_260BufferSize) { Alloc param = a; uint param_1 = ref.offset >> uint(2); uint param_2 = 1u; - write_mem(param, param_1, param_2, v_242, v_242BufferSize); + write_mem(param, param_1, param_2, v_260, v_260BufferSize); Alloc param_3 = a; CmdFillRef param_4 = CmdFillRef{ ref.offset + 4u }; CmdFill param_5 = s; - CmdFill_write(param_3, param_4, param_5, v_242, v_242BufferSize); + CmdFill_write(param_3, param_4, param_5, v_260, v_260BufferSize); } static inline __attribute__((always_inline)) -void Cmd_Solid_write(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_242, constant uint& v_242BufferSize) +void Cmd_Solid_write(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_260, constant uint& v_260BufferSize) { Alloc param = a; uint param_1 = ref.offset >> uint(2); uint param_2 = 3u; - write_mem(param, param_1, param_2, v_242, v_242BufferSize); + write_mem(param, param_1, param_2, v_260, v_260BufferSize); } static inline __attribute__((always_inline)) -void CmdStroke_write(thread const Alloc& a, thread const CmdStrokeRef& ref, thread const CmdStroke& s, device Memory& v_242, constant uint& v_242BufferSize) +void CmdStroke_write(thread const Alloc& a, thread const CmdStrokeRef& ref, thread const CmdStroke& s, device Memory& v_260, constant uint& v_260BufferSize) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; uint param_2 = s.tile_ref; - write_mem(param, param_1, param_2, v_242, v_242BufferSize); + write_mem(param, param_1, param_2, v_260, v_260BufferSize); Alloc param_3 = a; uint param_4 = ix + 1u; uint param_5 = as_type(s.half_width); - write_mem(param_3, param_4, param_5, v_242, v_242BufferSize); + write_mem(param_3, param_4, param_5, v_260, v_260BufferSize); } static inline __attribute__((always_inline)) -void Cmd_Stroke_write(thread const Alloc& a, thread const CmdRef& ref, thread const CmdStroke& s, device Memory& v_242, constant uint& v_242BufferSize) +void Cmd_Stroke_write(thread const Alloc& a, thread const CmdRef& ref, thread const CmdStroke& s, device Memory& v_260, constant uint& v_260BufferSize) { Alloc param = a; uint param_1 = ref.offset >> uint(2); uint param_2 = 2u; - write_mem(param, param_1, param_2, v_242, v_242BufferSize); + write_mem(param, param_1, param_2, v_260, v_260BufferSize); Alloc param_3 = a; CmdStrokeRef param_4 = CmdStrokeRef{ ref.offset + 4u }; CmdStroke param_5 = s; - CmdStroke_write(param_3, param_4, param_5, v_242, v_242BufferSize); + CmdStroke_write(param_3, param_4, param_5, v_260, v_260BufferSize); } static inline __attribute__((always_inline)) -void write_fill(thread const Alloc& alloc, thread CmdRef& cmd_ref, thread const Tile& tile, thread const float& linewidth, device Memory& v_242, constant uint& v_242BufferSize) +void write_fill(thread const Alloc& alloc, thread CmdRef& cmd_ref, thread const Tile& tile, thread const float& linewidth, device Memory& v_260, constant uint& v_260BufferSize) { if (linewidth < 0.0) { @@ -451,14 +466,14 @@ void write_fill(thread const Alloc& alloc, thread CmdRef& cmd_ref, thread const Alloc param = alloc; CmdRef param_1 = cmd_ref; CmdFill param_2 = cmd_fill; - Cmd_Fill_write(param, param_1, param_2, v_242, v_242BufferSize); + Cmd_Fill_write(param, param_1, param_2, v_260, v_260BufferSize); cmd_ref.offset += 12u; } else { Alloc param_3 = alloc; CmdRef param_4 = cmd_ref; - Cmd_Solid_write(param_3, param_4, v_242, v_242BufferSize); + Cmd_Solid_write(param_3, param_4, v_260, v_260BufferSize); cmd_ref.offset += 4u; } } @@ -468,138 +483,201 @@ void write_fill(thread const Alloc& alloc, thread CmdRef& cmd_ref, thread const Alloc param_5 = alloc; CmdRef param_6 = cmd_ref; CmdStroke param_7 = cmd_stroke; - Cmd_Stroke_write(param_5, param_6, param_7, v_242, v_242BufferSize); + Cmd_Stroke_write(param_5, param_6, param_7, v_260, v_260BufferSize); cmd_ref.offset += 12u; } } static inline __attribute__((always_inline)) -void CmdColor_write(thread const Alloc& a, thread const CmdColorRef& ref, thread const CmdColor& s, device Memory& v_242, constant uint& v_242BufferSize) +void CmdColor_write(thread const Alloc& a, thread const CmdColorRef& ref, thread const CmdColor& s, device Memory& v_260, constant uint& v_260BufferSize) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; uint param_2 = s.rgba_color; - write_mem(param, param_1, param_2, v_242, v_242BufferSize); + write_mem(param, param_1, param_2, v_260, v_260BufferSize); } static inline __attribute__((always_inline)) -void Cmd_Color_write(thread const Alloc& a, thread const CmdRef& ref, thread const CmdColor& s, device Memory& v_242, constant uint& v_242BufferSize) +void Cmd_Color_write(thread const Alloc& a, thread const CmdRef& ref, thread const CmdColor& s, device Memory& v_260, constant uint& v_260BufferSize) { Alloc param = a; uint param_1 = ref.offset >> uint(2); uint param_2 = 5u; - write_mem(param, param_1, param_2, v_242, v_242BufferSize); + write_mem(param, param_1, param_2, v_260, v_260BufferSize); Alloc param_3 = a; CmdColorRef param_4 = CmdColorRef{ ref.offset + 4u }; CmdColor param_5 = s; - CmdColor_write(param_3, param_4, param_5, v_242, v_242BufferSize); + CmdColor_write(param_3, param_4, param_5, v_260, v_260BufferSize); } static inline __attribute__((always_inline)) -void CmdLinGrad_write(thread const Alloc& a, thread const CmdLinGradRef& ref, thread const CmdLinGrad& s, device Memory& v_242, constant uint& v_242BufferSize) +void CmdLinGrad_write(thread const Alloc& a, thread const CmdLinGradRef& ref, thread const CmdLinGrad& s, device Memory& v_260, constant uint& v_260BufferSize) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; uint param_2 = s.index; - write_mem(param, param_1, param_2, v_242, v_242BufferSize); + write_mem(param, param_1, param_2, v_260, v_260BufferSize); Alloc param_3 = a; uint param_4 = ix + 1u; uint param_5 = as_type(s.line_x); - write_mem(param_3, param_4, param_5, v_242, v_242BufferSize); + write_mem(param_3, param_4, param_5, v_260, v_260BufferSize); Alloc param_6 = a; uint param_7 = ix + 2u; uint param_8 = as_type(s.line_y); - write_mem(param_6, param_7, param_8, v_242, v_242BufferSize); + write_mem(param_6, param_7, param_8, v_260, v_260BufferSize); Alloc param_9 = a; uint param_10 = ix + 3u; uint param_11 = as_type(s.line_c); - write_mem(param_9, param_10, param_11, v_242, v_242BufferSize); + write_mem(param_9, param_10, param_11, v_260, v_260BufferSize); } static inline __attribute__((always_inline)) -void Cmd_LinGrad_write(thread const Alloc& a, thread const CmdRef& ref, thread const CmdLinGrad& s, device Memory& v_242, constant uint& v_242BufferSize) +void Cmd_LinGrad_write(thread const Alloc& a, thread const CmdRef& ref, thread const CmdLinGrad& s, device Memory& v_260, constant uint& v_260BufferSize) { Alloc param = a; uint param_1 = ref.offset >> uint(2); uint param_2 = 6u; - write_mem(param, param_1, param_2, v_242, v_242BufferSize); + write_mem(param, param_1, param_2, v_260, v_260BufferSize); Alloc param_3 = a; CmdLinGradRef param_4 = CmdLinGradRef{ ref.offset + 4u }; CmdLinGrad param_5 = s; - CmdLinGrad_write(param_3, param_4, param_5, v_242, v_242BufferSize); + CmdLinGrad_write(param_3, param_4, param_5, v_260, v_260BufferSize); } static inline __attribute__((always_inline)) -void CmdImage_write(thread const Alloc& a, thread const CmdImageRef& ref, thread const CmdImage& s, device Memory& v_242, constant uint& v_242BufferSize) +void CmdRadGrad_write(thread const Alloc& a, thread const CmdRadGradRef& ref, thread const CmdRadGrad& s, device Memory& v_260, constant uint& v_260BufferSize) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; uint param_2 = s.index; - write_mem(param, param_1, param_2, v_242, v_242BufferSize); + write_mem(param, param_1, param_2, v_260, v_260BufferSize); Alloc param_3 = a; uint param_4 = ix + 1u; - uint param_5 = (uint(s.offset.x) & 65535u) | (uint(s.offset.y) << uint(16)); - write_mem(param_3, param_4, param_5, v_242, v_242BufferSize); + uint param_5 = as_type(s.mat.x); + write_mem(param_3, param_4, param_5, v_260, v_260BufferSize); + Alloc param_6 = a; + uint param_7 = ix + 2u; + uint param_8 = as_type(s.mat.y); + write_mem(param_6, param_7, param_8, v_260, v_260BufferSize); + Alloc param_9 = a; + uint param_10 = ix + 3u; + uint param_11 = as_type(s.mat.z); + write_mem(param_9, param_10, param_11, v_260, v_260BufferSize); + Alloc param_12 = a; + uint param_13 = ix + 4u; + uint param_14 = as_type(s.mat.w); + write_mem(param_12, param_13, param_14, v_260, v_260BufferSize); + Alloc param_15 = a; + uint param_16 = ix + 5u; + uint param_17 = as_type(s.xlat.x); + write_mem(param_15, param_16, param_17, v_260, v_260BufferSize); + Alloc param_18 = a; + uint param_19 = ix + 6u; + uint param_20 = as_type(s.xlat.y); + write_mem(param_18, param_19, param_20, v_260, v_260BufferSize); + Alloc param_21 = a; + uint param_22 = ix + 7u; + uint param_23 = as_type(s.c1.x); + write_mem(param_21, param_22, param_23, v_260, v_260BufferSize); + Alloc param_24 = a; + uint param_25 = ix + 8u; + uint param_26 = as_type(s.c1.y); + write_mem(param_24, param_25, param_26, v_260, v_260BufferSize); + Alloc param_27 = a; + uint param_28 = ix + 9u; + uint param_29 = as_type(s.ra); + write_mem(param_27, param_28, param_29, v_260, v_260BufferSize); + Alloc param_30 = a; + uint param_31 = ix + 10u; + uint param_32 = as_type(s.roff); + write_mem(param_30, param_31, param_32, v_260, v_260BufferSize); } static inline __attribute__((always_inline)) -void Cmd_Image_write(thread const Alloc& a, thread const CmdRef& ref, thread const CmdImage& s, device Memory& v_242, constant uint& v_242BufferSize) +void Cmd_RadGrad_write(thread const Alloc& a, thread const CmdRef& ref, thread const CmdRadGrad& s, device Memory& v_260, constant uint& v_260BufferSize) { Alloc param = a; uint param_1 = ref.offset >> uint(2); uint param_2 = 7u; - write_mem(param, param_1, param_2, v_242, v_242BufferSize); + write_mem(param, param_1, param_2, v_260, v_260BufferSize); Alloc param_3 = a; - CmdImageRef param_4 = CmdImageRef{ ref.offset + 4u }; - CmdImage param_5 = s; - CmdImage_write(param_3, param_4, param_5, v_242, v_242BufferSize); + CmdRadGradRef param_4 = CmdRadGradRef{ ref.offset + 4u }; + CmdRadGrad param_5 = s; + CmdRadGrad_write(param_3, param_4, param_5, v_260, v_260BufferSize); } static inline __attribute__((always_inline)) -void Cmd_BeginClip_write(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_242, constant uint& v_242BufferSize) +void CmdImage_write(thread const Alloc& a, thread const CmdImageRef& ref, thread const CmdImage& s, device Memory& v_260, constant uint& v_260BufferSize) +{ + uint ix = ref.offset >> uint(2); + Alloc param = a; + uint param_1 = ix + 0u; + uint param_2 = s.index; + write_mem(param, param_1, param_2, v_260, v_260BufferSize); + Alloc param_3 = a; + uint param_4 = ix + 1u; + uint param_5 = (uint(s.offset.x) & 65535u) | (uint(s.offset.y) << uint(16)); + write_mem(param_3, param_4, param_5, v_260, v_260BufferSize); +} + +static inline __attribute__((always_inline)) +void Cmd_Image_write(thread const Alloc& a, thread const CmdRef& ref, thread const CmdImage& s, device Memory& v_260, constant uint& v_260BufferSize) { Alloc param = a; uint param_1 = ref.offset >> uint(2); uint param_2 = 8u; - write_mem(param, param_1, param_2, v_242, v_242BufferSize); + write_mem(param, param_1, param_2, v_260, v_260BufferSize); + Alloc param_3 = a; + CmdImageRef param_4 = CmdImageRef{ ref.offset + 4u }; + CmdImage param_5 = s; + CmdImage_write(param_3, param_4, param_5, v_260, v_260BufferSize); } static inline __attribute__((always_inline)) -void CmdEndClip_write(thread const Alloc& a, thread const CmdEndClipRef& ref, thread const CmdEndClip& s, device Memory& v_242, constant uint& v_242BufferSize) +void Cmd_BeginClip_write(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_260, constant uint& v_260BufferSize) +{ + Alloc param = a; + uint param_1 = ref.offset >> uint(2); + uint param_2 = 9u; + write_mem(param, param_1, param_2, v_260, v_260BufferSize); +} + +static inline __attribute__((always_inline)) +void CmdEndClip_write(thread const Alloc& a, thread const CmdEndClipRef& ref, thread const CmdEndClip& s, device Memory& v_260, constant uint& v_260BufferSize) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; uint param_2 = s.blend; - write_mem(param, param_1, param_2, v_242, v_242BufferSize); + write_mem(param, param_1, param_2, v_260, v_260BufferSize); } static inline __attribute__((always_inline)) -void Cmd_EndClip_write(thread const Alloc& a, thread const CmdRef& ref, thread const CmdEndClip& s, device Memory& v_242, constant uint& v_242BufferSize) +void Cmd_EndClip_write(thread const Alloc& a, thread const CmdRef& ref, thread const CmdEndClip& s, device Memory& v_260, constant uint& v_260BufferSize) { Alloc param = a; uint param_1 = ref.offset >> uint(2); - uint param_2 = 9u; - write_mem(param, param_1, param_2, v_242, v_242BufferSize); + uint param_2 = 10u; + write_mem(param, param_1, param_2, v_260, v_260BufferSize); Alloc param_3 = a; CmdEndClipRef param_4 = CmdEndClipRef{ ref.offset + 4u }; CmdEndClip param_5 = s; - CmdEndClip_write(param_3, param_4, param_5, v_242, v_242BufferSize); + CmdEndClip_write(param_3, param_4, param_5, v_260, v_260BufferSize); } static inline __attribute__((always_inline)) -void Cmd_End_write(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_242, constant uint& v_242BufferSize) +void Cmd_End_write(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_260, constant uint& v_260BufferSize) { Alloc param = a; uint param_1 = ref.offset >> uint(2); uint param_2 = 0u; - write_mem(param, param_1, param_2, v_242, v_242BufferSize); + write_mem(param, param_1, param_2, v_260, v_260BufferSize); } -kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device Memory& v_242 [[buffer(0)]], const device ConfigBuf& _854 [[buffer(1)]], const device SceneBuf& _1222 [[buffer(2)]], uint3 gl_WorkGroupID [[threadgroup_position_in_grid]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]]) +kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device Memory& v_260 [[buffer(0)]], const device ConfigBuf& _1005 [[buffer(1)]], const device SceneBuf& _1372 [[buffer(2)]], uint3 gl_WorkGroupID [[threadgroup_position_in_grid]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]]) { threadgroup uint sh_bitmaps[8][256]; threadgroup Alloc sh_part_elements[256]; @@ -611,76 +689,77 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M threadgroup uint sh_tile_y0[256]; threadgroup uint sh_tile_base[256]; threadgroup uint sh_tile_count[256]; - constant uint& v_242BufferSize = spvBufferSizeConstants[0]; - uint width_in_bins = ((_854.conf.width_in_tiles + 16u) - 1u) / 16u; + constant uint& v_260BufferSize = spvBufferSizeConstants[0]; + uint width_in_bins = ((_1005.conf.width_in_tiles + 16u) - 1u) / 16u; uint bin_ix = (width_in_bins * gl_WorkGroupID.y) + gl_WorkGroupID.x; uint partition_ix = 0u; - uint n_partitions = ((_854.conf.n_elements + 256u) - 1u) / 256u; + uint n_partitions = ((_1005.conf.n_elements + 256u) - 1u) / 256u; uint th_ix = gl_LocalInvocationID.x; uint bin_tile_x = 16u * gl_WorkGroupID.x; uint bin_tile_y = 16u * gl_WorkGroupID.y; uint tile_x = gl_LocalInvocationID.x % 16u; uint tile_y = gl_LocalInvocationID.x / 16u; - uint this_tile_ix = (((bin_tile_y + tile_y) * _854.conf.width_in_tiles) + bin_tile_x) + tile_x; + uint this_tile_ix = (((bin_tile_y + tile_y) * _1005.conf.width_in_tiles) + bin_tile_x) + tile_x; Alloc param; - param.offset = _854.conf.ptcl_alloc.offset; + param.offset = _1005.conf.ptcl_alloc.offset; uint param_1 = this_tile_ix * 1024u; uint param_2 = 1024u; Alloc cmd_alloc = slice_mem(param, param_1, param_2); CmdRef cmd_ref = CmdRef{ cmd_alloc.offset }; - uint cmd_limit = (cmd_ref.offset + 1024u) - 60u; + uint cmd_limit = (cmd_ref.offset + 1024u) - 144u; uint clip_depth = 0u; uint clip_zero_depth = 0u; uint rd_ix = 0u; uint wr_ix = 0u; uint part_start_ix = 0u; uint ready_ix = 0u; - uint drawmonoid_start = _854.conf.drawmonoid_alloc.offset >> uint(2); - uint drawtag_start = _854.conf.drawtag_offset >> uint(2); - uint drawdata_start = _854.conf.drawdata_offset >> uint(2); - uint drawinfo_start = _854.conf.drawinfo_alloc.offset >> uint(2); - bool mem_ok = v_242.mem_error == 0u; + uint drawmonoid_start = _1005.conf.drawmonoid_alloc.offset >> uint(2); + uint drawtag_start = _1005.conf.drawtag_offset >> uint(2); + uint drawdata_start = _1005.conf.drawdata_offset >> uint(2); + uint drawinfo_start = _1005.conf.drawinfo_alloc.offset >> uint(2); + bool mem_ok = v_260.mem_error == 0u; Alloc param_3; Alloc param_5; - uint _1154; + uint _1304; uint element_ix; Alloc param_14; uint tile_count; - uint _1455; + uint _1605; float linewidth; CmdLinGrad cmd_lin; + CmdRadGrad cmd_rad; while (true) { for (uint i = 0u; i < 8u; i++) { sh_bitmaps[i][th_ix] = 0u; } - bool _1206; + bool _1356; for (;;) { if ((ready_ix == wr_ix) && (partition_ix < n_partitions)) { part_start_ix = ready_ix; uint count = 0u; - bool _1003 = th_ix < 256u; - bool _1011; - if (_1003) + bool _1154 = th_ix < 256u; + bool _1162; + if (_1154) { - _1011 = (partition_ix + th_ix) < n_partitions; + _1162 = (partition_ix + th_ix) < n_partitions; } else { - _1011 = _1003; + _1162 = _1154; } - if (_1011) + if (_1162) { - uint in_ix = (_854.conf.bin_alloc.offset >> uint(2)) + ((((partition_ix + th_ix) * 256u) + bin_ix) * 2u); - param_3.offset = _854.conf.bin_alloc.offset; + uint in_ix = (_1005.conf.bin_alloc.offset >> uint(2)) + ((((partition_ix + th_ix) * 256u) + bin_ix) * 2u); + param_3.offset = _1005.conf.bin_alloc.offset; uint param_4 = in_ix; - count = read_mem(param_3, param_4, v_242, v_242BufferSize); - param_5.offset = _854.conf.bin_alloc.offset; + count = read_mem(param_3, param_4, v_260, v_260BufferSize); + param_5.offset = _1005.conf.bin_alloc.offset; uint param_6 = in_ix + 1u; - uint offset = read_mem(param_5, param_6, v_242, v_242BufferSize); + uint offset = read_mem(param_5, param_6, v_260, v_260BufferSize); uint param_7 = offset; uint param_8 = count * 4u; bool param_9 = mem_ok; @@ -724,34 +803,34 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M } if (part_ix > 0u) { - _1154 = sh_part_count[part_ix - 1u]; + _1304 = sh_part_count[part_ix - 1u]; } else { - _1154 = part_start_ix; + _1304 = part_start_ix; } - ix -= _1154; + ix -= _1304; Alloc bin_alloc = sh_part_elements[part_ix]; BinInstanceRef inst_ref = BinInstanceRef{ bin_alloc.offset }; BinInstanceRef param_10 = inst_ref; uint param_11 = ix; Alloc param_12 = bin_alloc; BinInstanceRef param_13 = BinInstance_index(param_10, param_11); - BinInstance inst = BinInstance_read(param_12, param_13, v_242, v_242BufferSize); + BinInstance inst = BinInstance_read(param_12, param_13, v_260, v_260BufferSize); sh_elements[th_ix] = inst.element_ix; } threadgroup_barrier(mem_flags::mem_threadgroup); wr_ix = min((rd_ix + 256u), ready_ix); - bool _1196 = (wr_ix - rd_ix) < 256u; - if (_1196) + bool _1346 = (wr_ix - rd_ix) < 256u; + if (_1346) { - _1206 = (wr_ix < ready_ix) || (partition_ix < n_partitions); + _1356 = (wr_ix < ready_ix) || (partition_ix < n_partitions); } else { - _1206 = _1196; + _1356 = _1346; } - if (_1206) + if (_1356) { continue; } @@ -764,21 +843,22 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M if ((th_ix + rd_ix) < wr_ix) { element_ix = sh_elements[th_ix]; - tag = _1222.scene[drawtag_start + element_ix]; + tag = _1372.scene[drawtag_start + element_ix]; } switch (tag) { case 68u: case 72u: case 276u: + case 732u: case 5u: case 37u: { uint drawmonoid_base = drawmonoid_start + (4u * element_ix); - uint path_ix = v_242.memory[drawmonoid_base]; - param_14.offset = _854.conf.tile_alloc.offset; - PathRef param_15 = PathRef{ _854.conf.tile_alloc.offset + (path_ix * 12u) }; - Path path = Path_read(param_14, param_15, v_242, v_242BufferSize); + uint path_ix = v_260.memory[drawmonoid_base]; + param_14.offset = _1005.conf.tile_alloc.offset; + PathRef param_15 = PathRef{ _1005.conf.tile_alloc.offset + (path_ix * 12u) }; + Path path = Path_read(param_14, param_15, v_260, v_260BufferSize); uint stride = path.bbox.z - path.bbox.x; sh_tile_stride[th_ix] = stride; int dx = int(path.bbox.x) - int(bin_tile_x); @@ -833,16 +913,16 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M } } uint element_ix_1 = sh_elements[el_ix]; - uint tag_1 = _1222.scene[drawtag_start + element_ix_1]; + uint tag_1 = _1372.scene[drawtag_start + element_ix_1]; if (el_ix > 0u) { - _1455 = sh_tile_count[el_ix - 1u]; + _1605 = sh_tile_count[el_ix - 1u]; } else { - _1455 = 0u; + _1605 = 0u; } - uint seq_ix = ix_1 - _1455; + uint seq_ix = ix_1 - _1605; uint width = sh_tile_width[el_ix]; uint x = sh_tile_x0[el_ix] + (seq_ix % width); uint y = sh_tile_y0[el_ix] + (seq_ix / width); @@ -851,36 +931,36 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M { uint param_21 = el_ix; bool param_22 = mem_ok; - Alloc param_23 = read_tile_alloc(param_21, param_22, v_242, v_242BufferSize); + Alloc param_23 = read_tile_alloc(param_21, param_22, v_260, v_260BufferSize); TileRef param_24 = TileRef{ sh_tile_base[el_ix] + (((sh_tile_stride[el_ix] * y) + x) * 8u) }; - Tile tile = Tile_read(param_23, param_24, v_242, v_242BufferSize); + Tile tile = Tile_read(param_23, param_24, v_260, v_260BufferSize); bool is_clip = (tag_1 & 1u) != 0u; bool is_blend = false; if (is_clip) { uint drawmonoid_base_1 = drawmonoid_start + (4u * element_ix_1); - uint scene_offset = v_242.memory[drawmonoid_base_1 + 2u]; + uint scene_offset = v_260.memory[drawmonoid_base_1 + 2u]; uint dd = drawdata_start + (scene_offset >> uint(2)); - uint blend = _1222.scene[dd]; + uint blend = _1372.scene[dd]; is_blend = blend != 3u; } - bool _1542 = tile.tile.offset != 0u; - bool _1551; - if (!_1542) + bool _1692 = tile.tile.offset != 0u; + bool _1701; + if (!_1692) { - _1551 = (tile.backdrop == 0) == is_clip; + _1701 = (tile.backdrop == 0) == is_clip; } else { - _1551 = _1542; + _1701 = _1692; } - include_tile = _1551 || is_blend; + include_tile = _1701 || is_blend; } if (include_tile) { uint el_slice = el_ix / 32u; uint el_mask = 1u << (el_ix & 31u); - uint _1573 = atomic_fetch_or_explicit((threadgroup atomic_uint*)&sh_bitmaps[el_slice][(y * 16u) + x], el_mask, memory_order_relaxed); + uint _1723 = atomic_fetch_or_explicit((threadgroup atomic_uint*)&sh_bitmaps[el_slice][(y * 16u) + x], el_mask, memory_order_relaxed); } } threadgroup_barrier(mem_flags::mem_threadgroup); @@ -904,32 +984,32 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M uint element_ref_ix = (slice_ix * 32u) + uint(int(spvFindLSB(bitmap))); uint element_ix_2 = sh_elements[element_ref_ix]; bitmap &= (bitmap - 1u); - uint drawtag = _1222.scene[drawtag_start + element_ix_2]; + uint drawtag = _1372.scene[drawtag_start + element_ix_2]; if (clip_zero_depth == 0u) { uint param_25 = element_ref_ix; bool param_26 = mem_ok; - Alloc param_27 = read_tile_alloc(param_25, param_26, v_242, v_242BufferSize); + Alloc param_27 = read_tile_alloc(param_25, param_26, v_260, v_260BufferSize); TileRef param_28 = TileRef{ sh_tile_base[element_ref_ix] + (((sh_tile_stride[element_ref_ix] * tile_y) + tile_x) * 8u) }; - Tile tile_1 = Tile_read(param_27, param_28, v_242, v_242BufferSize); + Tile tile_1 = Tile_read(param_27, param_28, v_260, v_260BufferSize); uint drawmonoid_base_2 = drawmonoid_start + (4u * element_ix_2); - uint scene_offset_1 = v_242.memory[drawmonoid_base_2 + 2u]; - uint info_offset = v_242.memory[drawmonoid_base_2 + 3u]; + uint scene_offset_1 = v_260.memory[drawmonoid_base_2 + 2u]; + uint info_offset = v_260.memory[drawmonoid_base_2 + 3u]; uint dd_1 = drawdata_start + (scene_offset_1 >> uint(2)); uint di = drawinfo_start + (info_offset >> uint(2)); switch (drawtag) { case 68u: { - linewidth = as_type(v_242.memory[di]); + linewidth = as_type(v_260.memory[di]); Alloc param_29 = cmd_alloc; CmdRef param_30 = cmd_ref; uint param_31 = cmd_limit; - bool _1697 = alloc_cmd(param_29, param_30, param_31, v_242, v_242BufferSize); + bool _1848 = alloc_cmd(param_29, param_30, param_31, v_260, v_260BufferSize); cmd_alloc = param_29; cmd_ref = param_30; cmd_limit = param_31; - if (!_1697) + if (!_1848) { break; } @@ -937,13 +1017,13 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M CmdRef param_33 = cmd_ref; Tile param_34 = tile_1; float param_35 = linewidth; - write_fill(param_32, param_33, param_34, param_35, v_242, v_242BufferSize); + write_fill(param_32, param_33, param_34, param_35, v_260, v_260BufferSize); cmd_ref = param_33; - uint rgba = _1222.scene[dd_1]; + uint rgba = _1372.scene[dd_1]; Alloc param_36 = cmd_alloc; CmdRef param_37 = cmd_ref; CmdColor param_38 = CmdColor{ rgba }; - Cmd_Color_write(param_36, param_37, param_38, v_242, v_242BufferSize); + Cmd_Color_write(param_36, param_37, param_38, v_260, v_260BufferSize); cmd_ref.offset += 8u; break; } @@ -952,94 +1032,127 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M Alloc param_39 = cmd_alloc; CmdRef param_40 = cmd_ref; uint param_41 = cmd_limit; - bool _1738 = alloc_cmd(param_39, param_40, param_41, v_242, v_242BufferSize); + bool _1889 = alloc_cmd(param_39, param_40, param_41, v_260, v_260BufferSize); cmd_alloc = param_39; cmd_ref = param_40; cmd_limit = param_41; - if (!_1738) + if (!_1889) { break; } - linewidth = as_type(v_242.memory[di]); + linewidth = as_type(v_260.memory[di]); Alloc param_42 = cmd_alloc; CmdRef param_43 = cmd_ref; Tile param_44 = tile_1; float param_45 = linewidth; - write_fill(param_42, param_43, param_44, param_45, v_242, v_242BufferSize); + write_fill(param_42, param_43, param_44, param_45, v_260, v_260BufferSize); cmd_ref = param_43; - cmd_lin.index = _1222.scene[dd_1]; - cmd_lin.line_x = as_type(v_242.memory[di + 1u]); - cmd_lin.line_y = as_type(v_242.memory[di + 2u]); - cmd_lin.line_c = as_type(v_242.memory[di + 3u]); + cmd_lin.index = _1372.scene[dd_1]; + cmd_lin.line_x = as_type(v_260.memory[di + 1u]); + cmd_lin.line_y = as_type(v_260.memory[di + 2u]); + cmd_lin.line_c = as_type(v_260.memory[di + 3u]); Alloc param_46 = cmd_alloc; CmdRef param_47 = cmd_ref; CmdLinGrad param_48 = cmd_lin; - Cmd_LinGrad_write(param_46, param_47, param_48, v_242, v_242BufferSize); + Cmd_LinGrad_write(param_46, param_47, param_48, v_260, v_260BufferSize); cmd_ref.offset += 20u; break; } - case 72u: + case 732u: { - linewidth = as_type(v_242.memory[di]); Alloc param_49 = cmd_alloc; CmdRef param_50 = cmd_ref; uint param_51 = cmd_limit; - bool _1806 = alloc_cmd(param_49, param_50, param_51, v_242, v_242BufferSize); + bool _1953 = alloc_cmd(param_49, param_50, param_51, v_260, v_260BufferSize); cmd_alloc = param_49; cmd_ref = param_50; cmd_limit = param_51; - if (!_1806) + if (!_1953) { break; } + linewidth = as_type(v_260.memory[di]); Alloc param_52 = cmd_alloc; CmdRef param_53 = cmd_ref; Tile param_54 = tile_1; float param_55 = linewidth; - write_fill(param_52, param_53, param_54, param_55, v_242, v_242BufferSize); + write_fill(param_52, param_53, param_54, param_55, v_260, v_260BufferSize); cmd_ref = param_53; - uint index = _1222.scene[dd_1]; - uint raw1 = _1222.scene[dd_1 + 1u]; - int2 offset_1 = int2(int(raw1 << uint(16)) >> 16, int(raw1) >> 16); + cmd_rad.index = _1372.scene[dd_1]; + cmd_rad.mat = as_type(uint4(v_260.memory[di + 1u], v_260.memory[di + 2u], v_260.memory[di + 3u], v_260.memory[di + 4u])); + cmd_rad.xlat = as_type(uint2(v_260.memory[di + 5u], v_260.memory[di + 6u])); + cmd_rad.c1 = as_type(uint2(v_260.memory[di + 7u], v_260.memory[di + 8u])); + cmd_rad.ra = as_type(v_260.memory[di + 9u]); + cmd_rad.roff = as_type(v_260.memory[di + 10u]); Alloc param_56 = cmd_alloc; CmdRef param_57 = cmd_ref; - CmdImage param_58 = CmdImage{ index, offset_1 }; - Cmd_Image_write(param_56, param_57, param_58, v_242, v_242BufferSize); + CmdRadGrad param_58 = cmd_rad; + Cmd_RadGrad_write(param_56, param_57, param_58, v_260, v_260BufferSize); + cmd_ref.offset += 48u; + break; + } + case 72u: + { + linewidth = as_type(v_260.memory[di]); + Alloc param_59 = cmd_alloc; + CmdRef param_60 = cmd_ref; + uint param_61 = cmd_limit; + bool _2059 = alloc_cmd(param_59, param_60, param_61, v_260, v_260BufferSize); + cmd_alloc = param_59; + cmd_ref = param_60; + cmd_limit = param_61; + if (!_2059) + { + break; + } + Alloc param_62 = cmd_alloc; + CmdRef param_63 = cmd_ref; + Tile param_64 = tile_1; + float param_65 = linewidth; + write_fill(param_62, param_63, param_64, param_65, v_260, v_260BufferSize); + cmd_ref = param_63; + uint index = _1372.scene[dd_1]; + uint raw1 = _1372.scene[dd_1 + 1u]; + int2 offset_1 = int2(int(raw1 << uint(16)) >> 16, int(raw1) >> 16); + Alloc param_66 = cmd_alloc; + CmdRef param_67 = cmd_ref; + CmdImage param_68 = CmdImage{ index, offset_1 }; + Cmd_Image_write(param_66, param_67, param_68, v_260, v_260BufferSize); cmd_ref.offset += 12u; break; } case 5u: { - bool _1859 = tile_1.tile.offset == 0u; - bool _1865; - if (_1859) + bool _2112 = tile_1.tile.offset == 0u; + bool _2118; + if (_2112) { - _1865 = tile_1.backdrop == 0; + _2118 = tile_1.backdrop == 0; } else { - _1865 = _1859; + _2118 = _2112; } - if (_1865) + if (_2118) { clip_zero_depth = clip_depth + 1u; } else { - Alloc param_59 = cmd_alloc; - CmdRef param_60 = cmd_ref; - uint param_61 = cmd_limit; - bool _1877 = alloc_cmd(param_59, param_60, param_61, v_242, v_242BufferSize); - cmd_alloc = param_59; - cmd_ref = param_60; - cmd_limit = param_61; - if (!_1877) + Alloc param_69 = cmd_alloc; + CmdRef param_70 = cmd_ref; + uint param_71 = cmd_limit; + bool _2130 = alloc_cmd(param_69, param_70, param_71, v_260, v_260BufferSize); + cmd_alloc = param_69; + cmd_ref = param_70; + cmd_limit = param_71; + if (!_2130) { break; } - Alloc param_62 = cmd_alloc; - CmdRef param_63 = cmd_ref; - Cmd_BeginClip_write(param_62, param_63, v_242, v_242BufferSize); + Alloc param_72 = cmd_alloc; + CmdRef param_73 = cmd_ref; + Cmd_BeginClip_write(param_72, param_73, v_260, v_260BufferSize); cmd_ref.offset += 4u; } clip_depth++; @@ -1048,28 +1161,28 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M case 37u: { clip_depth--; - Alloc param_64 = cmd_alloc; - CmdRef param_65 = cmd_ref; - uint param_66 = cmd_limit; - bool _1905 = alloc_cmd(param_64, param_65, param_66, v_242, v_242BufferSize); - cmd_alloc = param_64; - cmd_ref = param_65; - cmd_limit = param_66; - if (!_1905) + Alloc param_74 = cmd_alloc; + CmdRef param_75 = cmd_ref; + uint param_76 = cmd_limit; + bool _2158 = alloc_cmd(param_74, param_75, param_76, v_260, v_260BufferSize); + cmd_alloc = param_74; + cmd_ref = param_75; + cmd_limit = param_76; + if (!_2158) { break; } - Alloc param_67 = cmd_alloc; - CmdRef param_68 = cmd_ref; - Tile param_69 = tile_1; - float param_70 = -1.0; - write_fill(param_67, param_68, param_69, param_70, v_242, v_242BufferSize); - cmd_ref = param_68; - uint blend_1 = _1222.scene[dd_1]; - Alloc param_71 = cmd_alloc; - CmdRef param_72 = cmd_ref; - CmdEndClip param_73 = CmdEndClip{ blend_1 }; - Cmd_EndClip_write(param_71, param_72, param_73, v_242, v_242BufferSize); + Alloc param_77 = cmd_alloc; + CmdRef param_78 = cmd_ref; + Tile param_79 = tile_1; + float param_80 = -1.0; + write_fill(param_77, param_78, param_79, param_80, v_260, v_260BufferSize); + cmd_ref = param_78; + uint blend_1 = _1372.scene[dd_1]; + Alloc param_81 = cmd_alloc; + CmdRef param_82 = cmd_ref; + CmdEndClip param_83 = CmdEndClip{ blend_1 }; + Cmd_EndClip_write(param_81, param_82, param_83, v_260, v_260BufferSize); cmd_ref.offset += 8u; break; } @@ -1103,21 +1216,21 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M break; } } - bool _1975 = (bin_tile_x + tile_x) < _854.conf.width_in_tiles; - bool _1984; - if (_1975) + bool _2228 = (bin_tile_x + tile_x) < _1005.conf.width_in_tiles; + bool _2237; + if (_2228) { - _1984 = (bin_tile_y + tile_y) < _854.conf.height_in_tiles; + _2237 = (bin_tile_y + tile_y) < _1005.conf.height_in_tiles; } else { - _1984 = _1975; + _2237 = _2228; } - if (_1984) + if (_2237) { - Alloc param_74 = cmd_alloc; - CmdRef param_75 = cmd_ref; - Cmd_End_write(param_74, param_75, v_242, v_242BufferSize); + Alloc param_84 = cmd_alloc; + CmdRef param_85 = cmd_ref; + Cmd_End_write(param_84, param_85, v_260, v_260BufferSize); } } diff --git a/piet-gpu/shader/gen/coarse.spv b/piet-gpu/shader/gen/coarse.spv index b85fd8cd546262ba315eca88fc6be6357bb82392..6d33ee70c7b65cf2d8b8fef43e5b5ea63b20cbdf 100644 GIT binary patch literal 58852 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 literal 52244 zcmbWA2Y@A2wY3Ynd&oHlp-GaXWRT1ZIZG5K_CUkT^e};(bIw6BsN@Wiqh!nh5EKal zf}&ys5rzNz?yc2*x}H4WZ~d=4YpuP{KKtx*s&3s|&HNqHE-_tIO;gQSO*HCE9+Yt>=XvdvaaS9O6qImeIeouEDv^CZsM>90PA zA_0x**}?ytmi7rqCnFErX85q}w;#66=EFx%oH%^)ltah$3?J7!p=bD*-bp>9r}Q4w zqu=y}U+;v`d`N4a+qMGj)H8YNI7VoX z+nPVPWhyjlF?M9{xSlcg@2cj8kMB>UJ;q#U17pruEeM~|H+A%W!x?#*$x|jx9X(~m zjZJ>VsjIfKZ}*!Yzl>+D3&02FJyX>UKX_8_l%CIxLm}|7?-yvxSc||1Vs%uD!Velb z4&NE8rNEPVMvnR1u-J{c1Z^2}N%%m_nX2XClgIUr{?GY!RLdBP)40nHiqlywXPo{u z8&a(Z-=ufKmJ=pV898Be&rUsK+iRrmF_6Qo)oSpz=D_e_{Fy!Q}&=d9Kq>^t1LX83_6ulK;e$;X)H zvnFl3J{{Fs;N-S0c!!Zw_Ol3HA99a@8gy1)hVQ}_jgQ=;^w|Jz9ChQ!Jw}b{Vp==d&RfziId27S=RBm^7QE^BF*{G0 z)OSF8H@0(9_ZY~#tJ(qH?+Z3hH4k$qCuTjMoBw_z$Bi9+aPJsbr>mN;+7+!o#_-l1 z;B&WBzh9sXyACnkXFJnoj=O-{bL^oiX_0=@44pJ!QT(^{^9IjTCtUT5h1_9kZLw+}e;8xGF= zMzzP?v~OJBBq!+pQu7#?UsuH~-~3vB+FVODk4gKE8aaHl5v=Px)&6Ml{m+xh(2d!& ztu?Qys1oiJ?D$T6+uYRyO8qnwW){Nz~sw%4`wFo2%> zpS4hPy;`5|+#RC%JkZh(9ng4$Xls0cckv142kO8W|G5$ai8pFd8(iG6_5ZnvUE>28 zBXyzt{dKV>S>uD+d2Bg;#puGkY`tQJe)jh-}W5U zJVuS{nc$xGzH=(=fZu!&LL*za4tA=I1k*OLuYki zd)(H7n7`a(AphB_OX1`;oHG6A+=!GU-1}dnZ*sTq>Cudlk4n-+8O+z|N)p;rQQ--0sO7^D)&L`y0jB-z>(ywtwu|s+%%)-?-lYpGrEn z8;bZh_Q#*Qx}%QSx)uL7(`nqpZ!N~Tt$&=3>UMCuhVxhV)??PUy#Hp@&$(N+*YWNm zhi?@*+|!@KJk`T>4z1hKf0Mz#xsN?ijQe0Q?nC|K&R#tZcK>YBvv2PNZ)N}Yv0MA( zQTk_(J_gS9@Jt=Iz7_r7qYhjWgYIJPnJ0^}p6VZ~qk0pZ`UO70-RG{S}tjUDYe}rC0lV zKG5B9EO)>E?NK>{)|J_X2l5pQ-2PJH?Y8wm zIkxqA+*!Rz{MMXW<8@ZQqBYNUPMy_TaLYy0n#bF;$O3)&gzW@e{&G; zsNO01zCXy;S^d7j|IpwcHTcI3{*MNqhKsSh#yT3jv%zO+@Yx!C_CdU(niHNn%s

VEY4F1u{O|@pw!x2Y@Dm#R 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 E5B6kiRsaA1 diff --git a/piet-gpu/shader/gen/draw_leaf.dxil b/piet-gpu/shader/gen/draw_leaf.dxil index 77396c1d0bfd610df15affb66d2501573c7ca0d8..200f16962e12a1076fc8d560bcb58523676956d1 100644 GIT binary patch delta 4301 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 uint(4)) & 28u }; - return _75; + DrawMonoid _76 = { has_path, tag_word & 1u, tag_word & 28u, (tag_word >> uint(4)) & 60u }; + return _76; } DrawMonoid combine_draw_monoid(DrawMonoid a, DrawMonoid b) @@ -88,15 +88,15 @@ DrawMonoid draw_monoid_identity() void comp_main() { uint ix = gl_GlobalInvocationID.x * 8u; - uint drawtag_base = _92.Load(100) >> uint(2); - uint tag_word = _102.Load((drawtag_base + ix) * 4 + 0); + uint drawtag_base = _93.Load(100) >> uint(2); + uint tag_word = _103.Load((drawtag_base + ix) * 4 + 0); uint param = tag_word; DrawMonoid agg = map_tag(param); DrawMonoid local[8]; local[0] = agg; for (uint i = 1u; i < 8u; i++) { - tag_word = _102.Load(((drawtag_base + ix) + i) * 4 + 0); + tag_word = _103.Load(((drawtag_base + ix) + i) * 4 + 0); uint param_1 = tag_word; DrawMonoid param_2 = agg; DrawMonoid param_3 = map_tag(param_1); @@ -121,15 +121,15 @@ void comp_main() DrawMonoid row = draw_monoid_identity(); if (gl_WorkGroupID.x > 0u) { - DrawMonoid _208; - _208.path_ix = _202.Load((gl_WorkGroupID.x - 1u) * 16 + 0); - _208.clip_ix = _202.Load((gl_WorkGroupID.x - 1u) * 16 + 4); - _208.scene_offset = _202.Load((gl_WorkGroupID.x - 1u) * 16 + 8); - _208.info_offset = _202.Load((gl_WorkGroupID.x - 1u) * 16 + 12); - row.path_ix = _208.path_ix; - row.clip_ix = _208.clip_ix; - row.scene_offset = _208.scene_offset; - row.info_offset = _208.info_offset; + DrawMonoid _209; + _209.path_ix = _203.Load((gl_WorkGroupID.x - 1u) * 16 + 0); + _209.clip_ix = _203.Load((gl_WorkGroupID.x - 1u) * 16 + 4); + _209.scene_offset = _203.Load((gl_WorkGroupID.x - 1u) * 16 + 8); + _209.info_offset = _203.Load((gl_WorkGroupID.x - 1u) * 16 + 12); + row.path_ix = _209.path_ix; + row.clip_ix = _209.clip_ix; + row.scene_offset = _209.scene_offset; + row.info_offset = _209.info_offset; } if (gl_LocalInvocationID.x > 0u) { @@ -137,13 +137,15 @@ void comp_main() DrawMonoid param_7 = sh_scratch[gl_LocalInvocationID.x - 1u]; row = combine_draw_monoid(param_6, param_7); } - uint drawdata_base = _92.Load(104) >> uint(2); - uint drawinfo_base = _92.Load(68) >> uint(2); + uint drawdata_base = _93.Load(104) >> uint(2); + uint drawinfo_base = _93.Load(68) >> uint(2); uint out_ix = gl_GlobalInvocationID.x * 8u; - uint out_base = (_92.Load(44) >> uint(2)) + (out_ix * 4u); - uint clip_out_base = _92.Load(48) >> uint(2); + uint out_base = (_93.Load(44) >> uint(2)) + (out_ix * 4u); + uint clip_out_base = _93.Load(48) >> uint(2); float4 mat; float2 translate; + float2 p0; + float2 p1; for (uint i_2 = 0u; i_2 < 8u; i_2++) { DrawMonoid m = row; @@ -153,31 +155,31 @@ void comp_main() DrawMonoid param_9 = local[i_2 - 1u]; m = combine_draw_monoid(param_8, param_9); } - _284.Store((out_base + (i_2 * 4u)) * 4 + 8, m.path_ix); - _284.Store(((out_base + (i_2 * 4u)) + 1u) * 4 + 8, m.clip_ix); - _284.Store(((out_base + (i_2 * 4u)) + 2u) * 4 + 8, m.scene_offset); - _284.Store(((out_base + (i_2 * 4u)) + 3u) * 4 + 8, m.info_offset); + _285.Store((out_base + (i_2 * 4u)) * 4 + 8, m.path_ix); + _285.Store(((out_base + (i_2 * 4u)) + 1u) * 4 + 8, m.clip_ix); + _285.Store(((out_base + (i_2 * 4u)) + 2u) * 4 + 8, m.scene_offset); + _285.Store(((out_base + (i_2 * 4u)) + 3u) * 4 + 8, m.info_offset); uint dd = drawdata_base + (m.scene_offset >> uint(2)); uint di = drawinfo_base + (m.info_offset >> uint(2)); - tag_word = _102.Load(((drawtag_base + ix) + i_2) * 4 + 0); - if ((((tag_word == 68u) || (tag_word == 276u)) || (tag_word == 72u)) || (tag_word == 5u)) + tag_word = _103.Load(((drawtag_base + ix) + i_2) * 4 + 0); + if (((((tag_word == 68u) || (tag_word == 276u)) || (tag_word == 732u)) || (tag_word == 72u)) || (tag_word == 5u)) { - uint bbox_offset = (_92.Load(40) >> uint(2)) + (6u * m.path_ix); - float bbox_l = float(_284.Load(bbox_offset * 4 + 8)) - 32768.0f; - float bbox_t = float(_284.Load((bbox_offset + 1u) * 4 + 8)) - 32768.0f; - float bbox_r = float(_284.Load((bbox_offset + 2u) * 4 + 8)) - 32768.0f; - float bbox_b = float(_284.Load((bbox_offset + 3u) * 4 + 8)) - 32768.0f; + uint bbox_offset = (_93.Load(40) >> uint(2)) + (6u * m.path_ix); + float bbox_l = float(_285.Load(bbox_offset * 4 + 8)) - 32768.0f; + float bbox_t = float(_285.Load((bbox_offset + 1u) * 4 + 8)) - 32768.0f; + float bbox_r = float(_285.Load((bbox_offset + 2u) * 4 + 8)) - 32768.0f; + float bbox_b = float(_285.Load((bbox_offset + 3u) * 4 + 8)) - 32768.0f; float4 bbox = float4(bbox_l, bbox_t, bbox_r, bbox_b); - float linewidth = asfloat(_284.Load((bbox_offset + 4u) * 4 + 8)); + float linewidth = asfloat(_285.Load((bbox_offset + 4u) * 4 + 8)); uint fill_mode = uint(linewidth >= 0.0f); - if ((linewidth >= 0.0f) || (tag_word == 276u)) + if (((linewidth >= 0.0f) || (tag_word == 276u)) || (tag_word == 732u)) { - uint trans_ix = _284.Load((bbox_offset + 5u) * 4 + 8); - uint t = (_92.Load(36) >> uint(2)) + (6u * trans_ix); - mat = asfloat(uint4(_284.Load(t * 4 + 8), _284.Load((t + 1u) * 4 + 8), _284.Load((t + 2u) * 4 + 8), _284.Load((t + 3u) * 4 + 8))); - if (tag_word == 276u) + uint trans_ix = _285.Load((bbox_offset + 5u) * 4 + 8); + uint t = (_93.Load(36) >> uint(2)) + (6u * trans_ix); + mat = asfloat(uint4(_285.Load(t * 4 + 8), _285.Load((t + 1u) * 4 + 8), _285.Load((t + 2u) * 4 + 8), _285.Load((t + 3u) * 4 + 8))); + if ((tag_word == 276u) || (tag_word == 732u)) { - translate = asfloat(uint2(_284.Load((t + 4u) * 4 + 8), _284.Load((t + 5u) * 4 + 8))); + translate = asfloat(uint2(_285.Load((t + 4u) * 4 + 8), _285.Load((t + 5u) * 4 + 8))); } } if (linewidth >= 0.0f) @@ -189,15 +191,14 @@ void comp_main() case 68u: case 72u: { - _284.Store(di * 4 + 8, asuint(linewidth)); + _285.Store(di * 4 + 8, asuint(linewidth)); break; } case 276u: { - _284.Store(di * 4 + 8, asuint(linewidth)); - uint index = _102.Load(dd * 4 + 0); - float2 p0 = asfloat(uint2(_102.Load((dd + 1u) * 4 + 0), _102.Load((dd + 2u) * 4 + 0))); - float2 p1 = asfloat(uint2(_102.Load((dd + 3u) * 4 + 0), _102.Load((dd + 4u) * 4 + 0))); + _285.Store(di * 4 + 8, asuint(linewidth)); + p0 = asfloat(uint2(_103.Load((dd + 1u) * 4 + 0), _103.Load((dd + 2u) * 4 + 0))); + p1 = asfloat(uint2(_103.Load((dd + 3u) * 4 + 0), _103.Load((dd + 4u) * 4 + 0))); p0 = ((mat.xy * p0.x) + (mat.zw * p0.y)) + translate; p1 = ((mat.xy * p1.x) + (mat.zw * p1.y)) + translate; float2 dxy = p1 - p0; @@ -205,9 +206,38 @@ void comp_main() float line_x = dxy.x * scale; float line_y = dxy.y * scale; float line_c = -((p0.x * line_x) + (p0.y * line_y)); - _284.Store((di + 1u) * 4 + 8, asuint(line_x)); - _284.Store((di + 2u) * 4 + 8, asuint(line_y)); - _284.Store((di + 3u) * 4 + 8, asuint(line_c)); + _285.Store((di + 1u) * 4 + 8, asuint(line_x)); + _285.Store((di + 2u) * 4 + 8, asuint(line_y)); + _285.Store((di + 3u) * 4 + 8, asuint(line_c)); + break; + } + case 732u: + { + p0 = asfloat(uint2(_103.Load((dd + 1u) * 4 + 0), _103.Load((dd + 2u) * 4 + 0))); + p1 = asfloat(uint2(_103.Load((dd + 3u) * 4 + 0), _103.Load((dd + 4u) * 4 + 0))); + float r0 = asfloat(_103.Load((dd + 5u) * 4 + 0)); + float r1 = asfloat(_103.Load((dd + 6u) * 4 + 0)); + float inv_det = 1.0f / ((mat.x * mat.w) - (mat.y * mat.z)); + float4 inv_mat = float4(mat.w, -mat.y, -mat.z, mat.x) * inv_det; + float2 inv_tr = (inv_mat.xz * translate.x) + (inv_mat.yw * translate.y); + inv_tr += p0; + float2 center1 = p1 - p0; + float rr = r1 / (r1 - r0); + float rainv = rr / ((r1 * r1) - dot(center1, center1)); + float2 c1 = center1 * rainv; + float ra = rr * rainv; + float roff = rr - 1.0f; + _285.Store(di * 4 + 8, asuint(linewidth)); + _285.Store((di + 1u) * 4 + 8, asuint(inv_mat.x)); + _285.Store((di + 2u) * 4 + 8, asuint(inv_mat.y)); + _285.Store((di + 3u) * 4 + 8, asuint(inv_mat.z)); + _285.Store((di + 4u) * 4 + 8, asuint(inv_mat.w)); + _285.Store((di + 5u) * 4 + 8, asuint(inv_tr.x)); + _285.Store((di + 6u) * 4 + 8, asuint(inv_tr.y)); + _285.Store((di + 7u) * 4 + 8, asuint(c1.x)); + _285.Store((di + 8u) * 4 + 8, asuint(c1.y)); + _285.Store((di + 9u) * 4 + 8, asuint(ra)); + _285.Store((di + 10u) * 4 + 8, asuint(roff)); break; } case 5u: @@ -223,7 +253,7 @@ void comp_main() { path_ix = m.path_ix; } - _284.Store((clip_out_base + m.clip_ix) * 4 + 8, path_ix); + _285.Store((clip_out_base + m.clip_ix) * 4 + 8, path_ix); } } } diff --git a/piet-gpu/shader/gen/draw_leaf.msl b/piet-gpu/shader/gen/draw_leaf.msl index a8516ae..c11e21b 100644 --- a/piet-gpu/shader/gen/draw_leaf.msl +++ b/piet-gpu/shader/gen/draw_leaf.msl @@ -124,7 +124,7 @@ static inline __attribute__((always_inline)) DrawMonoid map_tag(thread const uint& tag_word) { uint has_path = uint(tag_word != 0u); - return DrawMonoid{ has_path, tag_word & 1u, tag_word & 28u, (tag_word >> uint(4)) & 28u }; + return DrawMonoid{ has_path, tag_word & 1u, tag_word & 28u, (tag_word >> uint(4)) & 60u }; } static inline __attribute__((always_inline)) @@ -144,19 +144,19 @@ DrawMonoid draw_monoid_identity() return DrawMonoid{ 0u, 0u, 0u, 0u }; } -kernel void main0(device Memory& _284 [[buffer(0)]], const device ConfigBuf& _92 [[buffer(1)]], const device SceneBuf& _102 [[buffer(2)]], const device ParentBuf& _202 [[buffer(3)]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]], uint3 gl_WorkGroupID [[threadgroup_position_in_grid]]) +kernel void main0(device Memory& _285 [[buffer(0)]], const device ConfigBuf& _93 [[buffer(1)]], const device SceneBuf& _103 [[buffer(2)]], const device ParentBuf& _203 [[buffer(3)]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]], uint3 gl_WorkGroupID [[threadgroup_position_in_grid]]) { threadgroup DrawMonoid sh_scratch[256]; uint ix = gl_GlobalInvocationID.x * 8u; - uint drawtag_base = _92.conf.drawtag_offset >> uint(2); - uint tag_word = _102.scene[drawtag_base + ix]; + uint drawtag_base = _93.conf.drawtag_offset >> uint(2); + uint tag_word = _103.scene[drawtag_base + ix]; uint param = tag_word; DrawMonoid agg = map_tag(param); spvUnsafeArray local; local[0] = agg; for (uint i = 1u; i < 8u; i++) { - tag_word = _102.scene[(drawtag_base + ix) + i]; + tag_word = _103.scene[(drawtag_base + ix) + i]; uint param_1 = tag_word; DrawMonoid param_2 = agg; DrawMonoid param_3 = map_tag(param_1); @@ -181,11 +181,11 @@ kernel void main0(device Memory& _284 [[buffer(0)]], const device ConfigBuf& _92 DrawMonoid row = draw_monoid_identity(); if (gl_WorkGroupID.x > 0u) { - uint _205 = gl_WorkGroupID.x - 1u; - row.path_ix = _202.parent[_205].path_ix; - row.clip_ix = _202.parent[_205].clip_ix; - row.scene_offset = _202.parent[_205].scene_offset; - row.info_offset = _202.parent[_205].info_offset; + uint _206 = gl_WorkGroupID.x - 1u; + row.path_ix = _203.parent[_206].path_ix; + row.clip_ix = _203.parent[_206].clip_ix; + row.scene_offset = _203.parent[_206].scene_offset; + row.info_offset = _203.parent[_206].info_offset; } if (gl_LocalInvocationID.x > 0u) { @@ -193,13 +193,15 @@ kernel void main0(device Memory& _284 [[buffer(0)]], const device ConfigBuf& _92 DrawMonoid param_7 = sh_scratch[gl_LocalInvocationID.x - 1u]; row = combine_draw_monoid(param_6, param_7); } - uint drawdata_base = _92.conf.drawdata_offset >> uint(2); - uint drawinfo_base = _92.conf.drawinfo_alloc.offset >> uint(2); + uint drawdata_base = _93.conf.drawdata_offset >> uint(2); + uint drawinfo_base = _93.conf.drawinfo_alloc.offset >> uint(2); uint out_ix = gl_GlobalInvocationID.x * 8u; - uint out_base = (_92.conf.drawmonoid_alloc.offset >> uint(2)) + (out_ix * 4u); - uint clip_out_base = _92.conf.clip_alloc.offset >> uint(2); + uint out_base = (_93.conf.drawmonoid_alloc.offset >> uint(2)) + (out_ix * 4u); + uint clip_out_base = _93.conf.clip_alloc.offset >> uint(2); float4 mat; float2 translate; + float2 p0; + float2 p1; for (uint i_2 = 0u; i_2 < 8u; i_2++) { DrawMonoid m = row; @@ -209,31 +211,31 @@ kernel void main0(device Memory& _284 [[buffer(0)]], const device ConfigBuf& _92 DrawMonoid param_9 = local[i_2 - 1u]; m = combine_draw_monoid(param_8, param_9); } - _284.memory[out_base + (i_2 * 4u)] = m.path_ix; - _284.memory[(out_base + (i_2 * 4u)) + 1u] = m.clip_ix; - _284.memory[(out_base + (i_2 * 4u)) + 2u] = m.scene_offset; - _284.memory[(out_base + (i_2 * 4u)) + 3u] = m.info_offset; + _285.memory[out_base + (i_2 * 4u)] = m.path_ix; + _285.memory[(out_base + (i_2 * 4u)) + 1u] = m.clip_ix; + _285.memory[(out_base + (i_2 * 4u)) + 2u] = m.scene_offset; + _285.memory[(out_base + (i_2 * 4u)) + 3u] = m.info_offset; uint dd = drawdata_base + (m.scene_offset >> uint(2)); uint di = drawinfo_base + (m.info_offset >> uint(2)); - tag_word = _102.scene[(drawtag_base + ix) + i_2]; - if ((((tag_word == 68u) || (tag_word == 276u)) || (tag_word == 72u)) || (tag_word == 5u)) + tag_word = _103.scene[(drawtag_base + ix) + i_2]; + if (((((tag_word == 68u) || (tag_word == 276u)) || (tag_word == 732u)) || (tag_word == 72u)) || (tag_word == 5u)) { - uint bbox_offset = (_92.conf.path_bbox_alloc.offset >> uint(2)) + (6u * m.path_ix); - float bbox_l = float(_284.memory[bbox_offset]) - 32768.0; - float bbox_t = float(_284.memory[bbox_offset + 1u]) - 32768.0; - float bbox_r = float(_284.memory[bbox_offset + 2u]) - 32768.0; - float bbox_b = float(_284.memory[bbox_offset + 3u]) - 32768.0; + uint bbox_offset = (_93.conf.path_bbox_alloc.offset >> uint(2)) + (6u * m.path_ix); + float bbox_l = float(_285.memory[bbox_offset]) - 32768.0; + float bbox_t = float(_285.memory[bbox_offset + 1u]) - 32768.0; + float bbox_r = float(_285.memory[bbox_offset + 2u]) - 32768.0; + float bbox_b = float(_285.memory[bbox_offset + 3u]) - 32768.0; float4 bbox = float4(bbox_l, bbox_t, bbox_r, bbox_b); - float linewidth = as_type(_284.memory[bbox_offset + 4u]); + float linewidth = as_type(_285.memory[bbox_offset + 4u]); uint fill_mode = uint(linewidth >= 0.0); - if ((linewidth >= 0.0) || (tag_word == 276u)) + if (((linewidth >= 0.0) || (tag_word == 276u)) || (tag_word == 732u)) { - uint trans_ix = _284.memory[bbox_offset + 5u]; - uint t = (_92.conf.trans_alloc.offset >> uint(2)) + (6u * trans_ix); - mat = as_type(uint4(_284.memory[t], _284.memory[t + 1u], _284.memory[t + 2u], _284.memory[t + 3u])); - if (tag_word == 276u) + uint trans_ix = _285.memory[bbox_offset + 5u]; + uint t = (_93.conf.trans_alloc.offset >> uint(2)) + (6u * trans_ix); + mat = as_type(uint4(_285.memory[t], _285.memory[t + 1u], _285.memory[t + 2u], _285.memory[t + 3u])); + if ((tag_word == 276u) || (tag_word == 732u)) { - translate = as_type(uint2(_284.memory[t + 4u], _284.memory[t + 5u])); + translate = as_type(uint2(_285.memory[t + 4u], _285.memory[t + 5u])); } } if (linewidth >= 0.0) @@ -245,15 +247,14 @@ kernel void main0(device Memory& _284 [[buffer(0)]], const device ConfigBuf& _92 case 68u: case 72u: { - _284.memory[di] = as_type(linewidth); + _285.memory[di] = as_type(linewidth); break; } case 276u: { - _284.memory[di] = as_type(linewidth); - uint index = _102.scene[dd]; - float2 p0 = as_type(uint2(_102.scene[dd + 1u], _102.scene[dd + 2u])); - float2 p1 = as_type(uint2(_102.scene[dd + 3u], _102.scene[dd + 4u])); + _285.memory[di] = as_type(linewidth); + p0 = as_type(uint2(_103.scene[dd + 1u], _103.scene[dd + 2u])); + p1 = as_type(uint2(_103.scene[dd + 3u], _103.scene[dd + 4u])); p0 = ((mat.xy * p0.x) + (mat.zw * p0.y)) + translate; p1 = ((mat.xy * p1.x) + (mat.zw * p1.y)) + translate; float2 dxy = p1 - p0; @@ -261,9 +262,38 @@ kernel void main0(device Memory& _284 [[buffer(0)]], const device ConfigBuf& _92 float line_x = dxy.x * scale; float line_y = dxy.y * scale; float line_c = -((p0.x * line_x) + (p0.y * line_y)); - _284.memory[di + 1u] = as_type(line_x); - _284.memory[di + 2u] = as_type(line_y); - _284.memory[di + 3u] = as_type(line_c); + _285.memory[di + 1u] = as_type(line_x); + _285.memory[di + 2u] = as_type(line_y); + _285.memory[di + 3u] = as_type(line_c); + break; + } + case 732u: + { + p0 = as_type(uint2(_103.scene[dd + 1u], _103.scene[dd + 2u])); + p1 = as_type(uint2(_103.scene[dd + 3u], _103.scene[dd + 4u])); + float r0 = as_type(_103.scene[dd + 5u]); + float r1 = as_type(_103.scene[dd + 6u]); + float inv_det = 1.0 / ((mat.x * mat.w) - (mat.y * mat.z)); + float4 inv_mat = float4(mat.w, -mat.y, -mat.z, mat.x) * inv_det; + float2 inv_tr = (inv_mat.xz * translate.x) + (inv_mat.yw * translate.y); + inv_tr += p0; + float2 center1 = p1 - p0; + float rr = r1 / (r1 - r0); + float rainv = rr / ((r1 * r1) - dot(center1, center1)); + float2 c1 = center1 * rainv; + float ra = rr * rainv; + float roff = rr - 1.0; + _285.memory[di] = as_type(linewidth); + _285.memory[di + 1u] = as_type(inv_mat.x); + _285.memory[di + 2u] = as_type(inv_mat.y); + _285.memory[di + 3u] = as_type(inv_mat.z); + _285.memory[di + 4u] = as_type(inv_mat.w); + _285.memory[di + 5u] = as_type(inv_tr.x); + _285.memory[di + 6u] = as_type(inv_tr.y); + _285.memory[di + 7u] = as_type(c1.x); + _285.memory[di + 8u] = as_type(c1.y); + _285.memory[di + 9u] = as_type(ra); + _285.memory[di + 10u] = as_type(roff); break; } case 5u: @@ -279,7 +309,7 @@ kernel void main0(device Memory& _284 [[buffer(0)]], const device ConfigBuf& _92 { path_ix = m.path_ix; } - _284.memory[clip_out_base + m.clip_ix] = path_ix; + _285.memory[clip_out_base + m.clip_ix] = path_ix; } } } diff --git a/piet-gpu/shader/gen/draw_leaf.spv b/piet-gpu/shader/gen/draw_leaf.spv index d18b2877431a9e97c53c8343f35149e714cb73b8..58dde4387fddb65154909ba8a846f351b6115758 100644 GIT binary patch literal 20104 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 diff --git a/piet-gpu/shader/gen/draw_reduce.dxil b/piet-gpu/shader/gen/draw_reduce.dxil index 4df0ec51bdaf0e94f98038ec143b59dbf32c351f..be69aad2781f64f94fa4a1d109e7b980e3bf0fdb 100644 GIT binary patch delta 782 zcmZ8fO-vI(7@ci*m+fpRE3h~P4%_e}B7s&46@%IWA%PfDlZu6yxLdJ$G8{-STEq5_ zG!;lS_!m%@K!PzI3iZIBWC24+jEIIqJtz$-CY&H%O!VNc;6W#uFZ14;Z{C~CNTxB9 zvB6zezg>Cr%B9g3V-rRiFa72XfZDvwy0(bGQ{vLO)i*dMRu=|0 znYS_{lOz6O>ORu?8cCAl4VXEUukeRogSnB-~j=OGytd= zD91C3gHPe>>g7)+JplO$3-y!e8CK{lys1o;b;`uOpxGjQffk8_<2%qQ6-I4RmloDY zJ}nHobbZR60#XM8d`k2ebfPLx3~&_Lf@%ZfXZM8&X1(^L%EPO|vaw_%;>Sb|A+IDl zh>!h<1607_BC{skqq-i<=|DVzyUe7`BdQIzbNS|Ye=#n1*2hSp6N}^~?YELIpjC#) z9u-k!DIk6X{Lqfg^OD9XR-mVVNzn@31?Hv4pfncDv)BQH2TL+mIeMM9nm})!rj`oQ z_VsvLdnoq`+by!s{jIxpHpA7kYd?^Ytb}HCmD&P&uQ9|Si&<&cUSyMEb}Q-_$quk& zo0$;8j+_?3EyM^H*PBjxjH00RI7vP!GIuak&1pJ-SJ&%@a^`zU$y8=akNyYjheFnp zM!g>33*ce+#9HurIMq|?=BG?f;^>1*T$B$l9P~Kc!Vb}fT9Hr4iLm4aDIB285fD_% zC`Cm@NiF<6)r8TcD~`al#{UcUZtyDq{0OT=9YAW-JT>ZCNR2wlgTBl(q_^RdK0qe) z%Z%RU`>d|gGF^v%E%qa;@xopa%im=sfb zrH89%S(~mpQk^ka)39$fqdw+G007FP^myF*!Y6~W%p|TUBJia6{OpaFI3gD11lFn7 zDy0%b(joFg)p{=R#Wz`x-^WT07?rzrzJTiedBHq0QvJ2kQ*)w+1b_!Rkb?rCVF1@t z(7_LRu0s7}G60Y{nNR-Gb=`q>(j!O0AdZA|}!b!U>V`bWy-KC&90XWDhcMkcPqPoB^+bP6P`r|ARs5 ztwQJ90fl3gsXy4g3r2aoi=bA^p>n}R(wi~qPFOa^-L`O*e<_ZvL;*cC*lTY+dy;s p*uQ*oDU{*U;-+ld> uint(4)) & 28u }; - return _69; + DrawMonoid _70 = { has_path, tag_word & 1u, tag_word & 28u, (tag_word >> uint(4)) & 60u }; + return _70; } DrawMonoid combine_draw_monoid(DrawMonoid a, DrawMonoid b) @@ -81,13 +81,13 @@ DrawMonoid combine_draw_monoid(DrawMonoid a, DrawMonoid b) void comp_main() { uint ix = gl_GlobalInvocationID.x * 8u; - uint drawtag_base = _86.Load(100) >> uint(2); - uint tag_word = _96.Load((drawtag_base + ix) * 4 + 0); + uint drawtag_base = _87.Load(100) >> uint(2); + uint tag_word = _97.Load((drawtag_base + ix) * 4 + 0); uint param = tag_word; DrawMonoid agg = map_tag(param); for (uint i = 1u; i < 8u; i++) { - uint tag_word_1 = _96.Load(((drawtag_base + ix) + i) * 4 + 0); + uint tag_word_1 = _97.Load(((drawtag_base + ix) + i) * 4 + 0); uint param_1 = tag_word_1; DrawMonoid param_2 = agg; DrawMonoid param_3 = map_tag(param_1); @@ -109,10 +109,10 @@ void comp_main() } if (gl_LocalInvocationID.x == 0u) { - _187.Store(gl_WorkGroupID.x * 16 + 0, agg.path_ix); - _187.Store(gl_WorkGroupID.x * 16 + 4, agg.clip_ix); - _187.Store(gl_WorkGroupID.x * 16 + 8, agg.scene_offset); - _187.Store(gl_WorkGroupID.x * 16 + 12, agg.info_offset); + _188.Store(gl_WorkGroupID.x * 16 + 0, agg.path_ix); + _188.Store(gl_WorkGroupID.x * 16 + 4, agg.clip_ix); + _188.Store(gl_WorkGroupID.x * 16 + 8, agg.scene_offset); + _188.Store(gl_WorkGroupID.x * 16 + 12, agg.info_offset); } } diff --git a/piet-gpu/shader/gen/draw_reduce.msl b/piet-gpu/shader/gen/draw_reduce.msl index 8e409a8..759267c 100644 --- a/piet-gpu/shader/gen/draw_reduce.msl +++ b/piet-gpu/shader/gen/draw_reduce.msl @@ -85,7 +85,7 @@ static inline __attribute__((always_inline)) DrawMonoid map_tag(thread const uint& tag_word) { uint has_path = uint(tag_word != 0u); - return DrawMonoid{ has_path, tag_word & 1u, tag_word & 28u, (tag_word >> uint(4)) & 28u }; + return DrawMonoid{ has_path, tag_word & 1u, tag_word & 28u, (tag_word >> uint(4)) & 60u }; } static inline __attribute__((always_inline)) @@ -99,17 +99,17 @@ DrawMonoid combine_draw_monoid(thread const DrawMonoid& a, thread const DrawMono return c; } -kernel void main0(const device ConfigBuf& _86 [[buffer(1)]], const device SceneBuf& _96 [[buffer(2)]], device OutBuf& _187 [[buffer(3)]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]], uint3 gl_WorkGroupID [[threadgroup_position_in_grid]]) +kernel void main0(const device ConfigBuf& _87 [[buffer(1)]], const device SceneBuf& _97 [[buffer(2)]], device OutBuf& _188 [[buffer(3)]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]], uint3 gl_WorkGroupID [[threadgroup_position_in_grid]]) { threadgroup DrawMonoid sh_scratch[256]; uint ix = gl_GlobalInvocationID.x * 8u; - uint drawtag_base = _86.conf.drawtag_offset >> uint(2); - uint tag_word = _96.scene[drawtag_base + ix]; + uint drawtag_base = _87.conf.drawtag_offset >> uint(2); + uint tag_word = _97.scene[drawtag_base + ix]; uint param = tag_word; DrawMonoid agg = map_tag(param); for (uint i = 1u; i < 8u; i++) { - uint tag_word_1 = _96.scene[(drawtag_base + ix) + i]; + uint tag_word_1 = _97.scene[(drawtag_base + ix) + i]; uint param_1 = tag_word_1; DrawMonoid param_2 = agg; DrawMonoid param_3 = map_tag(param_1); @@ -131,10 +131,10 @@ kernel void main0(const device ConfigBuf& _86 [[buffer(1)]], const device SceneB } if (gl_LocalInvocationID.x == 0u) { - _187.outbuf[gl_WorkGroupID.x].path_ix = agg.path_ix; - _187.outbuf[gl_WorkGroupID.x].clip_ix = agg.clip_ix; - _187.outbuf[gl_WorkGroupID.x].scene_offset = agg.scene_offset; - _187.outbuf[gl_WorkGroupID.x].info_offset = agg.info_offset; + _188.outbuf[gl_WorkGroupID.x].path_ix = agg.path_ix; + _188.outbuf[gl_WorkGroupID.x].clip_ix = agg.clip_ix; + _188.outbuf[gl_WorkGroupID.x].scene_offset = agg.scene_offset; + _188.outbuf[gl_WorkGroupID.x].info_offset = agg.info_offset; } } diff --git a/piet-gpu/shader/gen/draw_reduce.spv b/piet-gpu/shader/gen/draw_reduce.spv index 4daf43af5dd87dfacfc4f1c5727b15274bdd4266..d6c6fb75fa1dc5d7d65bfa5c1ab890d474b0ee68 100644 GIT binary patch literal 7140 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 T+~3O~YjWLfkUsWJ+`j!AnWXVL literal 7124 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 O^WF$)W8cK>+kXJO$?lT? diff --git a/piet-gpu/shader/gen/kernel4.dxil b/piet-gpu/shader/gen/kernel4.dxil index c0c27c9109628203e890e8e82c8e455a8a8f5520..e6eccc19bc027f132723e05d38b856f586d013b8 100644 GIT binary patch delta 10511 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 LWca6bp1=PGEGgkJ delta 9662 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 image_atlas : register(u3, space0); RWTexture2D gradients : register(u4, space0); RWTexture2D image : register(u2, space0); @@ -174,8 +189,8 @@ float4 spvUnpackUnorm4x8(uint value) Alloc slice_mem(Alloc a, uint offset, uint size) { - Alloc _291 = { a.offset + offset }; - return _291; + Alloc _304 = { a.offset + offset }; + return _304; } bool touch_mem(Alloc alloc, uint offset) @@ -191,7 +206,7 @@ uint read_mem(Alloc alloc, uint offset) { return 0u; } - uint v = _278.Load(offset * 4 + 8); + uint v = _291.Load(offset * 4 + 8); return v; } @@ -200,8 +215,8 @@ CmdTag Cmd_tag(Alloc a, CmdRef ref) Alloc param = a; uint param_1 = ref.offset >> uint(2); uint tag_and_flags = read_mem(param, param_1); - CmdTag _525 = { tag_and_flags & 65535u, tag_and_flags >> uint(16) }; - return _525; + CmdTag _663 = { tag_and_flags & 65535u, tag_and_flags >> uint(16) }; + return _663; } CmdStroke CmdStroke_read(Alloc a, CmdStrokeRef ref) @@ -221,9 +236,9 @@ CmdStroke CmdStroke_read(Alloc a, CmdStrokeRef ref) CmdStroke Cmd_Stroke_read(Alloc a, CmdRef ref) { - CmdStrokeRef _542 = { ref.offset + 4u }; + CmdStrokeRef _679 = { ref.offset + 4u }; Alloc param = a; - CmdStrokeRef param_1 = _542; + CmdStrokeRef param_1 = _679; return CmdStroke_read(param, param_1); } @@ -259,8 +274,8 @@ TileSeg TileSeg_read(Alloc a, TileSegRef ref) s.origin = float2(asfloat(raw0), asfloat(raw1)); s._vector = float2(asfloat(raw2), asfloat(raw3)); s.y_edge = asfloat(raw4); - TileSegRef _675 = { raw5 }; - s.next = _675; + TileSegRef _820 = { raw5 }; + s.next = _820; return s; } @@ -286,9 +301,9 @@ CmdFill CmdFill_read(Alloc a, CmdFillRef ref) CmdFill Cmd_Fill_read(Alloc a, CmdRef ref) { - CmdFillRef _532 = { ref.offset + 4u }; + CmdFillRef _669 = { ref.offset + 4u }; Alloc param = a; - CmdFillRef param_1 = _532; + CmdFillRef param_1 = _669; return CmdFill_read(param, param_1); } @@ -305,9 +320,9 @@ CmdAlpha CmdAlpha_read(Alloc a, CmdAlphaRef ref) CmdAlpha Cmd_Alpha_read(Alloc a, CmdRef ref) { - CmdAlphaRef _552 = { ref.offset + 4u }; + CmdAlphaRef _689 = { ref.offset + 4u }; Alloc param = a; - CmdAlphaRef param_1 = _552; + CmdAlphaRef param_1 = _689; return CmdAlpha_read(param, param_1); } @@ -324,9 +339,9 @@ CmdColor CmdColor_read(Alloc a, CmdColorRef ref) CmdColor Cmd_Color_read(Alloc a, CmdRef ref) { - CmdColorRef _562 = { ref.offset + 4u }; + CmdColorRef _699 = { ref.offset + 4u }; Alloc param = a; - CmdColorRef param_1 = _562; + CmdColorRef param_1 = _699; return CmdColor_read(param, param_1); } @@ -370,12 +385,66 @@ CmdLinGrad CmdLinGrad_read(Alloc a, CmdLinGradRef ref) CmdLinGrad Cmd_LinGrad_read(Alloc a, CmdRef ref) { - CmdLinGradRef _572 = { ref.offset + 4u }; + CmdLinGradRef _709 = { ref.offset + 4u }; Alloc param = a; - CmdLinGradRef param_1 = _572; + CmdLinGradRef param_1 = _709; return CmdLinGrad_read(param, param_1); } +CmdRadGrad CmdRadGrad_read(Alloc a, CmdRadGradRef ref) +{ + uint ix = ref.offset >> uint(2); + Alloc param = a; + uint param_1 = ix + 0u; + uint raw0 = read_mem(param, param_1); + Alloc param_2 = a; + uint param_3 = ix + 1u; + uint raw1 = read_mem(param_2, param_3); + Alloc param_4 = a; + uint param_5 = ix + 2u; + uint raw2 = read_mem(param_4, param_5); + Alloc param_6 = a; + uint param_7 = ix + 3u; + uint raw3 = read_mem(param_6, param_7); + Alloc param_8 = a; + uint param_9 = ix + 4u; + uint raw4 = read_mem(param_8, param_9); + Alloc param_10 = a; + uint param_11 = ix + 5u; + uint raw5 = read_mem(param_10, param_11); + Alloc param_12 = a; + uint param_13 = ix + 6u; + uint raw6 = read_mem(param_12, param_13); + Alloc param_14 = a; + uint param_15 = ix + 7u; + uint raw7 = read_mem(param_14, param_15); + Alloc param_16 = a; + uint param_17 = ix + 8u; + uint raw8 = read_mem(param_16, param_17); + Alloc param_18 = a; + uint param_19 = ix + 9u; + uint raw9 = read_mem(param_18, param_19); + Alloc param_20 = a; + uint param_21 = ix + 10u; + uint raw10 = read_mem(param_20, param_21); + CmdRadGrad s; + s.index = raw0; + s.mat = float4(asfloat(raw1), asfloat(raw2), asfloat(raw3), asfloat(raw4)); + s.xlat = float2(asfloat(raw5), asfloat(raw6)); + s.c1 = float2(asfloat(raw7), asfloat(raw8)); + s.ra = asfloat(raw9); + s.roff = asfloat(raw10); + return s; +} + +CmdRadGrad Cmd_RadGrad_read(Alloc a, CmdRef ref) +{ + CmdRadGradRef _719 = { ref.offset + 4u }; + Alloc param = a; + CmdRadGradRef param_1 = _719; + return CmdRadGrad_read(param, param_1); +} + CmdImage CmdImage_read(Alloc a, CmdImageRef ref) { uint ix = ref.offset >> uint(2); @@ -393,9 +462,9 @@ CmdImage CmdImage_read(Alloc a, CmdImageRef ref) CmdImage Cmd_Image_read(Alloc a, CmdRef ref) { - CmdImageRef _582 = { ref.offset + 4u }; + CmdImageRef _729 = { ref.offset + 4u }; Alloc param = a; - CmdImageRef param_1 = _582; + CmdImageRef param_1 = _729; return CmdImage_read(param, param_1); } @@ -408,10 +477,10 @@ void fillImage(out float4 spvReturnValue[8], uint2 xy, CmdImage cmd_img) int2 uv = int2(xy + chunk_offset(param)) + cmd_img.offset; float4 fg_rgba = image_atlas[uv]; float3 param_1 = fg_rgba.xyz; - float3 _1493 = fromsRGB(param_1); - fg_rgba.x = _1493.x; - fg_rgba.y = _1493.y; - fg_rgba.z = _1493.z; + float3 _1638 = fromsRGB(param_1); + fg_rgba.x = _1638.x; + fg_rgba.y = _1638.y; + fg_rgba.z = _1638.z; rgba[i] = fg_rgba; } spvReturnValue = rgba; @@ -445,9 +514,9 @@ CmdEndClip CmdEndClip_read(Alloc a, CmdEndClipRef ref) CmdEndClip Cmd_EndClip_read(Alloc a, CmdRef ref) { - CmdEndClipRef _592 = { ref.offset + 4u }; + CmdEndClipRef _739 = { ref.offset + 4u }; Alloc param = a; - CmdEndClipRef param_1 = _592; + CmdEndClipRef param_1 = _739; return CmdEndClip_read(param, param_1); } @@ -637,8 +706,8 @@ float3 set_lum(float3 c, float l) { float3 param = c; float3 param_1 = c + (l - lum(param)).xxx; - float3 _901 = clip_color(param_1); - return _901; + float3 _1046 = clip_color(param_1); + return _1046; } float3 mix_blend(float3 cb, float3 cs, uint mode) @@ -726,9 +795,9 @@ float3 mix_blend(float3 cb, float3 cs, uint mode) float3 param_20 = cb; float3 param_21 = cs; float param_22 = sat(param_20); - float3 _1192 = set_sat(param_21, param_22); + float3 _1337 = set_sat(param_21, param_22); float3 param_23 = cb; - float3 param_24 = _1192; + float3 param_24 = _1337; float param_25 = lum(param_23); b = set_lum(param_24, param_25); break; @@ -738,9 +807,9 @@ float3 mix_blend(float3 cb, float3 cs, uint mode) float3 param_26 = cs; float3 param_27 = cb; float param_28 = sat(param_26); - float3 _1206 = set_sat(param_27, param_28); + float3 _1351 = set_sat(param_27, param_28); float3 param_29 = cb; - float3 param_30 = _1206; + float3 param_30 = _1351; float param_31 = lum(param_29); b = set_lum(param_30, param_31); break; @@ -877,24 +946,24 @@ CmdJump CmdJump_read(Alloc a, CmdJumpRef ref) CmdJump Cmd_Jump_read(Alloc a, CmdRef ref) { - CmdJumpRef _602 = { ref.offset + 4u }; + CmdJumpRef _749 = { ref.offset + 4u }; Alloc param = a; - CmdJumpRef param_1 = _602; + CmdJumpRef param_1 = _749; return CmdJump_read(param, param_1); } void comp_main() { - uint tile_ix = (gl_WorkGroupID.y * _1521.Load(8)) + gl_WorkGroupID.x; - Alloc _1536; - _1536.offset = _1521.Load(24); + uint tile_ix = (gl_WorkGroupID.y * _1666.Load(8)) + gl_WorkGroupID.x; + Alloc _1681; + _1681.offset = _1666.Load(24); Alloc param; - param.offset = _1536.offset; + param.offset = _1681.offset; uint param_1 = tile_ix * 1024u; uint param_2 = 1024u; Alloc cmd_alloc = slice_mem(param, param_1, param_2); - CmdRef _1545 = { cmd_alloc.offset }; - CmdRef cmd_ref = _1545; + CmdRef _1690 = { cmd_alloc.offset }; + CmdRef cmd_ref = _1690; uint2 xy_uint = uint2(gl_LocalInvocationID.x + (16u * gl_WorkGroupID.x), gl_LocalInvocationID.y + (16u * gl_WorkGroupID.y)); float2 xy = float2(xy_uint); float4 rgba[8]; @@ -903,7 +972,7 @@ void comp_main() rgba[i] = 0.0f.xxxx; } uint clip_depth = 0u; - bool mem_ok = _278.Load(4) == 0u; + bool mem_ok = _291.Load(4) == 0u; float df[8]; TileSegRef tile_seg_ref; float area[8]; @@ -928,8 +997,8 @@ void comp_main() { df[k] = 1000000000.0f; } - TileSegRef _1638 = { stroke.tile_ref }; - tile_seg_ref = _1638; + TileSegRef _1784 = { stroke.tile_ref }; + tile_seg_ref = _1784; do { uint param_7 = tile_seg_ref.offset; @@ -965,8 +1034,8 @@ void comp_main() { area[k_3] = float(fill.backdrop); } - TileSegRef _1758 = { fill.tile_ref }; - tile_seg_ref = _1758; + TileSegRef _1904 = { fill.tile_ref }; + tile_seg_ref = _1904; do { uint param_15 = tile_seg_ref.offset; @@ -1055,11 +1124,12 @@ void comp_main() int x = int(round(clamp(my_d, 0.0f, 1.0f) * 511.0f)); float4 fg_rgba = gradients[int2(x, int(lin.index))]; float3 param_29 = fg_rgba.xyz; - float3 _2092 = fromsRGB(param_29); - fg_rgba.x = _2092.x; - fg_rgba.y = _2092.y; - fg_rgba.z = _2092.z; - rgba[k_9] = fg_rgba; + float3 _2238 = fromsRGB(param_29); + fg_rgba.x = _2238.x; + fg_rgba.y = _2238.y; + fg_rgba.z = _2238.z; + float4 fg_k_1 = fg_rgba * area[k_9]; + rgba[k_9] = (rgba[k_9] * (1.0f - fg_k_1.w)) + fg_k_1; } cmd_ref.offset += 20u; break; @@ -1068,74 +1138,100 @@ void comp_main() { Alloc param_30 = cmd_alloc; CmdRef param_31 = cmd_ref; - CmdImage fill_img = Cmd_Image_read(param_30, param_31); - uint2 param_32 = xy_uint; - CmdImage param_33 = fill_img; - float4 _2121[8]; - fillImage(_2121, param_32, param_33); - float4 img[8] = _2121; + CmdRadGrad rad = Cmd_RadGrad_read(param_30, param_31); for (uint k_10 = 0u; k_10 < 8u; k_10++) { - float4 fg_k_1 = img[k_10] * area[k_10]; - rgba[k_10] = (rgba[k_10] * (1.0f - fg_k_1.w)) + fg_k_1; + uint param_32 = k_10; + float2 my_xy_1 = xy + float2(chunk_offset(param_32)); + my_xy_1 = ((rad.mat.xz * my_xy_1.x) + (rad.mat.yw * my_xy_1.y)) - rad.xlat; + float ba = dot(my_xy_1, rad.c1); + float ca = rad.ra * dot(my_xy_1, my_xy_1); + float t_2 = (sqrt((ba * ba) + ca) - ba) - rad.roff; + int x_1 = int(round(clamp(t_2, 0.0f, 1.0f) * 511.0f)); + float4 fg_rgba_1 = gradients[int2(x_1, int(rad.index))]; + float3 param_33 = fg_rgba_1.xyz; + float3 _2348 = fromsRGB(param_33); + fg_rgba_1.x = _2348.x; + fg_rgba_1.y = _2348.y; + fg_rgba_1.z = _2348.z; + float4 fg_k_2 = fg_rgba_1 * area[k_10]; + rgba[k_10] = (rgba[k_10] * (1.0f - fg_k_2.w)) + fg_k_2; } - cmd_ref.offset += 12u; + cmd_ref.offset += 48u; break; } case 8u: { + Alloc param_34 = cmd_alloc; + CmdRef param_35 = cmd_ref; + CmdImage fill_img = Cmd_Image_read(param_34, param_35); + uint2 param_36 = xy_uint; + CmdImage param_37 = fill_img; + float4 _2391[8]; + fillImage(_2391, param_36, param_37); + float4 img[8] = _2391; for (uint k_11 = 0u; k_11 < 8u; k_11++) + { + float4 fg_k_3 = img[k_11] * area[k_11]; + rgba[k_11] = (rgba[k_11] * (1.0f - fg_k_3.w)) + fg_k_3; + } + cmd_ref.offset += 12u; + break; + } + case 9u: + { + for (uint k_12 = 0u; k_12 < 8u; k_12++) { uint d_2 = min(clip_depth, 127u); - float4 param_34 = float4(rgba[k_11]); - uint _2184 = packsRGB(param_34); - blend_stack[d_2][k_11] = _2184; - rgba[k_11] = 0.0f.xxxx; + float4 param_38 = float4(rgba[k_12]); + uint _2454 = packsRGB(param_38); + blend_stack[d_2][k_12] = _2454; + rgba[k_12] = 0.0f.xxxx; } clip_depth++; cmd_ref.offset += 4u; break; } - case 9u: + case 10u: { - Alloc param_35 = cmd_alloc; - CmdRef param_36 = cmd_ref; - CmdEndClip end_clip = Cmd_EndClip_read(param_35, param_36); + Alloc param_39 = cmd_alloc; + CmdRef param_40 = cmd_ref; + CmdEndClip end_clip = Cmd_EndClip_read(param_39, param_40); uint blend_mode = end_clip.blend >> uint(8); uint comp_mode = end_clip.blend & 255u; clip_depth--; - for (uint k_12 = 0u; k_12 < 8u; k_12++) + for (uint k_13 = 0u; k_13 < 8u; k_13++) { uint d_3 = min(clip_depth, 127u); - uint param_37 = blend_stack[d_3][k_12]; - float4 bg = unpacksRGB(param_37); - float4 fg_1 = rgba[k_12] * area[k_12]; - float3 param_38 = bg.xyz; - float3 param_39 = fg_1.xyz; - uint param_40 = blend_mode; - float3 blend = mix_blend(param_38, param_39, param_40); - float4 _2251 = fg_1; - float _2255 = fg_1.w; - float3 _2262 = lerp(_2251.xyz, blend, float((_2255 * bg.w) > 0.0f).xxx); - fg_1.x = _2262.x; - fg_1.y = _2262.y; - fg_1.z = _2262.z; - float3 param_41 = bg.xyz; - float3 param_42 = fg_1.xyz; - float param_43 = bg.w; - float param_44 = fg_1.w; - uint param_45 = comp_mode; - rgba[k_12] = mix_compose(param_41, param_42, param_43, param_44, param_45); + uint param_41 = blend_stack[d_3][k_13]; + float4 bg = unpacksRGB(param_41); + float4 fg_1 = rgba[k_13] * area[k_13]; + float3 param_42 = bg.xyz; + float3 param_43 = fg_1.xyz; + uint param_44 = blend_mode; + float3 blend = mix_blend(param_42, param_43, param_44); + float4 _2521 = fg_1; + float _2525 = fg_1.w; + float3 _2532 = lerp(_2521.xyz, blend, float((_2525 * bg.w) > 0.0f).xxx); + fg_1.x = _2532.x; + fg_1.y = _2532.y; + fg_1.z = _2532.z; + float3 param_45 = bg.xyz; + float3 param_46 = fg_1.xyz; + float param_47 = bg.w; + float param_48 = fg_1.w; + uint param_49 = comp_mode; + rgba[k_13] = mix_compose(param_45, param_46, param_47, param_48, param_49); } cmd_ref.offset += 8u; break; } - case 10u: + case 11u: { - Alloc param_46 = cmd_alloc; - CmdRef param_47 = cmd_ref; - CmdRef _2299 = { Cmd_Jump_read(param_46, param_47).new_ref }; - cmd_ref = _2299; + Alloc param_50 = cmd_alloc; + CmdRef param_51 = cmd_ref; + CmdRef _2569 = { Cmd_Jump_read(param_50, param_51).new_ref }; + cmd_ref = _2569; cmd_alloc.offset = cmd_ref.offset; break; } @@ -1143,9 +1239,9 @@ void comp_main() } for (uint i_1 = 0u; i_1 < 8u; i_1++) { - uint param_48 = i_1; - float3 param_49 = rgba[i_1].xyz; - image[int2(xy_uint + chunk_offset(param_48))] = float4(tosRGB(param_49), rgba[i_1].w); + uint param_52 = i_1; + float3 param_53 = rgba[i_1].xyz; + image[int2(xy_uint + chunk_offset(param_52))] = float4(tosRGB(param_53), rgba[i_1].w); } } diff --git a/piet-gpu/shader/gen/kernel4.msl b/piet-gpu/shader/gen/kernel4.msl index c1f41af..6489563 100644 --- a/piet-gpu/shader/gen/kernel4.msl +++ b/piet-gpu/shader/gen/kernel4.msl @@ -94,6 +94,21 @@ struct CmdLinGrad float line_c; }; +struct CmdRadGradRef +{ + uint offset; +}; + +struct CmdRadGrad +{ + uint index; + float4 mat; + float2 xlat; + float2 c1; + float ra; + float roff; +}; + struct CmdImageRef { uint offset; @@ -222,7 +237,7 @@ bool touch_mem(thread const Alloc& alloc, thread const uint& offset) } static inline __attribute__((always_inline)) -uint read_mem(thread const Alloc& alloc, thread const uint& offset, device Memory& v_278) +uint read_mem(thread const Alloc& alloc, thread const uint& offset, device Memory& v_291) { Alloc param = alloc; uint param_1 = offset; @@ -230,29 +245,29 @@ uint read_mem(thread const Alloc& alloc, thread const uint& offset, device Memor { return 0u; } - uint v = v_278.memory[offset]; + uint v = v_291.memory[offset]; return v; } static inline __attribute__((always_inline)) -CmdTag Cmd_tag(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_278) +CmdTag Cmd_tag(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_291) { Alloc param = a; uint param_1 = ref.offset >> uint(2); - uint tag_and_flags = read_mem(param, param_1, v_278); + uint tag_and_flags = read_mem(param, param_1, v_291); return CmdTag{ tag_and_flags & 65535u, tag_and_flags >> uint(16) }; } static inline __attribute__((always_inline)) -CmdStroke CmdStroke_read(thread const Alloc& a, thread const CmdStrokeRef& ref, device Memory& v_278) +CmdStroke CmdStroke_read(thread const Alloc& a, thread const CmdStrokeRef& ref, device Memory& v_291) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; - uint raw0 = read_mem(param, param_1, v_278); + uint raw0 = read_mem(param, param_1, v_291); Alloc param_2 = a; uint param_3 = ix + 1u; - uint raw1 = read_mem(param_2, param_3, v_278); + uint raw1 = read_mem(param_2, param_3, v_291); CmdStroke s; s.tile_ref = raw0; s.half_width = as_type(raw1); @@ -260,11 +275,11 @@ CmdStroke CmdStroke_read(thread const Alloc& a, thread const CmdStrokeRef& ref, } static inline __attribute__((always_inline)) -CmdStroke Cmd_Stroke_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_278) +CmdStroke Cmd_Stroke_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_291) { Alloc param = a; CmdStrokeRef param_1 = CmdStrokeRef{ ref.offset + 4u }; - return CmdStroke_read(param, param_1, v_278); + return CmdStroke_read(param, param_1, v_291); } static inline __attribute__((always_inline)) @@ -276,27 +291,27 @@ Alloc new_alloc(thread const uint& offset, thread const uint& size, thread const } static inline __attribute__((always_inline)) -TileSeg TileSeg_read(thread const Alloc& a, thread const TileSegRef& ref, device Memory& v_278) +TileSeg TileSeg_read(thread const Alloc& a, thread const TileSegRef& ref, device Memory& v_291) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; - uint raw0 = read_mem(param, param_1, v_278); + uint raw0 = read_mem(param, param_1, v_291); Alloc param_2 = a; uint param_3 = ix + 1u; - uint raw1 = read_mem(param_2, param_3, v_278); + uint raw1 = read_mem(param_2, param_3, v_291); Alloc param_4 = a; uint param_5 = ix + 2u; - uint raw2 = read_mem(param_4, param_5, v_278); + uint raw2 = read_mem(param_4, param_5, v_291); Alloc param_6 = a; uint param_7 = ix + 3u; - uint raw3 = read_mem(param_6, param_7, v_278); + uint raw3 = read_mem(param_6, param_7, v_291); Alloc param_8 = a; uint param_9 = ix + 4u; - uint raw4 = read_mem(param_8, param_9, v_278); + uint raw4 = read_mem(param_8, param_9, v_291); Alloc param_10 = a; uint param_11 = ix + 5u; - uint raw5 = read_mem(param_10, param_11, v_278); + uint raw5 = read_mem(param_10, param_11, v_291); TileSeg s; s.origin = float2(as_type(raw0), as_type(raw1)); s.vector = float2(as_type(raw2), as_type(raw3)); @@ -312,15 +327,15 @@ uint2 chunk_offset(thread const uint& i) } static inline __attribute__((always_inline)) -CmdFill CmdFill_read(thread const Alloc& a, thread const CmdFillRef& ref, device Memory& v_278) +CmdFill CmdFill_read(thread const Alloc& a, thread const CmdFillRef& ref, device Memory& v_291) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; - uint raw0 = read_mem(param, param_1, v_278); + uint raw0 = read_mem(param, param_1, v_291); Alloc param_2 = a; uint param_3 = ix + 1u; - uint raw1 = read_mem(param_2, param_3, v_278); + uint raw1 = read_mem(param_2, param_3, v_291); CmdFill s; s.tile_ref = raw0; s.backdrop = int(raw1); @@ -328,51 +343,51 @@ CmdFill CmdFill_read(thread const Alloc& a, thread const CmdFillRef& ref, device } static inline __attribute__((always_inline)) -CmdFill Cmd_Fill_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_278) +CmdFill Cmd_Fill_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_291) { Alloc param = a; CmdFillRef param_1 = CmdFillRef{ ref.offset + 4u }; - return CmdFill_read(param, param_1, v_278); + return CmdFill_read(param, param_1, v_291); } static inline __attribute__((always_inline)) -CmdAlpha CmdAlpha_read(thread const Alloc& a, thread const CmdAlphaRef& ref, device Memory& v_278) +CmdAlpha CmdAlpha_read(thread const Alloc& a, thread const CmdAlphaRef& ref, device Memory& v_291) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; - uint raw0 = read_mem(param, param_1, v_278); + uint raw0 = read_mem(param, param_1, v_291); CmdAlpha s; s.alpha = as_type(raw0); return s; } static inline __attribute__((always_inline)) -CmdAlpha Cmd_Alpha_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_278) +CmdAlpha Cmd_Alpha_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_291) { Alloc param = a; CmdAlphaRef param_1 = CmdAlphaRef{ ref.offset + 4u }; - return CmdAlpha_read(param, param_1, v_278); + return CmdAlpha_read(param, param_1, v_291); } static inline __attribute__((always_inline)) -CmdColor CmdColor_read(thread const Alloc& a, thread const CmdColorRef& ref, device Memory& v_278) +CmdColor CmdColor_read(thread const Alloc& a, thread const CmdColorRef& ref, device Memory& v_291) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; - uint raw0 = read_mem(param, param_1, v_278); + uint raw0 = read_mem(param, param_1, v_291); CmdColor s; s.rgba_color = raw0; return s; } static inline __attribute__((always_inline)) -CmdColor Cmd_Color_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_278) +CmdColor Cmd_Color_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_291) { Alloc param = a; CmdColorRef param_1 = CmdColorRef{ ref.offset + 4u }; - return CmdColor_read(param, param_1, v_278); + return CmdColor_read(param, param_1, v_291); } static inline __attribute__((always_inline)) @@ -393,21 +408,21 @@ float4 unpacksRGB(thread const uint& srgba) } static inline __attribute__((always_inline)) -CmdLinGrad CmdLinGrad_read(thread const Alloc& a, thread const CmdLinGradRef& ref, device Memory& v_278) +CmdLinGrad CmdLinGrad_read(thread const Alloc& a, thread const CmdLinGradRef& ref, device Memory& v_291) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; - uint raw0 = read_mem(param, param_1, v_278); + uint raw0 = read_mem(param, param_1, v_291); Alloc param_2 = a; uint param_3 = ix + 1u; - uint raw1 = read_mem(param_2, param_3, v_278); + uint raw1 = read_mem(param_2, param_3, v_291); Alloc param_4 = a; uint param_5 = ix + 2u; - uint raw2 = read_mem(param_4, param_5, v_278); + uint raw2 = read_mem(param_4, param_5, v_291); Alloc param_6 = a; uint param_7 = ix + 3u; - uint raw3 = read_mem(param_6, param_7, v_278); + uint raw3 = read_mem(param_6, param_7, v_291); CmdLinGrad s; s.index = raw0; s.line_x = as_type(raw1); @@ -417,23 +432,78 @@ CmdLinGrad CmdLinGrad_read(thread const Alloc& a, thread const CmdLinGradRef& re } static inline __attribute__((always_inline)) -CmdLinGrad Cmd_LinGrad_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_278) +CmdLinGrad Cmd_LinGrad_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_291) { Alloc param = a; CmdLinGradRef param_1 = CmdLinGradRef{ ref.offset + 4u }; - return CmdLinGrad_read(param, param_1, v_278); + return CmdLinGrad_read(param, param_1, v_291); } static inline __attribute__((always_inline)) -CmdImage CmdImage_read(thread const Alloc& a, thread const CmdImageRef& ref, device Memory& v_278) +CmdRadGrad CmdRadGrad_read(thread const Alloc& a, thread const CmdRadGradRef& ref, device Memory& v_291) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; - uint raw0 = read_mem(param, param_1, v_278); + uint raw0 = read_mem(param, param_1, v_291); Alloc param_2 = a; uint param_3 = ix + 1u; - uint raw1 = read_mem(param_2, param_3, v_278); + uint raw1 = read_mem(param_2, param_3, v_291); + Alloc param_4 = a; + uint param_5 = ix + 2u; + uint raw2 = read_mem(param_4, param_5, v_291); + Alloc param_6 = a; + uint param_7 = ix + 3u; + uint raw3 = read_mem(param_6, param_7, v_291); + Alloc param_8 = a; + uint param_9 = ix + 4u; + uint raw4 = read_mem(param_8, param_9, v_291); + Alloc param_10 = a; + uint param_11 = ix + 5u; + uint raw5 = read_mem(param_10, param_11, v_291); + Alloc param_12 = a; + uint param_13 = ix + 6u; + uint raw6 = read_mem(param_12, param_13, v_291); + Alloc param_14 = a; + uint param_15 = ix + 7u; + uint raw7 = read_mem(param_14, param_15, v_291); + Alloc param_16 = a; + uint param_17 = ix + 8u; + uint raw8 = read_mem(param_16, param_17, v_291); + Alloc param_18 = a; + uint param_19 = ix + 9u; + uint raw9 = read_mem(param_18, param_19, v_291); + Alloc param_20 = a; + uint param_21 = ix + 10u; + uint raw10 = read_mem(param_20, param_21, v_291); + CmdRadGrad s; + s.index = raw0; + s.mat = float4(as_type(raw1), as_type(raw2), as_type(raw3), as_type(raw4)); + s.xlat = float2(as_type(raw5), as_type(raw6)); + s.c1 = float2(as_type(raw7), as_type(raw8)); + s.ra = as_type(raw9); + s.roff = as_type(raw10); + return s; +} + +static inline __attribute__((always_inline)) +CmdRadGrad Cmd_RadGrad_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_291) +{ + Alloc param = a; + CmdRadGradRef param_1 = CmdRadGradRef{ ref.offset + 4u }; + return CmdRadGrad_read(param, param_1, v_291); +} + +static inline __attribute__((always_inline)) +CmdImage CmdImage_read(thread const Alloc& a, thread const CmdImageRef& ref, device Memory& v_291) +{ + uint ix = ref.offset >> uint(2); + Alloc param = a; + uint param_1 = ix + 0u; + uint raw0 = read_mem(param, param_1, v_291); + Alloc param_2 = a; + uint param_3 = ix + 1u; + uint raw1 = read_mem(param_2, param_3, v_291); CmdImage s; s.index = raw0; s.offset = int2(int(raw1 << uint(16)) >> 16, int(raw1) >> 16); @@ -441,11 +511,11 @@ CmdImage CmdImage_read(thread const Alloc& a, thread const CmdImageRef& ref, dev } static inline __attribute__((always_inline)) -CmdImage Cmd_Image_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_278) +CmdImage Cmd_Image_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_291) { Alloc param = a; CmdImageRef param_1 = CmdImageRef{ ref.offset + 4u }; - return CmdImage_read(param, param_1, v_278); + return CmdImage_read(param, param_1, v_291); } static inline __attribute__((always_inline)) @@ -458,10 +528,10 @@ spvUnsafeArray fillImage(thread const uint2& xy, thread const CmdImag int2 uv = int2(xy + chunk_offset(param)) + cmd_img.offset; float4 fg_rgba = image_atlas.read(uint2(uv)); float3 param_1 = fg_rgba.xyz; - float3 _1493 = fromsRGB(param_1); - fg_rgba.x = _1493.x; - fg_rgba.y = _1493.y; - fg_rgba.z = _1493.z; + float3 _1638 = fromsRGB(param_1); + fg_rgba.x = _1638.x; + fg_rgba.y = _1638.y; + fg_rgba.z = _1638.z; rgba[i] = fg_rgba; } return rgba; @@ -485,23 +555,23 @@ uint packsRGB(thread float4& rgba) } static inline __attribute__((always_inline)) -CmdEndClip CmdEndClip_read(thread const Alloc& a, thread const CmdEndClipRef& ref, device Memory& v_278) +CmdEndClip CmdEndClip_read(thread const Alloc& a, thread const CmdEndClipRef& ref, device Memory& v_291) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; - uint raw0 = read_mem(param, param_1, v_278); + uint raw0 = read_mem(param, param_1, v_291); CmdEndClip s; s.blend = raw0; return s; } static inline __attribute__((always_inline)) -CmdEndClip Cmd_EndClip_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_278) +CmdEndClip Cmd_EndClip_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_291) { Alloc param = a; CmdEndClipRef param_1 = CmdEndClipRef{ ref.offset + 4u }; - return CmdEndClip_read(param, param_1, v_278); + return CmdEndClip_read(param, param_1, v_291); } static inline __attribute__((always_inline)) @@ -701,8 +771,8 @@ float3 set_lum(thread const float3& c, thread const float& l) { float3 param = c; float3 param_1 = c + float3(l - lum(param)); - float3 _901 = clip_color(param_1); - return _901; + float3 _1046 = clip_color(param_1); + return _1046; } static inline __attribute__((always_inline)) @@ -791,9 +861,9 @@ float3 mix_blend(thread const float3& cb, thread const float3& cs, thread const float3 param_20 = cb; float3 param_21 = cs; float param_22 = sat(param_20); - float3 _1192 = set_sat(param_21, param_22); + float3 _1337 = set_sat(param_21, param_22); float3 param_23 = cb; - float3 param_24 = _1192; + float3 param_24 = _1337; float param_25 = lum(param_23); b = set_lum(param_24, param_25); break; @@ -803,9 +873,9 @@ float3 mix_blend(thread const float3& cb, thread const float3& cs, thread const float3 param_26 = cs; float3 param_27 = cb; float param_28 = sat(param_26); - float3 _1206 = set_sat(param_27, param_28); + float3 _1351 = set_sat(param_27, param_28); float3 param_29 = cb; - float3 param_30 = _1206; + float3 param_30 = _1351; float param_31 = lum(param_29); b = set_lum(param_30, param_31); break; @@ -931,30 +1001,30 @@ float4 mix_compose(thread const float3& cb, thread const float3& cs, thread cons } static inline __attribute__((always_inline)) -CmdJump CmdJump_read(thread const Alloc& a, thread const CmdJumpRef& ref, device Memory& v_278) +CmdJump CmdJump_read(thread const Alloc& a, thread const CmdJumpRef& ref, device Memory& v_291) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; - uint raw0 = read_mem(param, param_1, v_278); + uint raw0 = read_mem(param, param_1, v_291); CmdJump s; s.new_ref = raw0; return s; } static inline __attribute__((always_inline)) -CmdJump Cmd_Jump_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_278) +CmdJump Cmd_Jump_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_291) { Alloc param = a; CmdJumpRef param_1 = CmdJumpRef{ ref.offset + 4u }; - return CmdJump_read(param, param_1, v_278); + return CmdJump_read(param, param_1, v_291); } -kernel void main0(device Memory& v_278 [[buffer(0)]], const device ConfigBuf& _1521 [[buffer(1)]], texture2d image [[texture(2)]], texture2d image_atlas [[texture(3)]], texture2d gradients [[texture(4)]], uint3 gl_WorkGroupID [[threadgroup_position_in_grid]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]]) +kernel void main0(device Memory& v_291 [[buffer(0)]], const device ConfigBuf& _1666 [[buffer(1)]], texture2d image [[texture(2)]], texture2d image_atlas [[texture(3)]], texture2d gradients [[texture(4)]], uint3 gl_WorkGroupID [[threadgroup_position_in_grid]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]]) { - uint tile_ix = (gl_WorkGroupID.y * _1521.conf.width_in_tiles) + gl_WorkGroupID.x; + uint tile_ix = (gl_WorkGroupID.y * _1666.conf.width_in_tiles) + gl_WorkGroupID.x; Alloc param; - param.offset = _1521.conf.ptcl_alloc.offset; + param.offset = _1666.conf.ptcl_alloc.offset; uint param_1 = tile_ix * 1024u; uint param_2 = 1024u; Alloc cmd_alloc = slice_mem(param, param_1, param_2); @@ -967,7 +1037,7 @@ kernel void main0(device Memory& v_278 [[buffer(0)]], const device ConfigBuf& _1 rgba[i] = float4(0.0); } uint clip_depth = 0u; - bool mem_ok = v_278.mem_error == 0u; + bool mem_ok = v_291.mem_error == 0u; spvUnsafeArray df; TileSegRef tile_seg_ref; spvUnsafeArray area; @@ -976,7 +1046,7 @@ kernel void main0(device Memory& v_278 [[buffer(0)]], const device ConfigBuf& _1 { Alloc param_3 = cmd_alloc; CmdRef param_4 = cmd_ref; - uint tag = Cmd_tag(param_3, param_4, v_278).tag; + uint tag = Cmd_tag(param_3, param_4, v_291).tag; if (tag == 0u) { break; @@ -987,7 +1057,7 @@ kernel void main0(device Memory& v_278 [[buffer(0)]], const device ConfigBuf& _1 { Alloc param_5 = cmd_alloc; CmdRef param_6 = cmd_ref; - CmdStroke stroke = Cmd_Stroke_read(param_5, param_6, v_278); + CmdStroke stroke = Cmd_Stroke_read(param_5, param_6, v_291); for (uint k = 0u; k < 8u; k++) { df[k] = 1000000000.0; @@ -1000,7 +1070,7 @@ kernel void main0(device Memory& v_278 [[buffer(0)]], const device ConfigBuf& _1 bool param_9 = mem_ok; Alloc param_10 = new_alloc(param_7, param_8, param_9); TileSegRef param_11 = tile_seg_ref; - TileSeg seg = TileSeg_read(param_10, param_11, v_278); + TileSeg seg = TileSeg_read(param_10, param_11, v_291); float2 line_vec = seg.vector; for (uint k_1 = 0u; k_1 < 8u; k_1++) { @@ -1023,7 +1093,7 @@ kernel void main0(device Memory& v_278 [[buffer(0)]], const device ConfigBuf& _1 { Alloc param_13 = cmd_alloc; CmdRef param_14 = cmd_ref; - CmdFill fill = Cmd_Fill_read(param_13, param_14, v_278); + CmdFill fill = Cmd_Fill_read(param_13, param_14, v_291); for (uint k_3 = 0u; k_3 < 8u; k_3++) { area[k_3] = float(fill.backdrop); @@ -1036,7 +1106,7 @@ kernel void main0(device Memory& v_278 [[buffer(0)]], const device ConfigBuf& _1 bool param_17 = mem_ok; Alloc param_18 = new_alloc(param_15, param_16, param_17); TileSegRef param_19 = tile_seg_ref; - TileSeg seg_1 = TileSeg_read(param_18, param_19, v_278); + TileSeg seg_1 = TileSeg_read(param_18, param_19, v_291); for (uint k_4 = 0u; k_4 < 8u; k_4++) { uint param_20 = k_4; @@ -1080,7 +1150,7 @@ kernel void main0(device Memory& v_278 [[buffer(0)]], const device ConfigBuf& _1 { Alloc param_21 = cmd_alloc; CmdRef param_22 = cmd_ref; - CmdAlpha alpha = Cmd_Alpha_read(param_21, param_22, v_278); + CmdAlpha alpha = Cmd_Alpha_read(param_21, param_22, v_291); for (uint k_7 = 0u; k_7 < 8u; k_7++) { area[k_7] = alpha.alpha; @@ -1092,7 +1162,7 @@ kernel void main0(device Memory& v_278 [[buffer(0)]], const device ConfigBuf& _1 { Alloc param_23 = cmd_alloc; CmdRef param_24 = cmd_ref; - CmdColor color = Cmd_Color_read(param_23, param_24, v_278); + CmdColor color = Cmd_Color_read(param_23, param_24, v_291); uint param_25 = color.rgba_color; float4 fg = unpacksRGB(param_25); for (uint k_8 = 0u; k_8 < 8u; k_8++) @@ -1107,7 +1177,7 @@ kernel void main0(device Memory& v_278 [[buffer(0)]], const device ConfigBuf& _1 { Alloc param_26 = cmd_alloc; CmdRef param_27 = cmd_ref; - CmdLinGrad lin = Cmd_LinGrad_read(param_26, param_27, v_278); + CmdLinGrad lin = Cmd_LinGrad_read(param_26, param_27, v_291); float d_1 = ((lin.line_x * xy.x) + (lin.line_y * xy.y)) + lin.line_c; for (uint k_9 = 0u; k_9 < 8u; k_9++) { @@ -1117,11 +1187,12 @@ kernel void main0(device Memory& v_278 [[buffer(0)]], const device ConfigBuf& _1 int x = int(round(fast::clamp(my_d, 0.0, 1.0) * 511.0)); float4 fg_rgba = gradients.read(uint2(int2(x, int(lin.index)))); float3 param_29 = fg_rgba.xyz; - float3 _2092 = fromsRGB(param_29); - fg_rgba.x = _2092.x; - fg_rgba.y = _2092.y; - fg_rgba.z = _2092.z; - rgba[k_9] = fg_rgba; + float3 _2238 = fromsRGB(param_29); + fg_rgba.x = _2238.x; + fg_rgba.y = _2238.y; + fg_rgba.z = _2238.z; + float4 fg_k_1 = fg_rgba * area[k_9]; + rgba[k_9] = (rgba[k_9] * (1.0 - fg_k_1.w)) + fg_k_1; } cmd_ref.offset += 20u; break; @@ -1130,72 +1201,98 @@ kernel void main0(device Memory& v_278 [[buffer(0)]], const device ConfigBuf& _1 { Alloc param_30 = cmd_alloc; CmdRef param_31 = cmd_ref; - CmdImage fill_img = Cmd_Image_read(param_30, param_31, v_278); - uint2 param_32 = xy_uint; - CmdImage param_33 = fill_img; - spvUnsafeArray img; - img = fillImage(param_32, param_33, image_atlas); + CmdRadGrad rad = Cmd_RadGrad_read(param_30, param_31, v_291); for (uint k_10 = 0u; k_10 < 8u; k_10++) { - float4 fg_k_1 = img[k_10] * area[k_10]; - rgba[k_10] = (rgba[k_10] * (1.0 - fg_k_1.w)) + fg_k_1; + uint param_32 = k_10; + float2 my_xy_1 = xy + float2(chunk_offset(param_32)); + my_xy_1 = ((rad.mat.xz * my_xy_1.x) + (rad.mat.yw * my_xy_1.y)) - rad.xlat; + float ba = dot(my_xy_1, rad.c1); + float ca = rad.ra * dot(my_xy_1, my_xy_1); + float t_2 = (sqrt((ba * ba) + ca) - ba) - rad.roff; + int x_1 = int(round(fast::clamp(t_2, 0.0, 1.0) * 511.0)); + float4 fg_rgba_1 = gradients.read(uint2(int2(x_1, int(rad.index)))); + float3 param_33 = fg_rgba_1.xyz; + float3 _2348 = fromsRGB(param_33); + fg_rgba_1.x = _2348.x; + fg_rgba_1.y = _2348.y; + fg_rgba_1.z = _2348.z; + float4 fg_k_2 = fg_rgba_1 * area[k_10]; + rgba[k_10] = (rgba[k_10] * (1.0 - fg_k_2.w)) + fg_k_2; } - cmd_ref.offset += 12u; + cmd_ref.offset += 48u; break; } case 8u: { + Alloc param_34 = cmd_alloc; + CmdRef param_35 = cmd_ref; + CmdImage fill_img = Cmd_Image_read(param_34, param_35, v_291); + uint2 param_36 = xy_uint; + CmdImage param_37 = fill_img; + spvUnsafeArray img; + img = fillImage(param_36, param_37, image_atlas); for (uint k_11 = 0u; k_11 < 8u; k_11++) + { + float4 fg_k_3 = img[k_11] * area[k_11]; + rgba[k_11] = (rgba[k_11] * (1.0 - fg_k_3.w)) + fg_k_3; + } + cmd_ref.offset += 12u; + break; + } + case 9u: + { + for (uint k_12 = 0u; k_12 < 8u; k_12++) { uint d_2 = min(clip_depth, 127u); - float4 param_34 = float4(rgba[k_11]); - uint _2184 = packsRGB(param_34); - blend_stack[d_2][k_11] = _2184; - rgba[k_11] = float4(0.0); + float4 param_38 = float4(rgba[k_12]); + uint _2454 = packsRGB(param_38); + blend_stack[d_2][k_12] = _2454; + rgba[k_12] = float4(0.0); } clip_depth++; cmd_ref.offset += 4u; break; } - case 9u: + case 10u: { - Alloc param_35 = cmd_alloc; - CmdRef param_36 = cmd_ref; - CmdEndClip end_clip = Cmd_EndClip_read(param_35, param_36, v_278); + Alloc param_39 = cmd_alloc; + CmdRef param_40 = cmd_ref; + CmdEndClip end_clip = Cmd_EndClip_read(param_39, param_40, v_291); uint blend_mode = end_clip.blend >> uint(8); uint comp_mode = end_clip.blend & 255u; clip_depth--; - for (uint k_12 = 0u; k_12 < 8u; k_12++) + for (uint k_13 = 0u; k_13 < 8u; k_13++) { uint d_3 = min(clip_depth, 127u); - uint param_37 = blend_stack[d_3][k_12]; - float4 bg = unpacksRGB(param_37); - float4 fg_1 = rgba[k_12] * area[k_12]; - float3 param_38 = bg.xyz; - float3 param_39 = fg_1.xyz; - uint param_40 = blend_mode; - float3 blend = mix_blend(param_38, param_39, param_40); - float4 _2251 = fg_1; - float _2255 = fg_1.w; - float3 _2262 = mix(_2251.xyz, blend, float3(float((_2255 * bg.w) > 0.0))); - fg_1.x = _2262.x; - fg_1.y = _2262.y; - fg_1.z = _2262.z; - float3 param_41 = bg.xyz; - float3 param_42 = fg_1.xyz; - float param_43 = bg.w; - float param_44 = fg_1.w; - uint param_45 = comp_mode; - rgba[k_12] = mix_compose(param_41, param_42, param_43, param_44, param_45); + uint param_41 = blend_stack[d_3][k_13]; + float4 bg = unpacksRGB(param_41); + float4 fg_1 = rgba[k_13] * area[k_13]; + float3 param_42 = bg.xyz; + float3 param_43 = fg_1.xyz; + uint param_44 = blend_mode; + float3 blend = mix_blend(param_42, param_43, param_44); + float4 _2521 = fg_1; + float _2525 = fg_1.w; + float3 _2532 = mix(_2521.xyz, blend, float3(float((_2525 * bg.w) > 0.0))); + fg_1.x = _2532.x; + fg_1.y = _2532.y; + fg_1.z = _2532.z; + float3 param_45 = bg.xyz; + float3 param_46 = fg_1.xyz; + float param_47 = bg.w; + float param_48 = fg_1.w; + uint param_49 = comp_mode; + rgba[k_13] = mix_compose(param_45, param_46, param_47, param_48, param_49); } cmd_ref.offset += 8u; break; } - case 10u: + case 11u: { - Alloc param_46 = cmd_alloc; - CmdRef param_47 = cmd_ref; - cmd_ref = CmdRef{ Cmd_Jump_read(param_46, param_47, v_278).new_ref }; + Alloc param_50 = cmd_alloc; + CmdRef param_51 = cmd_ref; + cmd_ref = CmdRef{ Cmd_Jump_read(param_50, param_51, v_291).new_ref }; cmd_alloc.offset = cmd_ref.offset; break; } @@ -1203,9 +1300,9 @@ kernel void main0(device Memory& v_278 [[buffer(0)]], const device ConfigBuf& _1 } for (uint i_1 = 0u; i_1 < 8u; i_1++) { - uint param_48 = i_1; - float3 param_49 = rgba[i_1].xyz; - image.write(float4(tosRGB(param_49), rgba[i_1].w), uint2(int2(xy_uint + chunk_offset(param_48)))); + uint param_52 = i_1; + float3 param_53 = rgba[i_1].xyz; + image.write(float4(tosRGB(param_53), rgba[i_1].w), uint2(int2(xy_uint + chunk_offset(param_52)))); } } diff --git a/piet-gpu/shader/gen/kernel4.spv b/piet-gpu/shader/gen/kernel4.spv index 91272da225f52879a626483478c6068cdabb6a3d..70612634a5e2d8a7713d8107b6f1da6aafffa287 100644 GIT binary patch literal 65556 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 literal 58596 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 diff --git a/piet-gpu/shader/gen/kernel4_gray.dxil b/piet-gpu/shader/gen/kernel4_gray.dxil index 18c4b7eab4faa745a72e49be704b48803ad300d8..046045f51c54cb050580f10b12ea5046b1b56a4f 100644 GIT binary patch delta 10374 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 F{|8H{zwrP7 delta 9433 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 V!do)nnPNun%sc}2-)JWP{Vy0$69NDL diff --git a/piet-gpu/shader/gen/kernel4_gray.hlsl b/piet-gpu/shader/gen/kernel4_gray.hlsl index de95771..019a73c 100644 --- a/piet-gpu/shader/gen/kernel4_gray.hlsl +++ b/piet-gpu/shader/gen/kernel4_gray.hlsl @@ -48,6 +48,21 @@ struct CmdLinGrad float line_c; }; +struct CmdRadGradRef +{ + uint offset; +}; + +struct CmdRadGrad +{ + uint index; + float4 mat; + float2 xlat; + float2 c1; + float ra; + float roff; +}; + struct CmdImageRef { uint offset; @@ -146,8 +161,8 @@ struct Config static const uint3 gl_WorkGroupSize = uint3(8u, 4u, 1u); -RWByteAddressBuffer _278 : register(u0, space0); -ByteAddressBuffer _1521 : register(t1, space0); +RWByteAddressBuffer _291 : register(u0, space0); +ByteAddressBuffer _1666 : register(t1, space0); RWTexture2D image_atlas : register(u3, space0); RWTexture2D gradients : register(u4, space0); RWTexture2D image : register(u2, space0); @@ -174,8 +189,8 @@ float4 spvUnpackUnorm4x8(uint value) Alloc slice_mem(Alloc a, uint offset, uint size) { - Alloc _291 = { a.offset + offset }; - return _291; + Alloc _304 = { a.offset + offset }; + return _304; } bool touch_mem(Alloc alloc, uint offset) @@ -191,7 +206,7 @@ uint read_mem(Alloc alloc, uint offset) { return 0u; } - uint v = _278.Load(offset * 4 + 8); + uint v = _291.Load(offset * 4 + 8); return v; } @@ -200,8 +215,8 @@ CmdTag Cmd_tag(Alloc a, CmdRef ref) Alloc param = a; uint param_1 = ref.offset >> uint(2); uint tag_and_flags = read_mem(param, param_1); - CmdTag _525 = { tag_and_flags & 65535u, tag_and_flags >> uint(16) }; - return _525; + CmdTag _663 = { tag_and_flags & 65535u, tag_and_flags >> uint(16) }; + return _663; } CmdStroke CmdStroke_read(Alloc a, CmdStrokeRef ref) @@ -221,9 +236,9 @@ CmdStroke CmdStroke_read(Alloc a, CmdStrokeRef ref) CmdStroke Cmd_Stroke_read(Alloc a, CmdRef ref) { - CmdStrokeRef _542 = { ref.offset + 4u }; + CmdStrokeRef _679 = { ref.offset + 4u }; Alloc param = a; - CmdStrokeRef param_1 = _542; + CmdStrokeRef param_1 = _679; return CmdStroke_read(param, param_1); } @@ -259,8 +274,8 @@ TileSeg TileSeg_read(Alloc a, TileSegRef ref) s.origin = float2(asfloat(raw0), asfloat(raw1)); s._vector = float2(asfloat(raw2), asfloat(raw3)); s.y_edge = asfloat(raw4); - TileSegRef _675 = { raw5 }; - s.next = _675; + TileSegRef _820 = { raw5 }; + s.next = _820; return s; } @@ -286,9 +301,9 @@ CmdFill CmdFill_read(Alloc a, CmdFillRef ref) CmdFill Cmd_Fill_read(Alloc a, CmdRef ref) { - CmdFillRef _532 = { ref.offset + 4u }; + CmdFillRef _669 = { ref.offset + 4u }; Alloc param = a; - CmdFillRef param_1 = _532; + CmdFillRef param_1 = _669; return CmdFill_read(param, param_1); } @@ -305,9 +320,9 @@ CmdAlpha CmdAlpha_read(Alloc a, CmdAlphaRef ref) CmdAlpha Cmd_Alpha_read(Alloc a, CmdRef ref) { - CmdAlphaRef _552 = { ref.offset + 4u }; + CmdAlphaRef _689 = { ref.offset + 4u }; Alloc param = a; - CmdAlphaRef param_1 = _552; + CmdAlphaRef param_1 = _689; return CmdAlpha_read(param, param_1); } @@ -324,9 +339,9 @@ CmdColor CmdColor_read(Alloc a, CmdColorRef ref) CmdColor Cmd_Color_read(Alloc a, CmdRef ref) { - CmdColorRef _562 = { ref.offset + 4u }; + CmdColorRef _699 = { ref.offset + 4u }; Alloc param = a; - CmdColorRef param_1 = _562; + CmdColorRef param_1 = _699; return CmdColor_read(param, param_1); } @@ -370,12 +385,66 @@ CmdLinGrad CmdLinGrad_read(Alloc a, CmdLinGradRef ref) CmdLinGrad Cmd_LinGrad_read(Alloc a, CmdRef ref) { - CmdLinGradRef _572 = { ref.offset + 4u }; + CmdLinGradRef _709 = { ref.offset + 4u }; Alloc param = a; - CmdLinGradRef param_1 = _572; + CmdLinGradRef param_1 = _709; return CmdLinGrad_read(param, param_1); } +CmdRadGrad CmdRadGrad_read(Alloc a, CmdRadGradRef ref) +{ + uint ix = ref.offset >> uint(2); + Alloc param = a; + uint param_1 = ix + 0u; + uint raw0 = read_mem(param, param_1); + Alloc param_2 = a; + uint param_3 = ix + 1u; + uint raw1 = read_mem(param_2, param_3); + Alloc param_4 = a; + uint param_5 = ix + 2u; + uint raw2 = read_mem(param_4, param_5); + Alloc param_6 = a; + uint param_7 = ix + 3u; + uint raw3 = read_mem(param_6, param_7); + Alloc param_8 = a; + uint param_9 = ix + 4u; + uint raw4 = read_mem(param_8, param_9); + Alloc param_10 = a; + uint param_11 = ix + 5u; + uint raw5 = read_mem(param_10, param_11); + Alloc param_12 = a; + uint param_13 = ix + 6u; + uint raw6 = read_mem(param_12, param_13); + Alloc param_14 = a; + uint param_15 = ix + 7u; + uint raw7 = read_mem(param_14, param_15); + Alloc param_16 = a; + uint param_17 = ix + 8u; + uint raw8 = read_mem(param_16, param_17); + Alloc param_18 = a; + uint param_19 = ix + 9u; + uint raw9 = read_mem(param_18, param_19); + Alloc param_20 = a; + uint param_21 = ix + 10u; + uint raw10 = read_mem(param_20, param_21); + CmdRadGrad s; + s.index = raw0; + s.mat = float4(asfloat(raw1), asfloat(raw2), asfloat(raw3), asfloat(raw4)); + s.xlat = float2(asfloat(raw5), asfloat(raw6)); + s.c1 = float2(asfloat(raw7), asfloat(raw8)); + s.ra = asfloat(raw9); + s.roff = asfloat(raw10); + return s; +} + +CmdRadGrad Cmd_RadGrad_read(Alloc a, CmdRef ref) +{ + CmdRadGradRef _719 = { ref.offset + 4u }; + Alloc param = a; + CmdRadGradRef param_1 = _719; + return CmdRadGrad_read(param, param_1); +} + CmdImage CmdImage_read(Alloc a, CmdImageRef ref) { uint ix = ref.offset >> uint(2); @@ -393,9 +462,9 @@ CmdImage CmdImage_read(Alloc a, CmdImageRef ref) CmdImage Cmd_Image_read(Alloc a, CmdRef ref) { - CmdImageRef _582 = { ref.offset + 4u }; + CmdImageRef _729 = { ref.offset + 4u }; Alloc param = a; - CmdImageRef param_1 = _582; + CmdImageRef param_1 = _729; return CmdImage_read(param, param_1); } @@ -408,10 +477,10 @@ void fillImage(out float4 spvReturnValue[8], uint2 xy, CmdImage cmd_img) int2 uv = int2(xy + chunk_offset(param)) + cmd_img.offset; float4 fg_rgba = image_atlas[uv]; float3 param_1 = fg_rgba.xyz; - float3 _1493 = fromsRGB(param_1); - fg_rgba.x = _1493.x; - fg_rgba.y = _1493.y; - fg_rgba.z = _1493.z; + float3 _1638 = fromsRGB(param_1); + fg_rgba.x = _1638.x; + fg_rgba.y = _1638.y; + fg_rgba.z = _1638.z; rgba[i] = fg_rgba; } spvReturnValue = rgba; @@ -445,9 +514,9 @@ CmdEndClip CmdEndClip_read(Alloc a, CmdEndClipRef ref) CmdEndClip Cmd_EndClip_read(Alloc a, CmdRef ref) { - CmdEndClipRef _592 = { ref.offset + 4u }; + CmdEndClipRef _739 = { ref.offset + 4u }; Alloc param = a; - CmdEndClipRef param_1 = _592; + CmdEndClipRef param_1 = _739; return CmdEndClip_read(param, param_1); } @@ -637,8 +706,8 @@ float3 set_lum(float3 c, float l) { float3 param = c; float3 param_1 = c + (l - lum(param)).xxx; - float3 _901 = clip_color(param_1); - return _901; + float3 _1046 = clip_color(param_1); + return _1046; } float3 mix_blend(float3 cb, float3 cs, uint mode) @@ -726,9 +795,9 @@ float3 mix_blend(float3 cb, float3 cs, uint mode) float3 param_20 = cb; float3 param_21 = cs; float param_22 = sat(param_20); - float3 _1192 = set_sat(param_21, param_22); + float3 _1337 = set_sat(param_21, param_22); float3 param_23 = cb; - float3 param_24 = _1192; + float3 param_24 = _1337; float param_25 = lum(param_23); b = set_lum(param_24, param_25); break; @@ -738,9 +807,9 @@ float3 mix_blend(float3 cb, float3 cs, uint mode) float3 param_26 = cs; float3 param_27 = cb; float param_28 = sat(param_26); - float3 _1206 = set_sat(param_27, param_28); + float3 _1351 = set_sat(param_27, param_28); float3 param_29 = cb; - float3 param_30 = _1206; + float3 param_30 = _1351; float param_31 = lum(param_29); b = set_lum(param_30, param_31); break; @@ -877,24 +946,24 @@ CmdJump CmdJump_read(Alloc a, CmdJumpRef ref) CmdJump Cmd_Jump_read(Alloc a, CmdRef ref) { - CmdJumpRef _602 = { ref.offset + 4u }; + CmdJumpRef _749 = { ref.offset + 4u }; Alloc param = a; - CmdJumpRef param_1 = _602; + CmdJumpRef param_1 = _749; return CmdJump_read(param, param_1); } void comp_main() { - uint tile_ix = (gl_WorkGroupID.y * _1521.Load(8)) + gl_WorkGroupID.x; - Alloc _1536; - _1536.offset = _1521.Load(24); + uint tile_ix = (gl_WorkGroupID.y * _1666.Load(8)) + gl_WorkGroupID.x; + Alloc _1681; + _1681.offset = _1666.Load(24); Alloc param; - param.offset = _1536.offset; + param.offset = _1681.offset; uint param_1 = tile_ix * 1024u; uint param_2 = 1024u; Alloc cmd_alloc = slice_mem(param, param_1, param_2); - CmdRef _1545 = { cmd_alloc.offset }; - CmdRef cmd_ref = _1545; + CmdRef _1690 = { cmd_alloc.offset }; + CmdRef cmd_ref = _1690; uint2 xy_uint = uint2(gl_LocalInvocationID.x + (16u * gl_WorkGroupID.x), gl_LocalInvocationID.y + (16u * gl_WorkGroupID.y)); float2 xy = float2(xy_uint); float4 rgba[8]; @@ -903,7 +972,7 @@ void comp_main() rgba[i] = 0.0f.xxxx; } uint clip_depth = 0u; - bool mem_ok = _278.Load(4) == 0u; + bool mem_ok = _291.Load(4) == 0u; float df[8]; TileSegRef tile_seg_ref; float area[8]; @@ -928,8 +997,8 @@ void comp_main() { df[k] = 1000000000.0f; } - TileSegRef _1638 = { stroke.tile_ref }; - tile_seg_ref = _1638; + TileSegRef _1784 = { stroke.tile_ref }; + tile_seg_ref = _1784; do { uint param_7 = tile_seg_ref.offset; @@ -965,8 +1034,8 @@ void comp_main() { area[k_3] = float(fill.backdrop); } - TileSegRef _1758 = { fill.tile_ref }; - tile_seg_ref = _1758; + TileSegRef _1904 = { fill.tile_ref }; + tile_seg_ref = _1904; do { uint param_15 = tile_seg_ref.offset; @@ -1055,11 +1124,12 @@ void comp_main() int x = int(round(clamp(my_d, 0.0f, 1.0f) * 511.0f)); float4 fg_rgba = gradients[int2(x, int(lin.index))]; float3 param_29 = fg_rgba.xyz; - float3 _2092 = fromsRGB(param_29); - fg_rgba.x = _2092.x; - fg_rgba.y = _2092.y; - fg_rgba.z = _2092.z; - rgba[k_9] = fg_rgba; + float3 _2238 = fromsRGB(param_29); + fg_rgba.x = _2238.x; + fg_rgba.y = _2238.y; + fg_rgba.z = _2238.z; + float4 fg_k_1 = fg_rgba * area[k_9]; + rgba[k_9] = (rgba[k_9] * (1.0f - fg_k_1.w)) + fg_k_1; } cmd_ref.offset += 20u; break; @@ -1068,74 +1138,100 @@ void comp_main() { Alloc param_30 = cmd_alloc; CmdRef param_31 = cmd_ref; - CmdImage fill_img = Cmd_Image_read(param_30, param_31); - uint2 param_32 = xy_uint; - CmdImage param_33 = fill_img; - float4 _2121[8]; - fillImage(_2121, param_32, param_33); - float4 img[8] = _2121; + CmdRadGrad rad = Cmd_RadGrad_read(param_30, param_31); for (uint k_10 = 0u; k_10 < 8u; k_10++) { - float4 fg_k_1 = img[k_10] * area[k_10]; - rgba[k_10] = (rgba[k_10] * (1.0f - fg_k_1.w)) + fg_k_1; + uint param_32 = k_10; + float2 my_xy_1 = xy + float2(chunk_offset(param_32)); + my_xy_1 = ((rad.mat.xz * my_xy_1.x) + (rad.mat.yw * my_xy_1.y)) - rad.xlat; + float ba = dot(my_xy_1, rad.c1); + float ca = rad.ra * dot(my_xy_1, my_xy_1); + float t_2 = (sqrt((ba * ba) + ca) - ba) - rad.roff; + int x_1 = int(round(clamp(t_2, 0.0f, 1.0f) * 511.0f)); + float4 fg_rgba_1 = gradients[int2(x_1, int(rad.index))]; + float3 param_33 = fg_rgba_1.xyz; + float3 _2348 = fromsRGB(param_33); + fg_rgba_1.x = _2348.x; + fg_rgba_1.y = _2348.y; + fg_rgba_1.z = _2348.z; + float4 fg_k_2 = fg_rgba_1 * area[k_10]; + rgba[k_10] = (rgba[k_10] * (1.0f - fg_k_2.w)) + fg_k_2; } - cmd_ref.offset += 12u; + cmd_ref.offset += 48u; break; } case 8u: { + Alloc param_34 = cmd_alloc; + CmdRef param_35 = cmd_ref; + CmdImage fill_img = Cmd_Image_read(param_34, param_35); + uint2 param_36 = xy_uint; + CmdImage param_37 = fill_img; + float4 _2391[8]; + fillImage(_2391, param_36, param_37); + float4 img[8] = _2391; for (uint k_11 = 0u; k_11 < 8u; k_11++) + { + float4 fg_k_3 = img[k_11] * area[k_11]; + rgba[k_11] = (rgba[k_11] * (1.0f - fg_k_3.w)) + fg_k_3; + } + cmd_ref.offset += 12u; + break; + } + case 9u: + { + for (uint k_12 = 0u; k_12 < 8u; k_12++) { uint d_2 = min(clip_depth, 127u); - float4 param_34 = float4(rgba[k_11]); - uint _2184 = packsRGB(param_34); - blend_stack[d_2][k_11] = _2184; - rgba[k_11] = 0.0f.xxxx; + float4 param_38 = float4(rgba[k_12]); + uint _2454 = packsRGB(param_38); + blend_stack[d_2][k_12] = _2454; + rgba[k_12] = 0.0f.xxxx; } clip_depth++; cmd_ref.offset += 4u; break; } - case 9u: + case 10u: { - Alloc param_35 = cmd_alloc; - CmdRef param_36 = cmd_ref; - CmdEndClip end_clip = Cmd_EndClip_read(param_35, param_36); + Alloc param_39 = cmd_alloc; + CmdRef param_40 = cmd_ref; + CmdEndClip end_clip = Cmd_EndClip_read(param_39, param_40); uint blend_mode = end_clip.blend >> uint(8); uint comp_mode = end_clip.blend & 255u; clip_depth--; - for (uint k_12 = 0u; k_12 < 8u; k_12++) + for (uint k_13 = 0u; k_13 < 8u; k_13++) { uint d_3 = min(clip_depth, 127u); - uint param_37 = blend_stack[d_3][k_12]; - float4 bg = unpacksRGB(param_37); - float4 fg_1 = rgba[k_12] * area[k_12]; - float3 param_38 = bg.xyz; - float3 param_39 = fg_1.xyz; - uint param_40 = blend_mode; - float3 blend = mix_blend(param_38, param_39, param_40); - float4 _2251 = fg_1; - float _2255 = fg_1.w; - float3 _2262 = lerp(_2251.xyz, blend, float((_2255 * bg.w) > 0.0f).xxx); - fg_1.x = _2262.x; - fg_1.y = _2262.y; - fg_1.z = _2262.z; - float3 param_41 = bg.xyz; - float3 param_42 = fg_1.xyz; - float param_43 = bg.w; - float param_44 = fg_1.w; - uint param_45 = comp_mode; - rgba[k_12] = mix_compose(param_41, param_42, param_43, param_44, param_45); + uint param_41 = blend_stack[d_3][k_13]; + float4 bg = unpacksRGB(param_41); + float4 fg_1 = rgba[k_13] * area[k_13]; + float3 param_42 = bg.xyz; + float3 param_43 = fg_1.xyz; + uint param_44 = blend_mode; + float3 blend = mix_blend(param_42, param_43, param_44); + float4 _2521 = fg_1; + float _2525 = fg_1.w; + float3 _2532 = lerp(_2521.xyz, blend, float((_2525 * bg.w) > 0.0f).xxx); + fg_1.x = _2532.x; + fg_1.y = _2532.y; + fg_1.z = _2532.z; + float3 param_45 = bg.xyz; + float3 param_46 = fg_1.xyz; + float param_47 = bg.w; + float param_48 = fg_1.w; + uint param_49 = comp_mode; + rgba[k_13] = mix_compose(param_45, param_46, param_47, param_48, param_49); } cmd_ref.offset += 8u; break; } - case 10u: + case 11u: { - Alloc param_46 = cmd_alloc; - CmdRef param_47 = cmd_ref; - CmdRef _2299 = { Cmd_Jump_read(param_46, param_47).new_ref }; - cmd_ref = _2299; + Alloc param_50 = cmd_alloc; + CmdRef param_51 = cmd_ref; + CmdRef _2569 = { Cmd_Jump_read(param_50, param_51).new_ref }; + cmd_ref = _2569; cmd_alloc.offset = cmd_ref.offset; break; } @@ -1143,8 +1239,8 @@ void comp_main() } for (uint i_1 = 0u; i_1 < 8u; i_1++) { - uint param_48 = i_1; - image[int2(xy_uint + chunk_offset(param_48))] = rgba[i_1].w.x; + uint param_52 = i_1; + image[int2(xy_uint + chunk_offset(param_52))] = rgba[i_1].w.x; } } diff --git a/piet-gpu/shader/gen/kernel4_gray.msl b/piet-gpu/shader/gen/kernel4_gray.msl index 5128e99..6402c6f 100644 --- a/piet-gpu/shader/gen/kernel4_gray.msl +++ b/piet-gpu/shader/gen/kernel4_gray.msl @@ -94,6 +94,21 @@ struct CmdLinGrad float line_c; }; +struct CmdRadGradRef +{ + uint offset; +}; + +struct CmdRadGrad +{ + uint index; + float4 mat; + float2 xlat; + float2 c1; + float ra; + float roff; +}; + struct CmdImageRef { uint offset; @@ -222,7 +237,7 @@ bool touch_mem(thread const Alloc& alloc, thread const uint& offset) } static inline __attribute__((always_inline)) -uint read_mem(thread const Alloc& alloc, thread const uint& offset, device Memory& v_278) +uint read_mem(thread const Alloc& alloc, thread const uint& offset, device Memory& v_291) { Alloc param = alloc; uint param_1 = offset; @@ -230,29 +245,29 @@ uint read_mem(thread const Alloc& alloc, thread const uint& offset, device Memor { return 0u; } - uint v = v_278.memory[offset]; + uint v = v_291.memory[offset]; return v; } static inline __attribute__((always_inline)) -CmdTag Cmd_tag(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_278) +CmdTag Cmd_tag(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_291) { Alloc param = a; uint param_1 = ref.offset >> uint(2); - uint tag_and_flags = read_mem(param, param_1, v_278); + uint tag_and_flags = read_mem(param, param_1, v_291); return CmdTag{ tag_and_flags & 65535u, tag_and_flags >> uint(16) }; } static inline __attribute__((always_inline)) -CmdStroke CmdStroke_read(thread const Alloc& a, thread const CmdStrokeRef& ref, device Memory& v_278) +CmdStroke CmdStroke_read(thread const Alloc& a, thread const CmdStrokeRef& ref, device Memory& v_291) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; - uint raw0 = read_mem(param, param_1, v_278); + uint raw0 = read_mem(param, param_1, v_291); Alloc param_2 = a; uint param_3 = ix + 1u; - uint raw1 = read_mem(param_2, param_3, v_278); + uint raw1 = read_mem(param_2, param_3, v_291); CmdStroke s; s.tile_ref = raw0; s.half_width = as_type(raw1); @@ -260,11 +275,11 @@ CmdStroke CmdStroke_read(thread const Alloc& a, thread const CmdStrokeRef& ref, } static inline __attribute__((always_inline)) -CmdStroke Cmd_Stroke_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_278) +CmdStroke Cmd_Stroke_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_291) { Alloc param = a; CmdStrokeRef param_1 = CmdStrokeRef{ ref.offset + 4u }; - return CmdStroke_read(param, param_1, v_278); + return CmdStroke_read(param, param_1, v_291); } static inline __attribute__((always_inline)) @@ -276,27 +291,27 @@ Alloc new_alloc(thread const uint& offset, thread const uint& size, thread const } static inline __attribute__((always_inline)) -TileSeg TileSeg_read(thread const Alloc& a, thread const TileSegRef& ref, device Memory& v_278) +TileSeg TileSeg_read(thread const Alloc& a, thread const TileSegRef& ref, device Memory& v_291) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; - uint raw0 = read_mem(param, param_1, v_278); + uint raw0 = read_mem(param, param_1, v_291); Alloc param_2 = a; uint param_3 = ix + 1u; - uint raw1 = read_mem(param_2, param_3, v_278); + uint raw1 = read_mem(param_2, param_3, v_291); Alloc param_4 = a; uint param_5 = ix + 2u; - uint raw2 = read_mem(param_4, param_5, v_278); + uint raw2 = read_mem(param_4, param_5, v_291); Alloc param_6 = a; uint param_7 = ix + 3u; - uint raw3 = read_mem(param_6, param_7, v_278); + uint raw3 = read_mem(param_6, param_7, v_291); Alloc param_8 = a; uint param_9 = ix + 4u; - uint raw4 = read_mem(param_8, param_9, v_278); + uint raw4 = read_mem(param_8, param_9, v_291); Alloc param_10 = a; uint param_11 = ix + 5u; - uint raw5 = read_mem(param_10, param_11, v_278); + uint raw5 = read_mem(param_10, param_11, v_291); TileSeg s; s.origin = float2(as_type(raw0), as_type(raw1)); s.vector = float2(as_type(raw2), as_type(raw3)); @@ -312,15 +327,15 @@ uint2 chunk_offset(thread const uint& i) } static inline __attribute__((always_inline)) -CmdFill CmdFill_read(thread const Alloc& a, thread const CmdFillRef& ref, device Memory& v_278) +CmdFill CmdFill_read(thread const Alloc& a, thread const CmdFillRef& ref, device Memory& v_291) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; - uint raw0 = read_mem(param, param_1, v_278); + uint raw0 = read_mem(param, param_1, v_291); Alloc param_2 = a; uint param_3 = ix + 1u; - uint raw1 = read_mem(param_2, param_3, v_278); + uint raw1 = read_mem(param_2, param_3, v_291); CmdFill s; s.tile_ref = raw0; s.backdrop = int(raw1); @@ -328,51 +343,51 @@ CmdFill CmdFill_read(thread const Alloc& a, thread const CmdFillRef& ref, device } static inline __attribute__((always_inline)) -CmdFill Cmd_Fill_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_278) +CmdFill Cmd_Fill_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_291) { Alloc param = a; CmdFillRef param_1 = CmdFillRef{ ref.offset + 4u }; - return CmdFill_read(param, param_1, v_278); + return CmdFill_read(param, param_1, v_291); } static inline __attribute__((always_inline)) -CmdAlpha CmdAlpha_read(thread const Alloc& a, thread const CmdAlphaRef& ref, device Memory& v_278) +CmdAlpha CmdAlpha_read(thread const Alloc& a, thread const CmdAlphaRef& ref, device Memory& v_291) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; - uint raw0 = read_mem(param, param_1, v_278); + uint raw0 = read_mem(param, param_1, v_291); CmdAlpha s; s.alpha = as_type(raw0); return s; } static inline __attribute__((always_inline)) -CmdAlpha Cmd_Alpha_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_278) +CmdAlpha Cmd_Alpha_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_291) { Alloc param = a; CmdAlphaRef param_1 = CmdAlphaRef{ ref.offset + 4u }; - return CmdAlpha_read(param, param_1, v_278); + return CmdAlpha_read(param, param_1, v_291); } static inline __attribute__((always_inline)) -CmdColor CmdColor_read(thread const Alloc& a, thread const CmdColorRef& ref, device Memory& v_278) +CmdColor CmdColor_read(thread const Alloc& a, thread const CmdColorRef& ref, device Memory& v_291) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; - uint raw0 = read_mem(param, param_1, v_278); + uint raw0 = read_mem(param, param_1, v_291); CmdColor s; s.rgba_color = raw0; return s; } static inline __attribute__((always_inline)) -CmdColor Cmd_Color_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_278) +CmdColor Cmd_Color_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_291) { Alloc param = a; CmdColorRef param_1 = CmdColorRef{ ref.offset + 4u }; - return CmdColor_read(param, param_1, v_278); + return CmdColor_read(param, param_1, v_291); } static inline __attribute__((always_inline)) @@ -393,21 +408,21 @@ float4 unpacksRGB(thread const uint& srgba) } static inline __attribute__((always_inline)) -CmdLinGrad CmdLinGrad_read(thread const Alloc& a, thread const CmdLinGradRef& ref, device Memory& v_278) +CmdLinGrad CmdLinGrad_read(thread const Alloc& a, thread const CmdLinGradRef& ref, device Memory& v_291) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; - uint raw0 = read_mem(param, param_1, v_278); + uint raw0 = read_mem(param, param_1, v_291); Alloc param_2 = a; uint param_3 = ix + 1u; - uint raw1 = read_mem(param_2, param_3, v_278); + uint raw1 = read_mem(param_2, param_3, v_291); Alloc param_4 = a; uint param_5 = ix + 2u; - uint raw2 = read_mem(param_4, param_5, v_278); + uint raw2 = read_mem(param_4, param_5, v_291); Alloc param_6 = a; uint param_7 = ix + 3u; - uint raw3 = read_mem(param_6, param_7, v_278); + uint raw3 = read_mem(param_6, param_7, v_291); CmdLinGrad s; s.index = raw0; s.line_x = as_type(raw1); @@ -417,23 +432,78 @@ CmdLinGrad CmdLinGrad_read(thread const Alloc& a, thread const CmdLinGradRef& re } static inline __attribute__((always_inline)) -CmdLinGrad Cmd_LinGrad_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_278) +CmdLinGrad Cmd_LinGrad_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_291) { Alloc param = a; CmdLinGradRef param_1 = CmdLinGradRef{ ref.offset + 4u }; - return CmdLinGrad_read(param, param_1, v_278); + return CmdLinGrad_read(param, param_1, v_291); } static inline __attribute__((always_inline)) -CmdImage CmdImage_read(thread const Alloc& a, thread const CmdImageRef& ref, device Memory& v_278) +CmdRadGrad CmdRadGrad_read(thread const Alloc& a, thread const CmdRadGradRef& ref, device Memory& v_291) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; - uint raw0 = read_mem(param, param_1, v_278); + uint raw0 = read_mem(param, param_1, v_291); Alloc param_2 = a; uint param_3 = ix + 1u; - uint raw1 = read_mem(param_2, param_3, v_278); + uint raw1 = read_mem(param_2, param_3, v_291); + Alloc param_4 = a; + uint param_5 = ix + 2u; + uint raw2 = read_mem(param_4, param_5, v_291); + Alloc param_6 = a; + uint param_7 = ix + 3u; + uint raw3 = read_mem(param_6, param_7, v_291); + Alloc param_8 = a; + uint param_9 = ix + 4u; + uint raw4 = read_mem(param_8, param_9, v_291); + Alloc param_10 = a; + uint param_11 = ix + 5u; + uint raw5 = read_mem(param_10, param_11, v_291); + Alloc param_12 = a; + uint param_13 = ix + 6u; + uint raw6 = read_mem(param_12, param_13, v_291); + Alloc param_14 = a; + uint param_15 = ix + 7u; + uint raw7 = read_mem(param_14, param_15, v_291); + Alloc param_16 = a; + uint param_17 = ix + 8u; + uint raw8 = read_mem(param_16, param_17, v_291); + Alloc param_18 = a; + uint param_19 = ix + 9u; + uint raw9 = read_mem(param_18, param_19, v_291); + Alloc param_20 = a; + uint param_21 = ix + 10u; + uint raw10 = read_mem(param_20, param_21, v_291); + CmdRadGrad s; + s.index = raw0; + s.mat = float4(as_type(raw1), as_type(raw2), as_type(raw3), as_type(raw4)); + s.xlat = float2(as_type(raw5), as_type(raw6)); + s.c1 = float2(as_type(raw7), as_type(raw8)); + s.ra = as_type(raw9); + s.roff = as_type(raw10); + return s; +} + +static inline __attribute__((always_inline)) +CmdRadGrad Cmd_RadGrad_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_291) +{ + Alloc param = a; + CmdRadGradRef param_1 = CmdRadGradRef{ ref.offset + 4u }; + return CmdRadGrad_read(param, param_1, v_291); +} + +static inline __attribute__((always_inline)) +CmdImage CmdImage_read(thread const Alloc& a, thread const CmdImageRef& ref, device Memory& v_291) +{ + uint ix = ref.offset >> uint(2); + Alloc param = a; + uint param_1 = ix + 0u; + uint raw0 = read_mem(param, param_1, v_291); + Alloc param_2 = a; + uint param_3 = ix + 1u; + uint raw1 = read_mem(param_2, param_3, v_291); CmdImage s; s.index = raw0; s.offset = int2(int(raw1 << uint(16)) >> 16, int(raw1) >> 16); @@ -441,11 +511,11 @@ CmdImage CmdImage_read(thread const Alloc& a, thread const CmdImageRef& ref, dev } static inline __attribute__((always_inline)) -CmdImage Cmd_Image_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_278) +CmdImage Cmd_Image_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_291) { Alloc param = a; CmdImageRef param_1 = CmdImageRef{ ref.offset + 4u }; - return CmdImage_read(param, param_1, v_278); + return CmdImage_read(param, param_1, v_291); } static inline __attribute__((always_inline)) @@ -458,10 +528,10 @@ spvUnsafeArray fillImage(thread const uint2& xy, thread const CmdImag int2 uv = int2(xy + chunk_offset(param)) + cmd_img.offset; float4 fg_rgba = image_atlas.read(uint2(uv)); float3 param_1 = fg_rgba.xyz; - float3 _1493 = fromsRGB(param_1); - fg_rgba.x = _1493.x; - fg_rgba.y = _1493.y; - fg_rgba.z = _1493.z; + float3 _1638 = fromsRGB(param_1); + fg_rgba.x = _1638.x; + fg_rgba.y = _1638.y; + fg_rgba.z = _1638.z; rgba[i] = fg_rgba; } return rgba; @@ -485,23 +555,23 @@ uint packsRGB(thread float4& rgba) } static inline __attribute__((always_inline)) -CmdEndClip CmdEndClip_read(thread const Alloc& a, thread const CmdEndClipRef& ref, device Memory& v_278) +CmdEndClip CmdEndClip_read(thread const Alloc& a, thread const CmdEndClipRef& ref, device Memory& v_291) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; - uint raw0 = read_mem(param, param_1, v_278); + uint raw0 = read_mem(param, param_1, v_291); CmdEndClip s; s.blend = raw0; return s; } static inline __attribute__((always_inline)) -CmdEndClip Cmd_EndClip_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_278) +CmdEndClip Cmd_EndClip_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_291) { Alloc param = a; CmdEndClipRef param_1 = CmdEndClipRef{ ref.offset + 4u }; - return CmdEndClip_read(param, param_1, v_278); + return CmdEndClip_read(param, param_1, v_291); } static inline __attribute__((always_inline)) @@ -701,8 +771,8 @@ float3 set_lum(thread const float3& c, thread const float& l) { float3 param = c; float3 param_1 = c + float3(l - lum(param)); - float3 _901 = clip_color(param_1); - return _901; + float3 _1046 = clip_color(param_1); + return _1046; } static inline __attribute__((always_inline)) @@ -791,9 +861,9 @@ float3 mix_blend(thread const float3& cb, thread const float3& cs, thread const float3 param_20 = cb; float3 param_21 = cs; float param_22 = sat(param_20); - float3 _1192 = set_sat(param_21, param_22); + float3 _1337 = set_sat(param_21, param_22); float3 param_23 = cb; - float3 param_24 = _1192; + float3 param_24 = _1337; float param_25 = lum(param_23); b = set_lum(param_24, param_25); break; @@ -803,9 +873,9 @@ float3 mix_blend(thread const float3& cb, thread const float3& cs, thread const float3 param_26 = cs; float3 param_27 = cb; float param_28 = sat(param_26); - float3 _1206 = set_sat(param_27, param_28); + float3 _1351 = set_sat(param_27, param_28); float3 param_29 = cb; - float3 param_30 = _1206; + float3 param_30 = _1351; float param_31 = lum(param_29); b = set_lum(param_30, param_31); break; @@ -931,30 +1001,30 @@ float4 mix_compose(thread const float3& cb, thread const float3& cs, thread cons } static inline __attribute__((always_inline)) -CmdJump CmdJump_read(thread const Alloc& a, thread const CmdJumpRef& ref, device Memory& v_278) +CmdJump CmdJump_read(thread const Alloc& a, thread const CmdJumpRef& ref, device Memory& v_291) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; - uint raw0 = read_mem(param, param_1, v_278); + uint raw0 = read_mem(param, param_1, v_291); CmdJump s; s.new_ref = raw0; return s; } static inline __attribute__((always_inline)) -CmdJump Cmd_Jump_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_278) +CmdJump Cmd_Jump_read(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_291) { Alloc param = a; CmdJumpRef param_1 = CmdJumpRef{ ref.offset + 4u }; - return CmdJump_read(param, param_1, v_278); + return CmdJump_read(param, param_1, v_291); } -kernel void main0(device Memory& v_278 [[buffer(0)]], const device ConfigBuf& _1521 [[buffer(1)]], texture2d image [[texture(2)]], texture2d image_atlas [[texture(3)]], texture2d gradients [[texture(4)]], uint3 gl_WorkGroupID [[threadgroup_position_in_grid]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]]) +kernel void main0(device Memory& v_291 [[buffer(0)]], const device ConfigBuf& _1666 [[buffer(1)]], texture2d image [[texture(2)]], texture2d image_atlas [[texture(3)]], texture2d gradients [[texture(4)]], uint3 gl_WorkGroupID [[threadgroup_position_in_grid]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]]) { - uint tile_ix = (gl_WorkGroupID.y * _1521.conf.width_in_tiles) + gl_WorkGroupID.x; + uint tile_ix = (gl_WorkGroupID.y * _1666.conf.width_in_tiles) + gl_WorkGroupID.x; Alloc param; - param.offset = _1521.conf.ptcl_alloc.offset; + param.offset = _1666.conf.ptcl_alloc.offset; uint param_1 = tile_ix * 1024u; uint param_2 = 1024u; Alloc cmd_alloc = slice_mem(param, param_1, param_2); @@ -967,7 +1037,7 @@ kernel void main0(device Memory& v_278 [[buffer(0)]], const device ConfigBuf& _1 rgba[i] = float4(0.0); } uint clip_depth = 0u; - bool mem_ok = v_278.mem_error == 0u; + bool mem_ok = v_291.mem_error == 0u; spvUnsafeArray df; TileSegRef tile_seg_ref; spvUnsafeArray area; @@ -976,7 +1046,7 @@ kernel void main0(device Memory& v_278 [[buffer(0)]], const device ConfigBuf& _1 { Alloc param_3 = cmd_alloc; CmdRef param_4 = cmd_ref; - uint tag = Cmd_tag(param_3, param_4, v_278).tag; + uint tag = Cmd_tag(param_3, param_4, v_291).tag; if (tag == 0u) { break; @@ -987,7 +1057,7 @@ kernel void main0(device Memory& v_278 [[buffer(0)]], const device ConfigBuf& _1 { Alloc param_5 = cmd_alloc; CmdRef param_6 = cmd_ref; - CmdStroke stroke = Cmd_Stroke_read(param_5, param_6, v_278); + CmdStroke stroke = Cmd_Stroke_read(param_5, param_6, v_291); for (uint k = 0u; k < 8u; k++) { df[k] = 1000000000.0; @@ -1000,7 +1070,7 @@ kernel void main0(device Memory& v_278 [[buffer(0)]], const device ConfigBuf& _1 bool param_9 = mem_ok; Alloc param_10 = new_alloc(param_7, param_8, param_9); TileSegRef param_11 = tile_seg_ref; - TileSeg seg = TileSeg_read(param_10, param_11, v_278); + TileSeg seg = TileSeg_read(param_10, param_11, v_291); float2 line_vec = seg.vector; for (uint k_1 = 0u; k_1 < 8u; k_1++) { @@ -1023,7 +1093,7 @@ kernel void main0(device Memory& v_278 [[buffer(0)]], const device ConfigBuf& _1 { Alloc param_13 = cmd_alloc; CmdRef param_14 = cmd_ref; - CmdFill fill = Cmd_Fill_read(param_13, param_14, v_278); + CmdFill fill = Cmd_Fill_read(param_13, param_14, v_291); for (uint k_3 = 0u; k_3 < 8u; k_3++) { area[k_3] = float(fill.backdrop); @@ -1036,7 +1106,7 @@ kernel void main0(device Memory& v_278 [[buffer(0)]], const device ConfigBuf& _1 bool param_17 = mem_ok; Alloc param_18 = new_alloc(param_15, param_16, param_17); TileSegRef param_19 = tile_seg_ref; - TileSeg seg_1 = TileSeg_read(param_18, param_19, v_278); + TileSeg seg_1 = TileSeg_read(param_18, param_19, v_291); for (uint k_4 = 0u; k_4 < 8u; k_4++) { uint param_20 = k_4; @@ -1080,7 +1150,7 @@ kernel void main0(device Memory& v_278 [[buffer(0)]], const device ConfigBuf& _1 { Alloc param_21 = cmd_alloc; CmdRef param_22 = cmd_ref; - CmdAlpha alpha = Cmd_Alpha_read(param_21, param_22, v_278); + CmdAlpha alpha = Cmd_Alpha_read(param_21, param_22, v_291); for (uint k_7 = 0u; k_7 < 8u; k_7++) { area[k_7] = alpha.alpha; @@ -1092,7 +1162,7 @@ kernel void main0(device Memory& v_278 [[buffer(0)]], const device ConfigBuf& _1 { Alloc param_23 = cmd_alloc; CmdRef param_24 = cmd_ref; - CmdColor color = Cmd_Color_read(param_23, param_24, v_278); + CmdColor color = Cmd_Color_read(param_23, param_24, v_291); uint param_25 = color.rgba_color; float4 fg = unpacksRGB(param_25); for (uint k_8 = 0u; k_8 < 8u; k_8++) @@ -1107,7 +1177,7 @@ kernel void main0(device Memory& v_278 [[buffer(0)]], const device ConfigBuf& _1 { Alloc param_26 = cmd_alloc; CmdRef param_27 = cmd_ref; - CmdLinGrad lin = Cmd_LinGrad_read(param_26, param_27, v_278); + CmdLinGrad lin = Cmd_LinGrad_read(param_26, param_27, v_291); float d_1 = ((lin.line_x * xy.x) + (lin.line_y * xy.y)) + lin.line_c; for (uint k_9 = 0u; k_9 < 8u; k_9++) { @@ -1117,11 +1187,12 @@ kernel void main0(device Memory& v_278 [[buffer(0)]], const device ConfigBuf& _1 int x = int(round(fast::clamp(my_d, 0.0, 1.0) * 511.0)); float4 fg_rgba = gradients.read(uint2(int2(x, int(lin.index)))); float3 param_29 = fg_rgba.xyz; - float3 _2092 = fromsRGB(param_29); - fg_rgba.x = _2092.x; - fg_rgba.y = _2092.y; - fg_rgba.z = _2092.z; - rgba[k_9] = fg_rgba; + float3 _2238 = fromsRGB(param_29); + fg_rgba.x = _2238.x; + fg_rgba.y = _2238.y; + fg_rgba.z = _2238.z; + float4 fg_k_1 = fg_rgba * area[k_9]; + rgba[k_9] = (rgba[k_9] * (1.0 - fg_k_1.w)) + fg_k_1; } cmd_ref.offset += 20u; break; @@ -1130,72 +1201,98 @@ kernel void main0(device Memory& v_278 [[buffer(0)]], const device ConfigBuf& _1 { Alloc param_30 = cmd_alloc; CmdRef param_31 = cmd_ref; - CmdImage fill_img = Cmd_Image_read(param_30, param_31, v_278); - uint2 param_32 = xy_uint; - CmdImage param_33 = fill_img; - spvUnsafeArray img; - img = fillImage(param_32, param_33, image_atlas); + CmdRadGrad rad = Cmd_RadGrad_read(param_30, param_31, v_291); for (uint k_10 = 0u; k_10 < 8u; k_10++) { - float4 fg_k_1 = img[k_10] * area[k_10]; - rgba[k_10] = (rgba[k_10] * (1.0 - fg_k_1.w)) + fg_k_1; + uint param_32 = k_10; + float2 my_xy_1 = xy + float2(chunk_offset(param_32)); + my_xy_1 = ((rad.mat.xz * my_xy_1.x) + (rad.mat.yw * my_xy_1.y)) - rad.xlat; + float ba = dot(my_xy_1, rad.c1); + float ca = rad.ra * dot(my_xy_1, my_xy_1); + float t_2 = (sqrt((ba * ba) + ca) - ba) - rad.roff; + int x_1 = int(round(fast::clamp(t_2, 0.0, 1.0) * 511.0)); + float4 fg_rgba_1 = gradients.read(uint2(int2(x_1, int(rad.index)))); + float3 param_33 = fg_rgba_1.xyz; + float3 _2348 = fromsRGB(param_33); + fg_rgba_1.x = _2348.x; + fg_rgba_1.y = _2348.y; + fg_rgba_1.z = _2348.z; + float4 fg_k_2 = fg_rgba_1 * area[k_10]; + rgba[k_10] = (rgba[k_10] * (1.0 - fg_k_2.w)) + fg_k_2; } - cmd_ref.offset += 12u; + cmd_ref.offset += 48u; break; } case 8u: { + Alloc param_34 = cmd_alloc; + CmdRef param_35 = cmd_ref; + CmdImage fill_img = Cmd_Image_read(param_34, param_35, v_291); + uint2 param_36 = xy_uint; + CmdImage param_37 = fill_img; + spvUnsafeArray img; + img = fillImage(param_36, param_37, image_atlas); for (uint k_11 = 0u; k_11 < 8u; k_11++) + { + float4 fg_k_3 = img[k_11] * area[k_11]; + rgba[k_11] = (rgba[k_11] * (1.0 - fg_k_3.w)) + fg_k_3; + } + cmd_ref.offset += 12u; + break; + } + case 9u: + { + for (uint k_12 = 0u; k_12 < 8u; k_12++) { uint d_2 = min(clip_depth, 127u); - float4 param_34 = float4(rgba[k_11]); - uint _2184 = packsRGB(param_34); - blend_stack[d_2][k_11] = _2184; - rgba[k_11] = float4(0.0); + float4 param_38 = float4(rgba[k_12]); + uint _2454 = packsRGB(param_38); + blend_stack[d_2][k_12] = _2454; + rgba[k_12] = float4(0.0); } clip_depth++; cmd_ref.offset += 4u; break; } - case 9u: + case 10u: { - Alloc param_35 = cmd_alloc; - CmdRef param_36 = cmd_ref; - CmdEndClip end_clip = Cmd_EndClip_read(param_35, param_36, v_278); + Alloc param_39 = cmd_alloc; + CmdRef param_40 = cmd_ref; + CmdEndClip end_clip = Cmd_EndClip_read(param_39, param_40, v_291); uint blend_mode = end_clip.blend >> uint(8); uint comp_mode = end_clip.blend & 255u; clip_depth--; - for (uint k_12 = 0u; k_12 < 8u; k_12++) + for (uint k_13 = 0u; k_13 < 8u; k_13++) { uint d_3 = min(clip_depth, 127u); - uint param_37 = blend_stack[d_3][k_12]; - float4 bg = unpacksRGB(param_37); - float4 fg_1 = rgba[k_12] * area[k_12]; - float3 param_38 = bg.xyz; - float3 param_39 = fg_1.xyz; - uint param_40 = blend_mode; - float3 blend = mix_blend(param_38, param_39, param_40); - float4 _2251 = fg_1; - float _2255 = fg_1.w; - float3 _2262 = mix(_2251.xyz, blend, float3(float((_2255 * bg.w) > 0.0))); - fg_1.x = _2262.x; - fg_1.y = _2262.y; - fg_1.z = _2262.z; - float3 param_41 = bg.xyz; - float3 param_42 = fg_1.xyz; - float param_43 = bg.w; - float param_44 = fg_1.w; - uint param_45 = comp_mode; - rgba[k_12] = mix_compose(param_41, param_42, param_43, param_44, param_45); + uint param_41 = blend_stack[d_3][k_13]; + float4 bg = unpacksRGB(param_41); + float4 fg_1 = rgba[k_13] * area[k_13]; + float3 param_42 = bg.xyz; + float3 param_43 = fg_1.xyz; + uint param_44 = blend_mode; + float3 blend = mix_blend(param_42, param_43, param_44); + float4 _2521 = fg_1; + float _2525 = fg_1.w; + float3 _2532 = mix(_2521.xyz, blend, float3(float((_2525 * bg.w) > 0.0))); + fg_1.x = _2532.x; + fg_1.y = _2532.y; + fg_1.z = _2532.z; + float3 param_45 = bg.xyz; + float3 param_46 = fg_1.xyz; + float param_47 = bg.w; + float param_48 = fg_1.w; + uint param_49 = comp_mode; + rgba[k_13] = mix_compose(param_45, param_46, param_47, param_48, param_49); } cmd_ref.offset += 8u; break; } - case 10u: + case 11u: { - Alloc param_46 = cmd_alloc; - CmdRef param_47 = cmd_ref; - cmd_ref = CmdRef{ Cmd_Jump_read(param_46, param_47, v_278).new_ref }; + Alloc param_50 = cmd_alloc; + CmdRef param_51 = cmd_ref; + cmd_ref = CmdRef{ Cmd_Jump_read(param_50, param_51, v_291).new_ref }; cmd_alloc.offset = cmd_ref.offset; break; } @@ -1203,8 +1300,8 @@ kernel void main0(device Memory& v_278 [[buffer(0)]], const device ConfigBuf& _1 } for (uint i_1 = 0u; i_1 < 8u; i_1++) { - uint param_48 = i_1; - image.write(float4(rgba[i_1].w), uint2(int2(xy_uint + chunk_offset(param_48)))); + uint param_52 = i_1; + image.write(float4(rgba[i_1].w), uint2(int2(xy_uint + chunk_offset(param_52)))); } } diff --git a/piet-gpu/shader/gen/kernel4_gray.spv b/piet-gpu/shader/gen/kernel4_gray.spv index 791b76cbe5790b68def82df39f9028af0fbc4b61..4633401878da028ffb233d5fda00be249864c016 100644 GIT binary patch literal 65312 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 CD&wO7 literal 58352 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 LKhH(6=i>hd17EVE diff --git a/piet-gpu/shader/kernel4.comp b/piet-gpu/shader/kernel4.comp index a97715a..c49e2fa 100644 --- a/piet-gpu/shader/kernel4.comp +++ b/piet-gpu/shader/kernel4.comp @@ -192,10 +192,27 @@ void main() { int x = int(round(clamp(my_d, 0.0, 1.0) * float(GRADIENT_WIDTH - 1))); mediump vec4 fg_rgba = imageLoad(gradients, ivec2(x, int(lin.index))); fg_rgba.rgb = fromsRGB(fg_rgba.rgb); - rgba[k] = fg_rgba; + mediump vec4 fg_k = fg_rgba * area[k]; + rgba[k] = rgba[k] * (1.0 - fg_k.a) + fg_k; } cmd_ref.offset += 4 + CmdLinGrad_size; break; + case Cmd_RadGrad: + CmdRadGrad rad = Cmd_RadGrad_read(cmd_alloc, cmd_ref); + for (uint k = 0; k < CHUNK; k++) { + vec2 my_xy = xy + vec2(chunk_offset(k)); + my_xy = rad.mat.xz * my_xy.x + rad.mat.yw * my_xy.y - rad.xlat; + float ba = dot(my_xy, rad.c1); + float ca = rad.ra * dot(my_xy, my_xy); + float t = sqrt(ba * ba + ca) - ba - rad.roff; + int x = int(round(clamp(t, 0.0, 1.0) * float(GRADIENT_WIDTH - 1))); + mediump vec4 fg_rgba = imageLoad(gradients, ivec2(x, int(rad.index))); + fg_rgba.rgb = fromsRGB(fg_rgba.rgb); + mediump vec4 fg_k = fg_rgba * area[k]; + rgba[k] = rgba[k] * (1.0 - fg_k.a) + fg_k; + } + cmd_ref.offset += 4 + CmdRadGrad_size; + break; case Cmd_Image: CmdImage fill_img = Cmd_Image_read(cmd_alloc, cmd_ref); mediump vec4 img[CHUNK] = fillImage(xy_uint, fill_img); diff --git a/piet-gpu/shader/ptcl.h b/piet-gpu/shader/ptcl.h index 9b9b341..54dcc9e 100644 --- a/piet-gpu/shader/ptcl.h +++ b/piet-gpu/shader/ptcl.h @@ -18,6 +18,10 @@ struct CmdLinGradRef { uint offset; }; +struct CmdRadGradRef { + uint offset; +}; + struct CmdImageRef { uint offset; }; @@ -83,6 +87,21 @@ CmdLinGradRef CmdLinGrad_index(CmdLinGradRef ref, uint index) { return CmdLinGradRef(ref.offset + index * CmdLinGrad_size); } +struct CmdRadGrad { + uint index; + vec4 mat; + vec2 xlat; + vec2 c1; + float ra; + float roff; +}; + +#define CmdRadGrad_size 44 + +CmdRadGradRef CmdRadGrad_index(CmdRadGradRef ref, uint index) { + return CmdRadGradRef(ref.offset + index * CmdRadGrad_size); +} + struct CmdImage { uint index; ivec2 offset; @@ -131,11 +150,12 @@ CmdJumpRef CmdJump_index(CmdJumpRef ref, uint index) { #define Cmd_Alpha 4 #define Cmd_Color 5 #define Cmd_LinGrad 6 -#define Cmd_Image 7 -#define Cmd_BeginClip 8 -#define Cmd_EndClip 9 -#define Cmd_Jump 10 -#define Cmd_size 20 +#define Cmd_RadGrad 7 +#define Cmd_Image 8 +#define Cmd_BeginClip 9 +#define Cmd_EndClip 10 +#define Cmd_Jump 11 +#define Cmd_size 48 CmdRef Cmd_index(CmdRef ref, uint index) { return CmdRef(ref.offset + index * Cmd_size); @@ -213,6 +233,44 @@ void CmdLinGrad_write(Alloc a, CmdLinGradRef ref, CmdLinGrad s) { write_mem(a, ix + 3, floatBitsToUint(s.line_c)); } +CmdRadGrad CmdRadGrad_read(Alloc a, CmdRadGradRef ref) { + uint ix = ref.offset >> 2; + uint raw0 = read_mem(a, ix + 0); + uint raw1 = read_mem(a, ix + 1); + uint raw2 = read_mem(a, ix + 2); + uint raw3 = read_mem(a, ix + 3); + uint raw4 = read_mem(a, ix + 4); + uint raw5 = read_mem(a, ix + 5); + uint raw6 = read_mem(a, ix + 6); + uint raw7 = read_mem(a, ix + 7); + uint raw8 = read_mem(a, ix + 8); + uint raw9 = read_mem(a, ix + 9); + uint raw10 = read_mem(a, ix + 10); + CmdRadGrad s; + s.index = raw0; + s.mat = vec4(uintBitsToFloat(raw1), uintBitsToFloat(raw2), uintBitsToFloat(raw3), uintBitsToFloat(raw4)); + s.xlat = vec2(uintBitsToFloat(raw5), uintBitsToFloat(raw6)); + s.c1 = vec2(uintBitsToFloat(raw7), uintBitsToFloat(raw8)); + s.ra = uintBitsToFloat(raw9); + s.roff = uintBitsToFloat(raw10); + return s; +} + +void CmdRadGrad_write(Alloc a, CmdRadGradRef ref, CmdRadGrad s) { + uint ix = ref.offset >> 2; + write_mem(a, ix + 0, s.index); + write_mem(a, ix + 1, floatBitsToUint(s.mat.x)); + write_mem(a, ix + 2, floatBitsToUint(s.mat.y)); + write_mem(a, ix + 3, floatBitsToUint(s.mat.z)); + write_mem(a, ix + 4, floatBitsToUint(s.mat.w)); + write_mem(a, ix + 5, floatBitsToUint(s.xlat.x)); + write_mem(a, ix + 6, floatBitsToUint(s.xlat.y)); + write_mem(a, ix + 7, floatBitsToUint(s.c1.x)); + write_mem(a, ix + 8, floatBitsToUint(s.c1.y)); + write_mem(a, ix + 9, floatBitsToUint(s.ra)); + write_mem(a, ix + 10, floatBitsToUint(s.roff)); +} + CmdImage CmdImage_read(Alloc a, CmdImageRef ref) { uint ix = ref.offset >> 2; uint raw0 = read_mem(a, ix + 0); @@ -293,6 +351,10 @@ CmdLinGrad Cmd_LinGrad_read(Alloc a, CmdRef ref) { return CmdLinGrad_read(a, CmdLinGradRef(ref.offset + 4)); } +CmdRadGrad Cmd_RadGrad_read(Alloc a, CmdRef ref) { + return CmdRadGrad_read(a, CmdRadGradRef(ref.offset + 4)); +} + CmdImage Cmd_Image_read(Alloc a, CmdRef ref) { return CmdImage_read(a, CmdImageRef(ref.offset + 4)); } @@ -338,6 +400,11 @@ void Cmd_LinGrad_write(Alloc a, CmdRef ref, CmdLinGrad s) { CmdLinGrad_write(a, CmdLinGradRef(ref.offset + 4), s); } +void Cmd_RadGrad_write(Alloc a, CmdRef ref, CmdRadGrad s) { + write_mem(a, ref.offset >> 2, Cmd_RadGrad); + CmdRadGrad_write(a, CmdRadGradRef(ref.offset + 4), s); +} + void Cmd_Image_write(Alloc a, CmdRef ref, CmdImage s) { write_mem(a, ref.offset >> 2, Cmd_Image); CmdImage_write(a, CmdImageRef(ref.offset + 4), s); diff --git a/piet-gpu/src/encoder.rs b/piet-gpu/src/encoder.rs index 62c59c4..2f4b85e 100644 --- a/piet-gpu/src/encoder.rs +++ b/piet-gpu/src/encoder.rs @@ -62,6 +62,7 @@ const ANNOTATED_SIZE: usize = 40; // Tags for draw objects. See shader/drawtag.h for the authoritative source. const DRAWTAG_FILLCOLOR: u32 = 0x44; const DRAWTAG_FILLLINGRADIENT: u32 = 0x114; +const DRAWTAG_FILLRADGRADIENT: u32 = 0x2dc; const DRAWTAG_BEGINCLIP: u32 = 0x05; const DRAWTAG_ENDCLIP: u32 = 0x25; @@ -79,6 +80,16 @@ pub struct FillLinGradient { p1: [f32; 2], } +#[repr(C)] +#[derive(Clone, Copy, Debug, Default, Zeroable, Pod)] +pub struct FillRadGradient { + index: u32, + p0: [f32; 2], + p1: [f32; 2], + r0: f32, + r1: f32, +} + #[allow(unused)] #[repr(C)] #[derive(Clone, Copy, Debug, Default, Zeroable, Pod)] @@ -123,6 +134,13 @@ impl Encoder { self.transform_stream.push(transform); } + // Swap the last two tags in the tag stream; used for transformed + // gradients. + pub fn swap_last_tags(&mut self) { + let len = self.tag_stream.len(); + self.tag_stream.swap(len - 1, len - 2); + } + // -1.0 means "fill" pub fn linewidth(&mut self, linewidth: f32) { self.tag_stream.push(0x40); @@ -147,6 +165,16 @@ impl Encoder { self.drawdata_stream.extend(bytemuck::bytes_of(&element)); } + + /// Encode a fill radial gradient draw object. + /// + /// This should be encoded after a path. + pub fn fill_rad_gradient(&mut self, index: u32, p0: [f32; 2], p1: [f32; 2], r0: f32, r1: f32) { + self.drawtag_stream.push(DRAWTAG_FILLRADGRADIENT); + let element = FillRadGradient { index, p0, p1, r0, r1 }; + self.drawdata_stream.extend(bytemuck::bytes_of(&element)); + } + /// Start a clip. pub fn begin_clip(&mut self, blend: Option) { self.drawtag_stream.push(DRAWTAG_BEGINCLIP); @@ -220,7 +248,7 @@ impl Encoder { alloc += n_drawobj * DRAW_BBOX_SIZE; let drawinfo_alloc = alloc; // TODO: not optimized; it can be accumulated during encoding or summed from drawtags - const MAX_DRAWINFO_SIZE: usize = 16; + const MAX_DRAWINFO_SIZE: usize = 44; alloc += n_drawobj * MAX_DRAWINFO_SIZE; let config = Config { diff --git a/piet-gpu/src/gradient.rs b/piet-gpu/src/gradient.rs index 20982e9..e655908 100644 --- a/piet-gpu/src/gradient.rs +++ b/piet-gpu/src/gradient.rs @@ -18,15 +18,29 @@ use std::collections::hash_map::{Entry, HashMap}; -use piet::{Color, FixedLinearGradient, GradientStop}; +use piet::kurbo::Point; +use piet::{Color, FixedLinearGradient, GradientStop, FixedRadialGradient}; + +/// Radial gradient compatible with COLRv1 spec +#[derive(Debug, Clone)] +pub struct Colrv1RadialGradient { + /// The center of the iner circle. + pub center0: Point, + /// The offset of the origin relative to the center. + pub center1: Point, + /// The radius of the inner circle. + pub radius0: f64, + /// The radius of the outer circle. + pub radius1: f64, + /// The stops. + pub stops: Vec, +} #[derive(Clone)] pub struct BakedGradient { ramp: Vec, } -/// This is basically the same type as scene::FillLinGradient, so could -/// potentially use that directly. #[derive(Clone)] pub struct LinearGradient { pub(crate) start: [f32; 2], @@ -34,6 +48,15 @@ pub struct LinearGradient { pub(crate) ramp_id: u32, } +#[derive(Clone)] +pub struct RadialGradient { + pub(crate) start: [f32; 2], + pub(crate) end: [f32; 2], + pub(crate) r0: f32, + pub(crate) r1: f32, + pub(crate) ramp_id: u32, +} + #[derive(Default)] pub struct RampCache { ramps: Vec, @@ -154,6 +177,28 @@ impl RampCache { } } + pub fn add_radial_gradient(&mut self, rad: &FixedRadialGradient) -> RadialGradient { + let ramp_id = self.add_ramp(&rad.stops); + RadialGradient { + ramp_id: ramp_id as u32, + start: crate::render_ctx::to_f32_2(rad.center + rad.origin_offset), + end: crate::render_ctx::to_f32_2(rad.center), + r0: 0.0, + r1: rad.radius as f32, + } + } + + pub fn add_radial_gradient_colrv1(&mut self, rad: &Colrv1RadialGradient) -> RadialGradient { + let ramp_id = self.add_ramp(&rad.stops); + RadialGradient { + ramp_id: ramp_id as u32, + start: crate::render_ctx::to_f32_2(rad.center0), + end: crate::render_ctx::to_f32_2(rad.center1), + r0: rad.radius0 as f32, + r1: rad.radius1 as f32, + } + } + /// Dump the contents of a gradient. This is for debugging. #[allow(unused)] pub(crate) fn dump_gradient(&self, lin: &LinearGradient) { diff --git a/piet-gpu/src/lib.rs b/piet-gpu/src/lib.rs index e12f824..475d723 100644 --- a/piet-gpu/src/lib.rs +++ b/piet-gpu/src/lib.rs @@ -12,6 +12,7 @@ use std::convert::TryInto; pub use blend::{Blend, BlendMode, CompositionMode}; pub use render_ctx::PietGpuRenderContext; +pub use gradient::Colrv1RadialGradient; use piet::kurbo::Vec2; use piet::{ImageFormat, RenderContext}; diff --git a/piet-gpu/src/render_ctx.rs b/piet-gpu/src/render_ctx.rs index 024dd2b..dca03eb 100644 --- a/piet-gpu/src/render_ctx.rs +++ b/piet-gpu/src/render_ctx.rs @@ -13,7 +13,7 @@ use piet_gpu_hal::BufWrite; use piet_gpu_types::encoder::{Encode, Encoder}; use piet_gpu_types::scene::Element; -use crate::gradient::{LinearGradient, RampCache}; +use crate::gradient::{LinearGradient, RadialGradient, RampCache, Colrv1RadialGradient}; use crate::text::Font; pub use crate::text::{PietGpuText, PietGpuTextLayout, PietGpuTextLayoutBuilder}; use crate::Blend; @@ -50,6 +50,7 @@ pub struct PietGpuRenderContext { pub enum PietGpuBrush { Solid(u32), LinGradient(LinearGradient), + RadGradient(RadialGradient), } #[derive(Default)] @@ -187,6 +188,10 @@ impl RenderContext for PietGpuRenderContext { let lin = self.ramp_cache.add_linear_gradient(&lin); Ok(PietGpuBrush::LinGradient(lin)) } + FixedGradient::Radial(rad) => { + let rad = self.ramp_cache.add_radial_gradient(&rad); + Ok(PietGpuBrush::RadGradient(rad)) + } _ => todo!("don't do radial gradients yet"), } } @@ -338,6 +343,20 @@ impl PietGpuRenderContext { } } + pub fn radial_gradient_colrv1(&mut self, rad: &Colrv1RadialGradient) -> PietGpuBrush { + PietGpuBrush::RadGradient(self.ramp_cache.add_radial_gradient_colrv1(rad)) + } + + pub fn fill_transform(&mut self, shape: impl Shape, brush: &PietGpuBrush, transform: Affine) { + let path = shape.path_elements(TOLERANCE); + self.encode_linewidth(-1.0); + self.encode_path(path, true); + self.encode_transform(Transform::from_kurbo(transform)); + self.new_encoder.swap_last_tags(); + self.encode_brush(&brush); + self.encode_transform(Transform::from_kurbo(transform.inverse())); + } + fn encode_path(&mut self, path: impl Iterator, is_fill: bool) { if is_fill { self.encode_path_inner( @@ -420,6 +439,10 @@ impl PietGpuRenderContext { self.new_encoder .fill_lin_gradient(lin.ramp_id, lin.start, lin.end); } + PietGpuBrush::RadGradient(rad) => { + self.new_encoder + .fill_rad_gradient(rad.ramp_id, rad.start, rad.end, rad.r0, rad.r1); + } } } } diff --git a/piet-gpu/src/test_scenes.rs b/piet-gpu/src/test_scenes.rs index ee5839d..cf5a50d 100644 --- a/piet-gpu/src/test_scenes.rs +++ b/piet-gpu/src/test_scenes.rs @@ -2,10 +2,10 @@ use rand::{Rng, RngCore}; -use crate::{Blend, BlendMode, CompositionMode, PietGpuRenderContext}; +use crate::{Blend, BlendMode, CompositionMode, PietGpuRenderContext, Colrv1RadialGradient}; use piet::kurbo::{Affine, BezPath, Circle, Line, Point, Rect, Shape}; use piet::{ - Color, FixedGradient, FixedLinearGradient, GradientStop, Text, TextAttribute, TextLayoutBuilder, + Color, FixedGradient, FixedRadialGradient, GradientStop, Text, TextAttribute, TextLayoutBuilder, }; use crate::{PicoSvg, RenderContext, Vec2}; @@ -32,7 +32,7 @@ pub fn render_svg(rc: &mut impl RenderContext, filename: &str, scale: f64) { println!("flattening and encoding time: {:?}", start.elapsed()); } -pub fn render_scene(rc: &mut impl RenderContext) { +pub fn render_scene(rc: &mut PietGpuRenderContext) { const WIDTH: usize = 2048; const HEIGHT: usize = 1536; let mut rng = rand::thread_rng(); @@ -142,7 +142,7 @@ fn render_alpha_test(rc: &mut impl RenderContext) { } #[allow(unused)] -fn render_gradient_test(rc: &mut impl RenderContext) { +fn render_gradient_test(rc: &mut PietGpuRenderContext) { let stops = vec![ GradientStop { color: Color::rgb8(0, 255, 0), @@ -153,14 +153,18 @@ fn render_gradient_test(rc: &mut impl RenderContext) { pos: 1.0, }, ]; - let lin = FixedLinearGradient { - start: Point::new(0.0, 100.0), - end: Point::new(0.0, 300.0), + let rad = Colrv1RadialGradient { + center0: Point::new(200.0, 200.0), + center1: Point::new(250.0, 200.0), + radius0: 50.0, + radius1: 100.0, stops, }; - let brush = FixedGradient::Linear(lin); + let brush = rc.radial_gradient_colrv1(&rad); + //let brush = FixedGradient::Radial(rad); //let brush = Color::rgb8(0, 128, 0); - rc.fill(Rect::new(100.0, 100.0, 300.0, 300.0), &brush); + let transform = Affine::new([1.0, 0.0, 0.0, 0.5, 0.0, 100.0]); + rc.fill_transform(Rect::new(100.0, 100.0, 300.0, 300.0), &brush, transform); } fn diamond(origin: Point) -> impl Shape {