From 307bf8d2276a26fd0828a5979f91d40be64d8772 Mon Sep 17 00:00:00 2001 From: Raph Levien Date: Tue, 17 May 2022 14:34:14 -0700 Subject: [PATCH] More blend mode fixes Adds a test to visualize the blend modes. Fixes a dumb bug in blend.h and also a more subtle issue where default blending is not the same as clipping, as the former needs to always push a blend group (to cause isolation) and the latter does not. This might be something we need to get back to. This should fix the rendering, so it fairly closely resembles the Mozilla reference image. There's also a compile-time switch to disable sRGB conversion, which is (sadly) needed for compatible rendering. --- pgpu-render/src/lib.rs | 5 +- pgpu-render/src/render.rs | 9 ++- piet-gpu/bin/cli.rs | 3 +- piet-gpu/bin/winit.rs | 2 +- piet-gpu/shader/blend.h | 15 ++-- piet-gpu/shader/coarse.comp | 2 +- piet-gpu/shader/gen/coarse.dxil | Bin 11628 -> 11632 bytes piet-gpu/shader/gen/coarse.hlsl | 82 +++++++++---------- piet-gpu/shader/gen/coarse.msl | 64 +++++++-------- piet-gpu/shader/gen/coarse.spv | Bin 58852 -> 58868 bytes piet-gpu/shader/gen/kernel4.dxil | Bin 15360 -> 14000 bytes piet-gpu/shader/gen/kernel4.hlsl | 111 +++++++++++++------------- piet-gpu/shader/gen/kernel4.msl | 76 ++++++++---------- piet-gpu/shader/gen/kernel4.spv | Bin 66476 -> 64668 bytes piet-gpu/shader/gen/kernel4_gray.dxil | Bin 15268 -> 14072 bytes piet-gpu/shader/gen/kernel4_gray.hlsl | 111 +++++++++++++------------- piet-gpu/shader/gen/kernel4_gray.msl | 76 ++++++++---------- piet-gpu/shader/gen/kernel4_gray.spv | Bin 66232 -> 64424 bytes piet-gpu/shader/kernel4.comp | 13 +++ piet-gpu/src/blend.rs | 4 +- piet-gpu/src/encoder.rs | 11 ++- piet-gpu/src/gradient.rs | 2 +- piet-gpu/src/lib.rs | 2 +- piet-gpu/src/render_ctx.rs | 31 ++++--- piet-gpu/src/stages/clip.rs | 4 +- piet-gpu/src/test_scenes.rs | 111 +++++++++++++++++++++++++- piet-scene/src/glyph/mod.rs | 4 +- 27 files changed, 431 insertions(+), 307 deletions(-) diff --git a/pgpu-render/src/lib.rs b/pgpu-render/src/lib.rs index 7d4c60b..50462e7 100644 --- a/pgpu-render/src/lib.rs +++ b/pgpu-render/src/lib.rs @@ -215,7 +215,10 @@ pub struct PgpuRect { /// Computes the bounding box for the glyph after applying the specified /// transform. #[no_mangle] -pub unsafe extern "C" fn pgpu_glyph_bbox(glyph: *const PgpuGlyph, transform: &[f32; 6]) -> PgpuRect { +pub unsafe extern "C" fn pgpu_glyph_bbox( + glyph: *const PgpuGlyph, + transform: &[f32; 6], +) -> PgpuRect { let transform = piet_scene::geometry::Affine::new(transform); let rect = (*glyph).bbox(Some(transform)); PgpuRect { diff --git a/pgpu-render/src/render.rs b/pgpu-render/src/render.rs index 361ef42..5b5d328 100644 --- a/pgpu-render/src/render.rs +++ b/pgpu-render/src/render.rs @@ -16,8 +16,8 @@ use piet_gpu::{EncodedSceneRef, PixelFormat, RenderConfig}; use piet_gpu_hal::{QueryPool, Session}; -use piet_scene::glyph::pinot::{types::Tag, FontDataRef}; use piet_scene::geometry::{Affine, Rect}; +use piet_scene::glyph::pinot::{types::Tag, FontDataRef}; use piet_scene::glyph::{GlyphContext, GlyphProvider}; use piet_scene::resource::ResourceContext; use piet_scene::scene::{Fragment, Scene}; @@ -214,7 +214,12 @@ pub struct PgpuGlyph { impl PgpuGlyph { pub fn bbox(&self, transform: Option) -> Rect { if let Some(transform) = &transform { - Rect::from_points(self.fragment.points().iter().map(|p| p.transform(transform))) + Rect::from_points( + self.fragment + .points() + .iter() + .map(|p| p.transform(transform)), + ) } else { Rect::from_points(self.fragment.points()) } diff --git a/piet-gpu/bin/cli.rs b/piet-gpu/bin/cli.rs index abe6ae1..7d577d3 100644 --- a/piet-gpu/bin/cli.rs +++ b/piet-gpu/bin/cli.rs @@ -249,7 +249,8 @@ fn main() -> Result<(), Error> { println!("parsing time: {:?}", start.elapsed()); test_scenes::render_svg(&mut ctx, &svg); } else { - test_scenes::render_scene(&mut ctx); + //test_scenes::render_scene(&mut ctx); + test_scenes::render_blend_grid(&mut ctx); } let mut renderer = Renderer::new(&session, WIDTH, HEIGHT, 1)?; diff --git a/piet-gpu/bin/winit.rs b/piet-gpu/bin/winit.rs index 1642026..78867f5 100644 --- a/piet-gpu/bin/winit.rs +++ b/piet-gpu/bin/winit.rs @@ -125,7 +125,7 @@ fn main() -> Result<(), Error> { } let mut ctx = PietGpuRenderContext::new(); - let test_blend = false; + let test_blend = true; if let Some(svg) = &svg { test_scenes::render_svg(&mut ctx, svg); } else if test_blend { diff --git a/piet-gpu/shader/blend.h b/piet-gpu/shader/blend.h index c0ae6af..7366006 100644 --- a/piet-gpu/shader/blend.h +++ b/piet-gpu/shader/blend.h @@ -18,6 +18,7 @@ #define Blend_Saturation 13 #define Blend_Color 14 #define Blend_Luminosity 15 +#define Blend_Clip 128 vec3 screen(vec3 cb, vec3 cs) { return cb + cs - (cb * cs); @@ -45,7 +46,7 @@ vec3 hard_light(vec3 cb, vec3 cs) { return mix( screen(cb, 2.0 * cs - 1.0), cb * 2.0 * cs, - vec3(lessThanEqual(cs, vec3(0.5))) + lessThanEqual(cs, vec3(0.5)) ); } @@ -53,12 +54,12 @@ vec3 soft_light(vec3 cb, vec3 cs) { vec3 d = mix( sqrt(cb), ((16.0 * cb - vec3(12.0)) * cb + vec3(4.0)) * cb, - vec3(lessThanEqual(cb, vec3(0.25))) + lessThanEqual(cb, vec3(0.25)) ); return mix( cb + (2.0 * cs - vec3(1.0)) * (d - cb), cb - (vec3(1.0) - 2.0 * cs) * cb * (vec3(1.0) - cb), - vec3(lessThanEqual(cs, vec3(0.5))) + lessThanEqual(cs, vec3(0.5)) ); } @@ -260,6 +261,7 @@ vec4 mix_compose(vec3 cb, vec3 cs, float ab, float as, uint mode) { } #define BlendComp_default (Blend_Normal << 8 | Comp_SrcOver) +#define BlendComp_clip (Blend_Clip << 8 | Comp_SrcOver) // This is added to alpha to prevent divide-by-zero #define EPSILON 1e-15 @@ -267,7 +269,8 @@ vec4 mix_compose(vec3 cb, vec3 cs, float ab, float as, uint mode) { // Apply blending and composition. Both input and output colors are // premultiplied RGB. vec4 mix_blend_compose(vec4 backdrop, vec4 src, uint mode) { - if (mode == BlendComp_default) { + if ((mode & 0x7fff) == BlendComp_default) { + // Both normal+src_over blend and clip case return backdrop * (1.0 - src.a) + src; } // Un-premultiply colors for blending @@ -276,9 +279,9 @@ vec4 mix_blend_compose(vec4 backdrop, vec4 src, uint mode) { float inv_backdrop_a = 1.0 / (backdrop.a + EPSILON); vec3 cb = backdrop.rgb * inv_backdrop_a; uint blend_mode = mode >> 8; - vec3 blended = mix_blend(cs, cb, blend_mode); + vec3 blended = mix_blend(cb, cs, blend_mode); cs = mix(cs, blended, backdrop.a); - uint comp_mode = mode * 0xff; + uint comp_mode = mode & 0xff; if (comp_mode == Comp_SrcOver) { vec3 co = mix(backdrop.rgb, cs, src.a); return vec4(co, src.a + backdrop.a * (1 - src.a)); diff --git a/piet-gpu/shader/coarse.comp b/piet-gpu/shader/coarse.comp index 3abb2e0..1b3f252 100644 --- a/piet-gpu/shader/coarse.comp +++ b/piet-gpu/shader/coarse.comp @@ -303,7 +303,7 @@ void main() { uint scene_offset = memory[drawmonoid_base + 2]; uint dd = drawdata_start + (scene_offset >> 2); uint blend = scene[dd]; - is_blend = (blend != BlendComp_default); + is_blend = (blend != BlendComp_clip); } include_tile = tile.tile.offset != 0 || (tile.backdrop == 0) == is_clip || is_blend; diff --git a/piet-gpu/shader/gen/coarse.dxil b/piet-gpu/shader/gen/coarse.dxil index 910925dd080752fe8c34968c6b8992f0dbb8556e..9187e01fce13411401d35ab8182d57aad5bd9bed 100644 GIT binary patch delta 6411 zcmYLNdq5NCvfn&5Bq2aZ2m}xfL^Kb;fPjh$NkF8Dk1Ya5L<~U@5ot~j_8?mG5{$@G zK+&SE0tyHe1uV7NCWwlN7AaQrqBpi`5w!;`T3^-sEhOH*_A&F#&NuU$-^{m96UP!u z**Ntn_c@fXkfLAK?{;lHU$7>VznYah9Hsbd33)mMDIplbQy>U?hHwx>hahN-3qjII z(>-q*1ic}b2jGskiKtB^U#=YlF^M1P_CyGp0rZG{P=!kDO>&9yb&1xwaH9T2s*sf9 zoMjq!Jfp&Cp|1!pPH;fx4LXw{B`#Mqc|C?*?X1t>dQAL?Y+~ccdd_ z&$eHA%`<&ohn7V{mT?xbSL=Xx6Sj6=5Gr!%_L#cCD+$KOsi`8B7W3rJy#B67c4suA zgLH^xBownbz$e{t$L}mxBmspph+_Dm)@r1~5U>;HHP)3bh2pf1b0^n(EEvbTk9W)ky+)W@YYsDB0IIY(#1{~$jc69b9Fn+~^hSi>P`gqFb}hxJPfNmSanMr@t~#^S ziNMlsgJya@xFCk1X{O!Sm1Dh%r#2DfQQWTv*K(?UN*8KavQ9kTYj=qeoJ!^>9hR^~f409{axuP42n`$C7rBqSo zl#}xvjF#yn^p%OFbckGvMu{@TM1CN2)9zbn6FW=lt4|^LD0buOBebyMLMhYFndV8C zl;<+%Xe^9%NQ}Uwj)bV|kVv$R7Uf(x8OJkB-gD|Zlz|0)ku0fB3b87>S&Jm$9XhCSH2h-UJ`1tBS?%-(`aMjcMeVe_(`nL&Y9OZ_CLE~+m$ zSm>o@zYE8REJtaRlH>3lnFmF~ls<+Z!ApxGl)OoB>Q1}OEn^<glYyk<(FONYa*8#qY=r{CO8wP zXVHH6+ye)j*jY+_U{w~c5XHAE>>uEXLUvbb2%f499Ol5OqPqxN0&hFzYJtfKqUyz& zL>DNv6K8)(dG@GCPmLkS>Kzp3{;A(NBT(Ue(k!;&aefzB(CWZD8mxpbY#)yn<3#zM zJseD+0g@31UdjR`9J!-#@q}b>Led3{k6+$8VchJX5A1}D0z5m5JVcL|4@*W@`QvZ|8F;#Ab~X<3v7ltYuqZu}deu4Fpx&MjR5uXwm|eLmbq- zKJr(Q6Fohx^r9qzdVs%fOX&?s0=^&#-hgA(_rzPK*~-398STdR1?A^<_~1WJ0Un95+H-2x?2~4pMeJRx|T4 z=H69EacU>3mlhP%>L~(txiG-UqBV8R9GmpLkC9GbLFJE`XY@zo-$#YpYI8G+=d{;* z)KL z6WEY1twQmy@;UCIoC+mG`;5f~^qGSvwbAamS}QV0sAiOJVEbxRF9Z@;b=vg-1#D^O zo~Fqvp;)VAbe;ceCcQ~H*DZ;{gD$BJ%tCW^WD1dm_9h|%fUy369~l$%Be2$wk;RiF zf%-XDDxav5b|vk&CzV^TOhSpPbS&DNV*wMT3mGN^8g9LK4NA-bl8^XV6B5y+gsU)% zg2pF}hmbE>@SH}n5;k0YfY}w4I@d#Mv$`Q1$X;;i#{FTGd+UR}p?uF`4G!>2AlZP@ zvw=|&GYA;1@}(O+4+t!nrq9 zKv(Wdq4lAQ6GZR(t|m>W-tJx!4Zh5)#lwQJ{U=RYsw`SK*PT6Cv_%_YqZ9O%?x1LW z5K=Ua4xl7{=f1C@(zHIBiAPPA4cVREuMdc-)^iL&*Gx<@&ZBxUmxwEp-0IzJe}>Lu;&+b!zGLo$}V%pdduU^mB4{64dP{aR*%w?>=$| zBseOIK!V{U+&Q)LEyp>;FPS73Z5xi>Moa@OlDrCoL<{1O4yEmLlb9FAvQ{>2pHZ z%xvkK@`x9+C%J5|eaG^Vk)N>%3JpgjAJSQWV{ztysAnT~fVS|UDIl|VMx6LX$|p)W z#2W{Ovo3u?R#$ zer%KwT!1NcXq>c}S%suZXRMQ+S>f=Z+-oXZ6UH7ii|v#{x>Y^8Rf8bKQ_tx{Qv$C! zK4D(IkJ6=2Uw;S`*jrlz%9N7cZb!4k-c8$mAAyfW{ zDL=C(zwZx{a#N`{J1`yV#EwN-BmcoqVW`Qw)a0)P2feF&M+`bg(+xtV(^6tMFN9O$ zX)XVvFL~SbULIKaXOji}-d>Xy{w&(wvt2*!%cIlY9-WqZBnZeXHd#QiiTt%*BQKuhB8l9==nZo+6y_-Ku*z`LYfzYqu~WXV@b zmhfKJB)_hScw6Hpkd!DV_cT}WwuVU+Z*&t=D#Vn0>K)*AOrCX-ic*1$kbM_W>kw)k z`=DjtGdKIQm2+3|Ie>+=|WjM^@-ouvx@6%{XV3FsLpvYvtDC&r}`K@k{k zQjP<|69=i6dj;1JlMLexPl4Hp!|FBNq8XHhx||yTWnD2-X5)~#=2%DgbTHtMo862! zx;#wPj}1E2^KQmE!Dpr~JF`xHW?l5l_l!7^JW=9rE0xDP)IaMq+E^XKUpdafDCrpVZ1#8keU7r{zDi%QwXlg*HP^+vTY)W3gTGbKUaHxOk!2 z&kQIYy|@Y+{Dnm#2-(u}zwV68Oj3_%Q}( z4thWYtx_Qfg*_l1@%re@(aMtheyFRvIU97=1Yw$Z+|P$gI3c@p?R ztuTR6|dNx`h}!M@nH!j$QPRS2uyNeUy!NGlYCR-^d_6t&a^Rp?07ZbmZ+FseijN>d%w2uMp!>=D7IILvOfC1^YaXwKLKW{l2{D3KYxFY=F3PB~Z zJkh++7D{2=@?$PfS1fz_OZc;21eMC=qRCuNkw5!|2fxqOFyD7Cf8Q;G?=t%sgI(55 z`CnXKn?254_;N+W%N4?Fj6prWZu$``wv!r<$SBWeR=k+0c`{OC`XSh z<3s!-5Wf`9SDeKSdAz1rDX+YtR8}XhC6+PxWqa#Rzon#6GEz_tLA?(54Xkr5n2|JU zonYD;$`b3)T5N(5mFcZx%9p*h$$W7G7*pztYL(U@?68c#ikgrChOpkhW?CuW*$GAC zKK%X(`Z8>{E$<$!Q}d13a$Zo5O|`jcohD;H{vf6sX881}{>J0m`JEHGA*fAvbF*4d zjX#8`X8gbEaK?!q{>X&t+_`+K2mUSFN2~FznCd}7h0TKzLDL|geG>B^kS?qjH%)M( z29Vb@mXwJ({=1>O-*PiXBFS>F!I z4(mG@hK|IO9d}N6^ir*%{{3Xf!4ukMleT%Np!s!!@vtpDZws17`02uLo9{F>zips? zqj%O!lHB{o=25;{c)fYJxA}bot2OQlYHnfvhE}(dCfseY9BKGS06OZftp! z(GuOb@6&>qO)anZsLhaIG1_}XU%q69hlY3S zps)-?=g!IV$4)vMu+vMa@=0@a!M7NQ@MrYYSF)2mLU2ST23D;%ZG)Ff4{w}3vD&pm$7=SQD7djaC_PxuZTx7VVsb z_eK4|ZlCu%k{BHZ|-Thm?k5?yO*?Q>K*1PeP-)!&i-`aXUUYl%} zd(0kQH2R|>|KyxT0%p)$E`4)RE8dlHzN(vbEG2&<&YdHzY*&S=& z-AsPAK6&yu&)KcWxmmdlYq9W;8kp6-KjBm|IP8#BqN_^BKj?*QKdfbMQ9bQg>HX{4 z@kML7p>nk&fwk`n>5=#+$-KUxT0$6+CHM9eD}p+M*qg_wQ&(2zd&8eGCGs9x=r_Jut=oA?i=Lk*ReI_AE7&f5B&I zTGt}x9k#fMUadXB(ki~zv5h)*W_+0nX~d_B^?gTT z(2UgS(W-w!CJz9y#rNGdRSsbX0AwwK+r5$HL$V$Ko>@LcDm+wmIxjW&j4D%jJhhGZ zCpZDz*xc`^n$mi~kFeleB+_|Ih3E=wenmV|onf7;Dn387=lswYl`Zw`IFrgcZX{Ki z*;#Pluic8mi;A51*(#A7aw2#^e>>)OIOaZdBzWx`A^n$g)*NOk|3cuVDRgJM1g0Y9 z!j0}JAbo#voVu+T-k6_i@qNHP_)t;&P>~ytq$Zk+Y#82jJoPu$Q^nz@L&eXAax0ao zwg&mlv!NV#!B;aETuNPVDYaPt;6_WT=aeL>oybjnscJq*YOf1?3F#{&MulYVj7@+v@baZd?09rZCDlb|AhhQPdo-`rgJjrlgnB5h9LN->DjJCl>G>S|p# zyndMW@6d@8>j(=>Tet{XoT4jy=-;SQ8|@#9lVn~tiPe9=ir4)aIV6?j@S()R4_6(o N8}ie&1^Ug${U2&KJ;eY3 delta 6323 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 JEo?6i{9l6n6Jh`W diff --git a/piet-gpu/shader/gen/coarse.hlsl b/piet-gpu/shader/gen/coarse.hlsl index 04529bb..0331e33 100644 --- a/piet-gpu/shader/gen/coarse.hlsl +++ b/piet-gpu/shader/gen/coarse.hlsl @@ -919,26 +919,26 @@ void comp_main() uint scene_offset = _260.Load((drawmonoid_base_1 + 2u) * 4 + 8); uint dd = drawdata_start + (scene_offset >> uint(2)); uint blend = _1372.Load(dd * 4 + 0); - is_blend = blend != 3u; + is_blend = blend != 32771u; } - bool _1692 = tile.tile.offset != 0u; - bool _1701; - if (!_1692) + bool _1693 = tile.tile.offset != 0u; + bool _1702; + if (!_1693) { - _1701 = (tile.backdrop == 0) == is_clip; + _1702 = (tile.backdrop == 0) == is_clip; } else { - _1701 = _1692; + _1702 = _1693; } - include_tile = _1701 || is_blend; + include_tile = _1702 || is_blend; } if (include_tile) { uint el_slice = el_ix / 32u; uint el_mask = 1u << (el_ix & 31u); - uint _1723; - InterlockedOr(sh_bitmaps[el_slice][(y * 16u) + x], el_mask, _1723); + uint _1724; + InterlockedOr(sh_bitmaps[el_slice][(y * 16u) + x], el_mask, _1724); } } GroupMemoryBarrierWithGroupSync(); @@ -967,9 +967,9 @@ void comp_main() { uint param_25 = element_ref_ix; bool param_26 = mem_ok; - TileRef _1800 = { sh_tile_base[element_ref_ix] + (((sh_tile_stride[element_ref_ix] * tile_y) + tile_x) * 8u) }; + TileRef _1801 = { 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 = _1800; + TileRef param_28 = _1801; Tile tile_1 = Tile_read(param_27, param_28); uint drawmonoid_base_2 = drawmonoid_start + (4u * element_ix_2); uint scene_offset_1 = _260.Load((drawmonoid_base_2 + 2u) * 4 + 8); @@ -984,11 +984,11 @@ void comp_main() Alloc param_29 = cmd_alloc; CmdRef param_30 = cmd_ref; uint param_31 = cmd_limit; - bool _1848 = alloc_cmd(param_29, param_30, param_31); + bool _1849 = alloc_cmd(param_29, param_30, param_31); cmd_alloc = param_29; cmd_ref = param_30; cmd_limit = param_31; - if (!_1848) + if (!_1849) { break; } @@ -999,10 +999,10 @@ void comp_main() write_fill(param_32, param_33, param_34, param_35); cmd_ref = param_33; uint rgba = _1372.Load(dd_1 * 4 + 0); - CmdColor _1871 = { rgba }; + CmdColor _1872 = { rgba }; Alloc param_36 = cmd_alloc; CmdRef param_37 = cmd_ref; - CmdColor param_38 = _1871; + CmdColor param_38 = _1872; Cmd_Color_write(param_36, param_37, param_38); cmd_ref.offset += 8u; break; @@ -1012,11 +1012,11 @@ void comp_main() Alloc param_39 = cmd_alloc; CmdRef param_40 = cmd_ref; uint param_41 = cmd_limit; - bool _1889 = alloc_cmd(param_39, param_40, param_41); + bool _1890 = alloc_cmd(param_39, param_40, param_41); cmd_alloc = param_39; cmd_ref = param_40; cmd_limit = param_41; - if (!_1889) + if (!_1890) { break; } @@ -1043,11 +1043,11 @@ void comp_main() Alloc param_49 = cmd_alloc; CmdRef param_50 = cmd_ref; uint param_51 = cmd_limit; - bool _1953 = alloc_cmd(param_49, param_50, param_51); + bool _1954 = alloc_cmd(param_49, param_50, param_51); cmd_alloc = param_49; cmd_ref = param_50; cmd_limit = param_51; - if (!_1953) + if (!_1954) { break; } @@ -1077,11 +1077,11 @@ void comp_main() 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); + bool _2060 = alloc_cmd(param_59, param_60, param_61); cmd_alloc = param_59; cmd_ref = param_60; cmd_limit = param_61; - if (!_2059) + if (!_2060) { break; } @@ -1094,27 +1094,27 @@ void comp_main() 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 }; + CmdImage _2099 = { index, offset_1 }; Alloc param_66 = cmd_alloc; CmdRef param_67 = cmd_ref; - CmdImage param_68 = _2098; + CmdImage param_68 = _2099; Cmd_Image_write(param_66, param_67, param_68); cmd_ref.offset += 12u; break; } case 5u: { - bool _2112 = tile_1.tile.offset == 0u; - bool _2118; - if (_2112) + bool _2113 = tile_1.tile.offset == 0u; + bool _2119; + if (_2113) { - _2118 = tile_1.backdrop == 0; + _2119 = tile_1.backdrop == 0; } else { - _2118 = _2112; + _2119 = _2113; } - if (_2118) + if (_2119) { clip_zero_depth = clip_depth + 1u; } @@ -1123,11 +1123,11 @@ void comp_main() 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); + bool _2131 = alloc_cmd(param_69, param_70, param_71); cmd_alloc = param_69; cmd_ref = param_70; cmd_limit = param_71; - if (!_2130) + if (!_2131) { break; } @@ -1145,11 +1145,11 @@ void comp_main() 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); + bool _2159 = alloc_cmd(param_74, param_75, param_76); cmd_alloc = param_74; cmd_ref = param_75; cmd_limit = param_76; - if (!_2158) + if (!_2159) { break; } @@ -1160,10 +1160,10 @@ void comp_main() 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 }; + CmdEndClip _2182 = { blend_1 }; Alloc param_81 = cmd_alloc; CmdRef param_82 = cmd_ref; - CmdEndClip param_83 = _2181; + CmdEndClip param_83 = _2182; Cmd_EndClip_write(param_81, param_82, param_83); cmd_ref.offset += 8u; break; @@ -1198,17 +1198,17 @@ void comp_main() break; } } - bool _2228 = (bin_tile_x + tile_x) < _1005.Load(8); - bool _2237; - if (_2228) + bool _2229 = (bin_tile_x + tile_x) < _1005.Load(8); + bool _2238; + if (_2229) { - _2237 = (bin_tile_y + tile_y) < _1005.Load(12); + _2238 = (bin_tile_y + tile_y) < _1005.Load(12); } else { - _2237 = _2228; + _2238 = _2229; } - if (_2237) + if (_2238) { Alloc param_84 = cmd_alloc; CmdRef param_85 = cmd_ref; diff --git a/piet-gpu/shader/gen/coarse.msl b/piet-gpu/shader/gen/coarse.msl index 55812d4..854d243 100644 --- a/piet-gpu/shader/gen/coarse.msl +++ b/piet-gpu/shader/gen/coarse.msl @@ -942,25 +942,25 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M uint scene_offset = v_260.memory[drawmonoid_base_1 + 2u]; uint dd = drawdata_start + (scene_offset >> uint(2)); uint blend = _1372.scene[dd]; - is_blend = blend != 3u; + is_blend = blend != 32771u; } - bool _1692 = tile.tile.offset != 0u; - bool _1701; - if (!_1692) + bool _1693 = tile.tile.offset != 0u; + bool _1702; + if (!_1693) { - _1701 = (tile.backdrop == 0) == is_clip; + _1702 = (tile.backdrop == 0) == is_clip; } else { - _1701 = _1692; + _1702 = _1693; } - include_tile = _1701 || is_blend; + include_tile = _1702 || is_blend; } if (include_tile) { uint el_slice = el_ix / 32u; uint el_mask = 1u << (el_ix & 31u); - uint _1723 = atomic_fetch_or_explicit((threadgroup atomic_uint*)&sh_bitmaps[el_slice][(y * 16u) + x], el_mask, memory_order_relaxed); + uint _1724 = 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); @@ -1005,11 +1005,11 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M Alloc param_29 = cmd_alloc; CmdRef param_30 = cmd_ref; uint param_31 = cmd_limit; - bool _1848 = alloc_cmd(param_29, param_30, param_31, v_260, v_260BufferSize); + bool _1849 = 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 (!_1848) + if (!_1849) { break; } @@ -1032,11 +1032,11 @@ 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 _1889 = alloc_cmd(param_39, param_40, param_41, v_260, v_260BufferSize); + bool _1890 = 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 (!_1889) + if (!_1890) { break; } @@ -1063,11 +1063,11 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M Alloc param_49 = cmd_alloc; CmdRef param_50 = cmd_ref; uint param_51 = cmd_limit; - bool _1953 = alloc_cmd(param_49, param_50, param_51, v_260, v_260BufferSize); + bool _1954 = 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 (!_1953) + if (!_1954) { break; } @@ -1097,11 +1097,11 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M 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); + bool _2060 = 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) + if (!_2060) { break; } @@ -1123,17 +1123,17 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M } case 5u: { - bool _2112 = tile_1.tile.offset == 0u; - bool _2118; - if (_2112) + bool _2113 = tile_1.tile.offset == 0u; + bool _2119; + if (_2113) { - _2118 = tile_1.backdrop == 0; + _2119 = tile_1.backdrop == 0; } else { - _2118 = _2112; + _2119 = _2113; } - if (_2118) + if (_2119) { clip_zero_depth = clip_depth + 1u; } @@ -1142,11 +1142,11 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M 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); + bool _2131 = 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) + if (!_2131) { break; } @@ -1164,11 +1164,11 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M 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); + bool _2159 = 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) + if (!_2159) { break; } @@ -1216,17 +1216,17 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M break; } } - bool _2228 = (bin_tile_x + tile_x) < _1005.conf.width_in_tiles; - bool _2237; - if (_2228) + bool _2229 = (bin_tile_x + tile_x) < _1005.conf.width_in_tiles; + bool _2238; + if (_2229) { - _2237 = (bin_tile_y + tile_y) < _1005.conf.height_in_tiles; + _2238 = (bin_tile_y + tile_y) < _1005.conf.height_in_tiles; } else { - _2237 = _2228; + _2238 = _2229; } - if (_2237) + if (_2238) { Alloc param_84 = cmd_alloc; CmdRef param_85 = cmd_ref; diff --git a/piet-gpu/shader/gen/coarse.spv b/piet-gpu/shader/gen/coarse.spv index 6d33ee70c7b65cf2d8b8fef43e5b5ea63b20cbdf..56a87e5310cbe190f85e0e22531ab599ed276b46 100644 GIT binary patch delta 13021 zcmZ9S3A|QiwZ=Da4j@Wu;1uSVnSfIcNl9KDKr>S_wGzbx9Fc${0$pb}Dr%;s-cwFF z0127{p{O`Bik7Kmx6<;Om6i>fmV#s6|NlGRbKLCj=jMH$wbr}V+H1e>dcW^%UwpjR z8;|$u->c`geTt$-(XZ%RJbFj}a`1My^)8C`$z!HZo;a?(;L}>P6brj#Q`)9ag0~h+ zI`0@fpj?V{?8F&U+NNsNyLi4~)jp-YW5$?i?I(wo_)b zO~9h1SOcFiadLOWx8PITrnOCJX7Emp_v=$^v6jKQ+{T9!dKdjW+lFki*+-F1AJ^W| zKIWtoPMF?4qw9uRi%mK&A2Oia9PRk=CfTdlT0F5U;hn&fCw8=-GI9Kj6PpR_hU`QC zEyW%+{+SvdQRDm7_yK*2axI6WY6b_xr%f2!)|GNgad=ICM2#O=elJPX}jwR>&;o@?>4rPymNK}&H+jUQU$hu8QqHGXW3Ppt7tRbG<7d|R*)@I+eC*`*4t8~;LKoKb7ghLnmgwS&K)$TTS1ek#^M$>7tXg!?Zj09~ zuci(4npqS>umlzh_-8A|@H^pKR`?aHn1S%Euzw27e}xZk6Zo?bee`VVpKIz*gU8={ z$aZP!x9?kQ({M1WX>cgxDWqEzGnWj-)#_eFv1-xf`yA1GLz}p&EXnw@HV;h8LT3xT8%vd>yz=I(%a|O}d-!U(oMt(lK!CU*opxs(zCi-@L|c z+OdBfe>U!L6R>HA&n14NYe(Q{*A91rT|0a(+^!vN1?bw{+<-Ri=pAj^;rg>_htDN` zVb_kp!_KZ9?u5}5ZUT1g=pB!*aP4i{(Q9wh4mV+&c6e#VcI^mGg4?yjb!gWP*P&fI zT>H)n*Z$fH*WRWbd&k)ya{3(tyLJqmVAl>eW4m^^3EQ>9&w$&s!}Vv=4%eSeJ6wC4 zb{D7LIl-2kWCw2HrkOTvTMh{(XJh?L%Vjk4(;0Em%(k?;o94@!?j=0ctv!n3RXXD< zy%zO5xZlnjT|<+)ipy61dA|6a!+1^S4yO+)e*l`m^$s4qhEpzRaV`I-yOk3K$HjGE zW$WPiW^9yQ4_CehkFy#5yn{~p4P46JqScE>;Ab&&=YWmZA55&W7|Eo$2vpqC4E95? zvLs}%8{ubh-Pp952i8vc+XP84$2TdAbLN9ha2A*LCgKgMy9s-A+&bBiKl|KT>yw6)1{dk|sZ{bqreTq}R+re9KU4VCn;>Y}>%)?Xf9#+a?e+O9m zN1OJGz{)sW%VK3yco%}c6i%g1{E4D0PVNTlIQ$;)Ff9a+GhzXvG}k>ml$! zt|am>SXs+@1om!KKHS-Q*7oHRknS^e8N4r6UHKNpa=7Wbe$>To1z4TlmNLpsXCe8mc>}JfC%}GO zQR;ri^+f04<$&@@khhwOJOx(f-tiXHDNCfEgOw%HFTl#q=-CzNm*7NF_cWI>GZuTR zxdY^7x8q--)Num+8eFaSZ{XHjJ9V*p2COdimPhw2xLTIq!j+{g&-M1J10U<6@^@U% zaha{yY<);_<#KB&cTAw)gH1l0;03TUcVcY*05+NRir&RYV*U}_!}tersXUV;7>Ymf zkIFof7r`%ZDfcd)XH*u)e+DbF{dG{Gzkv5_Eehqac^RzS`7bfb)s>9JU-@S#*SXE@ z`8TjKcUTv40hOAjyRP6K>$#)N5dD%0fkslh?tc$=p4qK_>qT ztj<8MFv_F*w{ikyLB0W3mS?;g?8ir}?oF;vnzN7aO`m@py^X>$8ssfTxjGy9yI}XB zx_7|xVLYsU=-var%;+3-@%KKs`dI!0f0~<99-9xWzlsPvZL5=dz|Uin^4RnQD-Z7l z-jw9B_*&rFD347mcpx?@e{Z;UrHV}K16JW)j$vQ;2PCNOFsd<}T-E_Aw;KKwu>xX$ zg{ZSKqp({Kd@!Rn>alirC@uB}^ickuR9 zLfvj)xw<*TFZNW>RPF(mC&*sly_!0I(#nUi7wrkdz^^ju(0S?;@Uvj$1~jm|DGxsuV^>rDc`jvEQ|v+I1bsVbq96UmOHp!)P#lI#-)!%(D1G zQ_&~~cPv-wuJ|I@Rh_kP2sr11y4ZaQtWF>Pr9d9tp!S2pk0z{>2k zvHUvRXdZt?k!#m@n4KqIGN3#bmRv`J<;isnIJq7NmZu19;H=~0!Sbx*v0&G+{+y@2 zt2q230V_8f;+73T0**)F1eFGsCty2RN9qhL&pJK>7rcdW;lc1+G<<7Ojr2>_1j?=)^&2c(B zn?qgf&H$^+DmxQ=DpyvST$|XR1-7zTsb_%DPT&zAgDzhw~96xCWVg0a#svUkFx~;NJop-1E+o%C*V- zi@??3--aveKHWp!^^b`2QSA)ht5-t@hvCZn(VAdO;3>EI%v}mrH@x8cmsu`@RGlq{E35us zSOJeS^>MZmtStR)I!w`aHOr(C^{OrdASq0iJ}^XYL=s>camBuKM~DTv_9r zpZD*P_9B8f(;$;y0;|j2{TXZk<+;1RfR*R&UIu%2IcenD#OGhZNvQGnpT8kcctPdv z{tiz<>NEKtV0CF!uYi>q+ynkqu)zm#Q&v{4P3Hd-oZ#%dvUm-F!pkecUxz2S`b_>8 zSY3ku8>}qB-vArD6JG|GYvX*+*wx^4&NsoU`;6&Q&O!MWg0#*xV7U`dNB0g`$2xtR zQJypQUGQVr=+JrUO^Bg*zj4O?2lzf$&e#vY%HHFOr9UZ+o^~hKu6nWzhNl!g(Obtf zfnM;GOkM0+`ch++sadOrT;9q~IFP44eZZ+t<85A3XL;5Er#!ydlPAc!;GEmO<&)>! zUav2E%!6BpPShX)`-7F6jDh9q4EPbS_Ua5QPr&uT`cY?KdCu((!0T~&Zhw@K`?stu zg^CTi6nb!rtL0Um#5Mw_627ODC$UYysf6z=zRZ;8 zjNKgU8EY_|I$4_p{diNJYRJ`jdTj~bys{Ryg6E7y_u(14H42qF@$IQRPPPT>B#ZPD zaAno=bUSz)tIym|g4OBQm$35acJTQtT*;m=+ri)+xGtqbxF|;=8v<9p0vq{Iurh7p zXh*nyGG`~Svdq~TtjsyK%USr@1wORoAC+e3D`ACkx+~a9$er+Mur@k4AHEw{8|B*A zMfLz^ZTL!AuFggK8F1Eyub1Vefql2EvviGN;3t`&0}a)u7kn116MI1t{Twpoc|3cA zm9646TjmXiXPzJ#uQVC5!fV0i)_3D#bnf#nH!6j(p%j0-P|w8o=R7}U~z zjnR*#Q~p&hW!|~C+8LE6vC-gE;ux?zi5&+{C5{Elhxv|)^SBrTd79BlDzj>j2WQph zF4~YO&*K^kR@U{kx9e;j2hTk3R<2$35&9^*e`Af8P?9)phbzlhTy@H-cRrK_m!u{% z=jS!qiEw4r`N~qMZ-A{-WB*TtC`hR$gHx(WV0i*{fU{<%faO^;CxKlv`g5N81e^+1 zo;4#!S2jA+$q*-G(Z~~U8dyhJH1e#O>0pDpX1>Yj$2FsT2A49|jJR4kFo)#>9LMtOASgO&ML=1cK;0a%&((nI50kW}D8uw11T_%=8d zxCksa$i<90%9(Kq_!;b-ubukrqVIsS8uwdg3K0UlU^_f zuB@80GUpFV){fOOT26WX4+BSe{#TJzom)>GRNly}eF&BM%!4ayL1wDzlqI$KP5bbh z;QL~;fJXr=Zss3tl*i^rDzFK^1>U1;&QXm?w<6F;#Z65|w}Ex0&blsO^kZGs-Oi=V zx{AHEV{s~9&^d4Rka8hX|IeF*y#qcFo?E>Wu8s2i&{+h2g)cpRUGNXNnR^# z-3@lWa7vu-PTKGP0TRQ;umAu6 delta 13014 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 KPrver9sdW4cEV`@ diff --git a/piet-gpu/shader/gen/kernel4.dxil b/piet-gpu/shader/gen/kernel4.dxil index da6c56306152a11db46427763591ff31027185e4..0322bf6b4ee86dece87a7ae16e94f5527a4fa1fd 100644 GIT binary patch delta 9293 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 TPWPvT?fN3^RS^Z%asK;X0)&sx delta 10687 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 diff --git a/piet-gpu/shader/gen/kernel4.hlsl b/piet-gpu/shader/gen/kernel4.hlsl index 5d6f839..4839db2 100644 --- a/piet-gpu/shader/gen/kernel4.hlsl +++ b/piet-gpu/shader/gen/kernel4.hlsl @@ -162,7 +162,7 @@ struct Config static const uint3 gl_WorkGroupSize = uint3(8u, 4u, 1u); RWByteAddressBuffer _297 : register(u0, space0); -ByteAddressBuffer _1749 : register(t1, space0); +ByteAddressBuffer _1681 : register(t1, space0); RWTexture2D image_atlas : register(u3, space0); RWTexture2D gradients : register(u4, space0); RWTexture2D image : register(u2, space0); @@ -347,10 +347,7 @@ CmdColor Cmd_Color_read(Alloc a, CmdRef ref) float3 fromsRGB(float3 srgb) { - bool3 cutoff = bool3(srgb.x >= 0.040449999272823333740234375f.xxx.x, srgb.y >= 0.040449999272823333740234375f.xxx.y, srgb.z >= 0.040449999272823333740234375f.xxx.z); - float3 below = srgb / 12.9200000762939453125f.xxx; - float3 above = pow((srgb + 0.054999999701976776123046875f.xxx) / 1.05499994754791259765625f.xxx, 2.400000095367431640625f.xxx); - return float3(cutoff.x ? above.x : below.x, cutoff.y ? above.y : below.y, cutoff.z ? above.z : below.z); + return srgb; } float4 unpacksRGB(uint srgba) @@ -477,10 +474,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 _1721 = fromsRGB(param_1); - fg_rgba.x = _1721.x; - fg_rgba.y = _1721.y; - fg_rgba.z = _1721.z; + float3 _1653 = fromsRGB(param_1); + fg_rgba.x = _1653.x; + fg_rgba.y = _1653.y; + fg_rgba.z = _1653.z; rgba[i] = fg_rgba; } spvReturnValue = rgba; @@ -488,10 +485,7 @@ void fillImage(out float4 spvReturnValue[8], uint2 xy, CmdImage cmd_img) float3 tosRGB(float3 rgb) { - bool3 cutoff = bool3(rgb.x >= 0.003130800090730190277099609375f.xxx.x, rgb.y >= 0.003130800090730190277099609375f.xxx.y, rgb.z >= 0.003130800090730190277099609375f.xxx.z); - float3 below = 12.9200000762939453125f.xxx * rgb; - float3 above = (1.05499994754791259765625f.xxx * pow(rgb, 0.416660010814666748046875f.xxx)) - 0.054999999701976776123046875f.xxx; - return float3(cutoff.x ? above.x : below.x, cutoff.y ? above.y : below.y, cutoff.z ? above.z : below.z); + return rgb; } uint packsRGB(inout float4 rgba) @@ -529,7 +523,10 @@ float3 hard_light(float3 cb, float3 cs) { float3 param = cb; float3 param_1 = (cs * 2.0f) - 1.0f.xxx; - return lerp(screen(param, param_1), (cb * 2.0f) * cs, float3(bool3(cs.x <= 0.5f.xxx.x, cs.y <= 0.5f.xxx.y, cs.z <= 0.5f.xxx.z))); + float3 _889 = screen(param, param_1); + float3 _893 = (cb * 2.0f) * cs; + bool3 _898 = bool3(cs.x <= 0.5f.xxx.x, cs.y <= 0.5f.xxx.y, cs.z <= 0.5f.xxx.z); + return float3(_898.x ? _893.x : _889.x, _898.y ? _893.y : _889.y, _898.z ? _893.z : _889.z); } float color_dodge(float cb, float cs) @@ -572,8 +569,14 @@ float color_burn(float cb, float cs) float3 soft_light(float3 cb, float3 cs) { - float3 d = lerp(sqrt(cb), ((((cb * 16.0f) - 12.0f.xxx) * cb) + 4.0f.xxx) * cb, float3(bool3(cb.x <= 0.25f.xxx.x, cb.y <= 0.25f.xxx.y, cb.z <= 0.25f.xxx.z))); - return lerp(cb + (((cs * 2.0f) - 1.0f.xxx) * (d - cb)), cb - (((1.0f.xxx - (cs * 2.0f)) * cb) * (1.0f.xxx - cb)), float3(bool3(cs.x <= 0.5f.xxx.x, cs.y <= 0.5f.xxx.y, cs.z <= 0.5f.xxx.z))); + float3 _904 = sqrt(cb); + float3 _917 = ((((cb * 16.0f) - 12.0f.xxx) * cb) + 4.0f.xxx) * cb; + bool3 _921 = bool3(cb.x <= 0.25f.xxx.x, cb.y <= 0.25f.xxx.y, cb.z <= 0.25f.xxx.z); + float3 d = float3(_921.x ? _917.x : _904.x, _921.y ? _917.y : _904.y, _921.z ? _917.z : _904.z); + float3 _932 = cb + (((cs * 2.0f) - 1.0f.xxx) * (d - cb)); + float3 _942 = cb - (((1.0f.xxx - (cs * 2.0f)) * cb) * (1.0f.xxx - cb)); + bool3 _944 = bool3(cs.x <= 0.5f.xxx.x, cs.y <= 0.5f.xxx.y, cs.z <= 0.5f.xxx.z); + return float3(_944.x ? _942.x : _932.x, _944.y ? _942.y : _932.y, _944.z ? _942.z : _932.z); } float sat(float3 c) @@ -706,8 +709,8 @@ float3 set_lum(float3 c, float l) { float3 param = c; float3 param_1 = c + (l - lum(param)).xxx; - float3 _1052 = clip_color(param_1); - return _1052; + float3 _1048 = clip_color(param_1); + return _1048; } float3 mix_blend(float3 cb, float3 cs, uint mode) @@ -795,9 +798,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 _1343 = set_sat(param_21, param_22); + float3 _1340 = set_sat(param_21, param_22); float3 param_23 = cb; - float3 param_24 = _1343; + float3 param_24 = _1340; float param_25 = lum(param_23); b = set_lum(param_24, param_25); break; @@ -807,9 +810,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 _1357 = set_sat(param_27, param_28); + float3 _1354 = set_sat(param_27, param_28); float3 param_29 = cb; - float3 param_30 = _1357; + float3 param_30 = _1354; float param_31 = lum(param_29); b = set_lum(param_30, param_31); break; @@ -918,12 +921,6 @@ float4 mix_compose(float3 cb, float3 cs, float ab, float as, uint mode) break; } case 13u: - { - float rev_as = 1.0f - as; - float rev_ab = 1.0f - ab; - return max(0.0f.xxxx, float4((cs * rev_as) + (cb * rev_ab), rev_as + rev_ab)); - } - case 14u: { return min(1.0f.xxxx, float4((cs * as) + (cb * ab), as + ab)); } @@ -940,7 +937,7 @@ float4 mix_compose(float3 cb, float3 cs, float ab, float as, uint mode) float4 mix_blend_compose(float4 backdrop, float4 src, uint mode) { - if (mode == 3u) + if ((mode & 32767u) == 3u) { return (backdrop * (1.0f - src.w)) + src; } @@ -949,12 +946,12 @@ float4 mix_blend_compose(float4 backdrop, float4 src, uint mode) float inv_backdrop_a = 1.0f / (backdrop.w + 1.0000000036274937255387218471014e-15f); float3 cb = backdrop.xyz * inv_backdrop_a; uint blend_mode = mode >> uint(8); - float3 param = cs; - float3 param_1 = cb; + float3 param = cb; + float3 param_1 = cs; uint param_2 = blend_mode; float3 blended = mix_blend(param, param_1, param_2); cs = lerp(cs, blended, backdrop.w.xxx); - uint comp_mode = mode * 255u; + uint comp_mode = mode & 255u; if (comp_mode == 3u) { float3 co = lerp(backdrop.xyz, cs, src.w.xxx); @@ -992,16 +989,16 @@ CmdJump Cmd_Jump_read(Alloc a, CmdRef ref) void comp_main() { - uint tile_ix = (gl_WorkGroupID.y * _1749.Load(8)) + gl_WorkGroupID.x; - Alloc _1764; - _1764.offset = _1749.Load(24); + uint tile_ix = (gl_WorkGroupID.y * _1681.Load(8)) + gl_WorkGroupID.x; + Alloc _1696; + _1696.offset = _1681.Load(24); Alloc param; - param.offset = _1764.offset; + param.offset = _1696.offset; uint param_1 = tile_ix * 1024u; uint param_2 = 1024u; Alloc cmd_alloc = slice_mem(param, param_1, param_2); - CmdRef _1773 = { cmd_alloc.offset }; - CmdRef cmd_ref = _1773; + CmdRef _1705 = { cmd_alloc.offset }; + CmdRef cmd_ref = _1705; 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]; @@ -1035,8 +1032,8 @@ void comp_main() { df[k] = 1000000000.0f; } - TileSegRef _1867 = { stroke.tile_ref }; - tile_seg_ref = _1867; + TileSegRef _1800 = { stroke.tile_ref }; + tile_seg_ref = _1800; do { uint param_7 = tile_seg_ref.offset; @@ -1072,8 +1069,8 @@ void comp_main() { area[k_3] = float(fill.backdrop); } - TileSegRef _1987 = { fill.tile_ref }; - tile_seg_ref = _1987; + TileSegRef _1920 = { fill.tile_ref }; + tile_seg_ref = _1920; do { uint param_15 = tile_seg_ref.offset; @@ -1162,10 +1159,10 @@ 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 _2321 = fromsRGB(param_29); - fg_rgba.x = _2321.x; - fg_rgba.y = _2321.y; - fg_rgba.z = _2321.z; + float3 _2254 = fromsRGB(param_29); + fg_rgba.x = _2254.x; + fg_rgba.y = _2254.y; + fg_rgba.z = _2254.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; } @@ -1188,10 +1185,10 @@ void comp_main() 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 _2431 = fromsRGB(param_33); - fg_rgba_1.x = _2431.x; - fg_rgba_1.y = _2431.y; - fg_rgba_1.z = _2431.z; + float3 _2364 = fromsRGB(param_33); + fg_rgba_1.x = _2364.x; + fg_rgba_1.y = _2364.y; + fg_rgba_1.z = _2364.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; } @@ -1205,9 +1202,9 @@ void comp_main() CmdImage fill_img = Cmd_Image_read(param_34, param_35); uint2 param_36 = xy_uint; CmdImage param_37 = fill_img; - float4 _2474[8]; - fillImage(_2474, param_36, param_37); - float4 img[8] = _2474; + float4 _2407[8]; + fillImage(_2407, param_36, param_37); + float4 img[8] = _2407; for (uint k_11 = 0u; k_11 < 8u; k_11++) { float4 fg_k_3 = img[k_11] * area[k_11]; @@ -1222,8 +1219,8 @@ void comp_main() { uint d_2 = min(clip_depth, 127u); float4 param_38 = float4(rgba[k_12]); - uint _2537 = packsRGB(param_38); - blend_stack[d_2][k_12] = _2537; + uint _2470 = packsRGB(param_38); + blend_stack[d_2][k_12] = _2470; rgba[k_12] = 0.0f.xxxx; } clip_depth++; @@ -1256,8 +1253,8 @@ void comp_main() { Alloc param_45 = cmd_alloc; CmdRef param_46 = cmd_ref; - CmdRef _2615 = { Cmd_Jump_read(param_45, param_46).new_ref }; - cmd_ref = _2615; + CmdRef _2548 = { Cmd_Jump_read(param_45, param_46).new_ref }; + cmd_ref = _2548; cmd_alloc.offset = cmd_ref.offset; break; } diff --git a/piet-gpu/shader/gen/kernel4.msl b/piet-gpu/shader/gen/kernel4.msl index 796043b..4caeaf0 100644 --- a/piet-gpu/shader/gen/kernel4.msl +++ b/piet-gpu/shader/gen/kernel4.msl @@ -393,10 +393,7 @@ CmdColor Cmd_Color_read(thread const Alloc& a, thread const CmdRef& ref, device static inline __attribute__((always_inline)) float3 fromsRGB(thread const float3& srgb) { - bool3 cutoff = srgb >= float3(0.040449999272823333740234375); - float3 below = srgb / float3(12.9200000762939453125); - float3 above = pow((srgb + float3(0.054999999701976776123046875)) / float3(1.05499994754791259765625), float3(2.400000095367431640625)); - return select(below, above, cutoff); + return srgb; } static inline __attribute__((always_inline)) @@ -528,10 +525,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 _1721 = fromsRGB(param_1); - fg_rgba.x = _1721.x; - fg_rgba.y = _1721.y; - fg_rgba.z = _1721.z; + float3 _1653 = fromsRGB(param_1); + fg_rgba.x = _1653.x; + fg_rgba.y = _1653.y; + fg_rgba.z = _1653.z; rgba[i] = fg_rgba; } return rgba; @@ -540,10 +537,7 @@ spvUnsafeArray fillImage(thread const uint2& xy, thread const CmdImag static inline __attribute__((always_inline)) float3 tosRGB(thread const float3& rgb) { - bool3 cutoff = rgb >= float3(0.003130800090730190277099609375); - float3 below = float3(12.9200000762939453125) * rgb; - float3 above = (float3(1.05499994754791259765625) * pow(rgb, float3(0.416660010814666748046875))) - float3(0.054999999701976776123046875); - return select(below, above, cutoff); + return rgb; } static inline __attribute__((always_inline)) @@ -585,7 +579,7 @@ float3 hard_light(thread const float3& cb, thread const float3& cs) { float3 param = cb; float3 param_1 = (cs * 2.0) - float3(1.0); - return mix(screen(param, param_1), (cb * 2.0) * cs, float3(cs <= float3(0.5))); + return select(screen(param, param_1), (cb * 2.0) * cs, cs <= float3(0.5)); } static inline __attribute__((always_inline)) @@ -631,8 +625,8 @@ float color_burn(thread const float& cb, thread const float& cs) static inline __attribute__((always_inline)) float3 soft_light(thread const float3& cb, thread const float3& cs) { - float3 d = mix(sqrt(cb), ((((cb * 16.0) - float3(12.0)) * cb) + float3(4.0)) * cb, float3(cb <= float3(0.25))); - return mix(cb + (((cs * 2.0) - float3(1.0)) * (d - cb)), cb - (((float3(1.0) - (cs * 2.0)) * cb) * (float3(1.0) - cb)), float3(cs <= float3(0.5))); + float3 d = select(sqrt(cb), ((((cb * 16.0) - float3(12.0)) * cb) + float3(4.0)) * cb, cb <= float3(0.25)); + return select(cb + (((cs * 2.0) - float3(1.0)) * (d - cb)), cb - (((float3(1.0) - (cs * 2.0)) * cb) * (float3(1.0) - cb)), cs <= float3(0.5)); } static inline __attribute__((always_inline)) @@ -771,8 +765,8 @@ float3 set_lum(thread const float3& c, thread const float& l) { float3 param = c; float3 param_1 = c + float3(l - lum(param)); - float3 _1052 = clip_color(param_1); - return _1052; + float3 _1048 = clip_color(param_1); + return _1048; } static inline __attribute__((always_inline)) @@ -861,9 +855,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 _1343 = set_sat(param_21, param_22); + float3 _1340 = set_sat(param_21, param_22); float3 param_23 = cb; - float3 param_24 = _1343; + float3 param_24 = _1340; float param_25 = lum(param_23); b = set_lum(param_24, param_25); break; @@ -873,9 +867,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 _1357 = set_sat(param_27, param_28); + float3 _1354 = set_sat(param_27, param_28); float3 param_29 = cb; - float3 param_30 = _1357; + float3 param_30 = _1354; float param_31 = lum(param_29); b = set_lum(param_30, param_31); break; @@ -985,12 +979,6 @@ float4 mix_compose(thread const float3& cb, thread const float3& cs, thread cons break; } case 13u: - { - float rev_as = 1.0 - as; - float rev_ab = 1.0 - ab; - return fast::max(float4(0.0), float4((cs * rev_as) + (cb * rev_ab), rev_as + rev_ab)); - } - case 14u: { return fast::min(float4(1.0), float4((cs * as) + (cb * ab), as + ab)); } @@ -1008,7 +996,7 @@ float4 mix_compose(thread const float3& cb, thread const float3& cs, thread cons static inline __attribute__((always_inline)) float4 mix_blend_compose(thread const float4& backdrop, thread const float4& src, thread const uint& mode) { - if (mode == 3u) + if ((mode & 32767u) == 3u) { return (backdrop * (1.0 - src.w)) + src; } @@ -1017,12 +1005,12 @@ float4 mix_blend_compose(thread const float4& backdrop, thread const float4& src float inv_backdrop_a = 1.0 / (backdrop.w + 1.0000000036274937255387218471014e-15); float3 cb = backdrop.xyz * inv_backdrop_a; uint blend_mode = mode >> uint(8); - float3 param = cs; - float3 param_1 = cb; + float3 param = cb; + float3 param_1 = cs; uint param_2 = blend_mode; float3 blended = mix_blend(param, param_1, param_2); cs = mix(cs, blended, float3(backdrop.w)); - uint comp_mode = mode * 255u; + uint comp_mode = mode & 255u; if (comp_mode == 3u) { float3 co = mix(backdrop.xyz, cs, float3(src.w)); @@ -1059,11 +1047,11 @@ CmdJump Cmd_Jump_read(thread const Alloc& a, thread const CmdRef& ref, device Me return CmdJump_read(param, param_1, v_297); } -kernel void main0(device Memory& v_297 [[buffer(0)]], const device ConfigBuf& _1749 [[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_297 [[buffer(0)]], const device ConfigBuf& _1681 [[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 * _1749.conf.width_in_tiles) + gl_WorkGroupID.x; + uint tile_ix = (gl_WorkGroupID.y * _1681.conf.width_in_tiles) + gl_WorkGroupID.x; Alloc param; - param.offset = _1749.conf.ptcl_alloc.offset; + param.offset = _1681.conf.ptcl_alloc.offset; uint param_1 = tile_ix * 1024u; uint param_2 = 1024u; Alloc cmd_alloc = slice_mem(param, param_1, param_2); @@ -1226,10 +1214,10 @@ kernel void main0(device Memory& v_297 [[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 _2321 = fromsRGB(param_29); - fg_rgba.x = _2321.x; - fg_rgba.y = _2321.y; - fg_rgba.z = _2321.z; + float3 _2254 = fromsRGB(param_29); + fg_rgba.x = _2254.x; + fg_rgba.y = _2254.y; + fg_rgba.z = _2254.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; } @@ -1252,10 +1240,10 @@ kernel void main0(device Memory& v_297 [[buffer(0)]], const device ConfigBuf& _1 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 _2431 = fromsRGB(param_33); - fg_rgba_1.x = _2431.x; - fg_rgba_1.y = _2431.y; - fg_rgba_1.z = _2431.z; + float3 _2364 = fromsRGB(param_33); + fg_rgba_1.x = _2364.x; + fg_rgba_1.y = _2364.y; + fg_rgba_1.z = _2364.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; } @@ -1285,8 +1273,8 @@ kernel void main0(device Memory& v_297 [[buffer(0)]], const device ConfigBuf& _1 { uint d_2 = min(clip_depth, 127u); float4 param_38 = float4(rgba[k_12]); - uint _2537 = packsRGB(param_38); - blend_stack[d_2][k_12] = _2537; + uint _2470 = packsRGB(param_38); + blend_stack[d_2][k_12] = _2470; rgba[k_12] = float4(0.0); } clip_depth++; diff --git a/piet-gpu/shader/gen/kernel4.spv b/piet-gpu/shader/gen/kernel4.spv index b145245533171d27c8272c481f98a9d7bfa57cfc..f0e29634b2b9d08bc0070eb64f30f96acb59c5d6 100644 GIT binary patch literal 64668 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 diff --git a/piet-gpu/shader/gen/kernel4_gray.dxil b/piet-gpu/shader/gen/kernel4_gray.dxil index abe1d225b002617025777d5c355ec77cbff70d71..d48974d6811f75016bae7d23cf71a05a570a3b9d 100644 GIT binary patch delta 9276 zcmbVSdsI`$y5D*2gs=k%&mAHp;Uy|+!b?Pr2_T}NMnpt>1pr ztkx*CMe8GoT5GLMAef+>8e41AR&AivQmegzW7}Z0-q{d5cdhf^WwFSf+23nse!p+N znef35_XZt`cPF)l)Do#g=B?(`~ynP4aO2`b#q`PY*RO?dHx@$Ef9B)G_~Lqof$D8J^&|^4HnR8Kn1;R4yzW48M}E8hHY_CqaZU`THt=KNh?+)iMsc8%<}>m# z1|6|^@<*)mH5+KW+Nt_AA;bRHS>7Td3{;MDn4VRp5PTpFm21^ zqvnbAC<;+jIHh-)9f-leiO`7;xg_tcAe{F}MIfm{y?DGFy?n3GkGwhm32%RAa_ly} zO*yV9CHrTwPbW-dzyw~o5GmwAop3dMq(KCYtk5Z2lWR};d^_FHnN#Z>`c>iS&ci-W zfGE8L6Sas(L@6VUbkH!~D_l~$CI5->oO*ifHix4ZxF~<7z+A{1Mt!Wq6svWkK0qTY zRIoz~eEc}$Eb!qQ<^Vo|eV<`IHejL_`>2nRMmlH!A4q>;Xj4kPd8QGl@C~)w!Jyzj zoFgM4kBnq9rdmxOX%ImpD^&iaDXat7WhLoH4FNIr$i@tHy9iI%IFIQ)G+Gl?GaD9QBR?g(v1~fQ4KwBmM zuJ4ERmz`y)awu2flk$LWBceTV#JRleB#Pz(-lEFIdbIe?5PgaRn@93MJ4sI=o6pnoeKbB;sdD zdi?aF2~%)^it0Rm}&GWIL=8=~S)V+@; zaa3DS#W|mkoc^=HR1qKZpcSFw-tm=14h7}QLg-4$2l#xK#fW1VI-&Ay;yp%tT_GVn zvli!gVx$(`_3MPw4L$_pH_E`9;juL|jU*J7e4I8(*Oia3=yKc)#1w0e6Z4OzsV4-Q zK!E;Z0TwtcQ;EqV@j2ea7c`ygV_pd26NV<>JVY~-7B!|h{ad_n;#=7!&lGPR^dF#C zca^0=xe;$nuF`a+5Q{h0w|#`}(zLBbXUMZmNG>vT@hMJvP2%U`uS)iE>nkkQ>IlKo zfv%+$!3A^6BqZ79Y3Mf9;u?yJpRTy05n*c>d0}&qHi9^sa&#uRKHSg_hwU%NyGJvV`6O#6qkNmQ z_B(qF@219#C8cp+h(gR*1~5bUJ6Jq)BV{!KDP@L4qYF3$$yKh6#?zNnG&x_I^1Z*r z3!am2^0=Bi9^HYq5YfVVbR1Y!b3@p9##2ikxe@Ypfd$1ELS+H&i08FDoN67iD1 zCnVvIqx@uuPE>c!Dvf~lo%5NzIP5XD;2n^C0@|tP2qIuINNW|gxf_U5eo+NR4XezV zAr4v*TAVuTmK5Nj8fRF_tC=H`c}9NK_aVhzG&&_dF9-GuCtpcc@@+it*G^zqj#=JrM)Tk|G3PV> zqPWLm4yx0drd~-o+ojRiMq(BZLu_7_qEX-`=R)iPvwRG16N}h#hSLi07Es9cKzP-@ z{@OC)-x!30(JSAWr>wNh0SpjgeA+P>&WkIT3yBzOOy2171~5zxMvc{$%zc0wB0eD6 z^VE#IVlc7w7@LCQ``BQ76$s$w4FiM81WQ>A2>5)?emfRjB!QO&(Q=Uui`Ok8aZd)C zC>~aS5-}dn679uU!x)eEux41ZwlG0^8%s#1zaNM(|nLlS&zwjWkCD)#A)OucI zmnB+YXbQ!?Zph8~{jm2FW4D96}y<=}XD4CCiq^K{`J@H=n4Pn-}p3jVq0 zU0x@`gNQ?Ig*vU5NEYj63_BVuRyB12Cu6HF!m^`-J{~DdrK`M=c6OWEo$rFj;{0h5e71oFd~7?2-GAU~7^gZyALC`@K_wB#{9$odRq ztPvUy+`d38kCT@R>(h8pq|Z&1&%@Y1XN@yzY}(gYqN)xR5>Ad&;W%4BQW~k0Vqe8g zHG4?PSu#a=6hQSCIs!GT`56cT(wzjy+~wurKgz81dIIp9Su24kq4oUHg6y`fKZ`dy zhw|F)vssGqprA-05`<4A^$Y@*kn*!@)~GyV&bhftH48xfdoBtUk)@t=c`)v^-&o#= z8}xH`8*zg^W=J;!m0C<#1`cXsG)p|m_}vrla&iIjswlAG&$QK&Cg{5-uITYw<2vPV zx^N=coNx=p(Ir5_kc%t#N>y1JxzJ zmjH6+lmHUmn|J$c41^|GVp&0iW{^<6`_oOnsE_OuCyi(GeWV7hk>O*249w}D??;PH9Q-p)`EZYhY#Ky|o#NG=~1-5d|%&7D);@fcrK zOVe;d6wC1+Y$2A)4XStVG6+O4=L7bd(w$Mp=DXEUtEuEtwb4wKWbD&1&k9Q~)gLj( z*I(;sji^uQh>3VKN04FKC#%;452M_vL(Nfkcp|+0cAxNvC$335{KXO^0za(h+N?T} z;6wV*@+ZzIySK(}s|fx=)Rc1d_K%TSp$|xv0pazcYA?Qq2QzLOb@LA03{Q|delr2w zCWivtaxNL>M{P5xKEF%NC1)UXfGoqu$Lx!nC6yWec!S2S^n_heTUijzJBEe*(YfJI>nF}b28TFrcI9T<^qMRV|yFctyer(!t zUiDCZH{=$15_J4CbE|*-MQ5>7stjjG*ZEU9F552xB^}y@p;4#UD zSOsf%44bpB_^;&IH6jAo#M58+&nS-hrCrxN6 zafqL$(@tWlWj&n!_Ite>UVgOVi7V;#Pm{M*vFIgk?6;iI(Z z=P5Yqeyoz>f}}8VWcfo(?Ote1#kK@0#q6o1B$m|6{#Wf-C8d6268)V1J5kQZY?A86 zY_83SyEFqw!)z{iN$}V_wU{=%up$k!8RRo&v%EU3*MDHdX44y+tY`FL;w;Q$SHqae z@pA>00vw8&+#Nd><~NJc(~Ec+Er>ut!q(ARssr73A4=|dWi(3! zF1}fIXfZcJK5t6bU3%_4PvLega&EPd5|lfdw{c)eN7B}>rv%jcTBAE3lz%GRShZ7s zXaXrAVKiBhr=QA^qy;_Ijj3=y5>uz3WflX5xszM^T3B07L4hl~4})I-Qb~e{lHm^* ziV~D4s3Gjh4LH(GUW87|RLOeKeksg7e#$4Map8L7JyGqwb+o3G0eecDIfoot^ik5- zO4AFGw^|NejZBbVA^%NO_tr?>H%Xds$PGiEwFzXh3B%m+tF@+@}feJeTI{~CG z`7L+;s|4b!dyBv?ST)`e4za~c&66JyB3YsTWPW(`l#e`N$(@|q*(WEIo$h3RlbZmJ zP&No;%uYUbz>^>*kgWm;lCKt+0iCNR06L=tKBd&lCNUIINO6jK4&2*D>QrF zN7bi%KD@M~Gl#sSZ-R;<1tZ2%10S3$a`K}B&`x}sAQ~N-)MnOc88xz|6z5mVXJv&} zc%3tx^10fWcQ=Q;GG|iVe-z7)9eNs?C`bDPks6ljDqg+3CXS;vJhGhy^TljM7n+f$ ziJ7BYl*I4cQB}*4f+x;}yQ4sk8vjKI$WdRfVSpUvb%{C>$ViIv?2o4|XHN1wc3qzT zmgn*3%h?}$9!Xag{>JM#)i0G>vbwDl{Xs2*A9dWbt*y^Gukk#VzxC#EV7|k34WNAX>0VFVro;PS*<2 zLK>L&!JqG8ovRnhX^Q>kP1piloeUNrnGjFe+tlHGtEtkv)Ju0Q>RT1HAZzYuVvV2r z-S?*zSFprdIq!m`i9-W<@mreRnV@d;R0G|g&(ETqqjqGi2maOB=avc0yovhBlg-zS zs_(xF-{?K*>g363pSX~g^SmdNmIFNbEy^`8_-#?_h^O-f84nJFl{0?x&f=_4$KEf_ zoboCEX3hN^@|B?r`~I_XfF<8(HosYN&x-FwsfUHZ6P$6pROD*@k|p z8d&EIqirUuh9t;{b@7XocVb2J(fAcEd7FbeAQeTj{lkYH^lqyK`ot-{5@@%oc%WR9 za@ed}Lcw8jQcY*Inch$6gmYNw8-<@MQIpx9d>|~h#SVX9gik@usp!$vP*+EQ?=G=# zM&uAbyg|#Tla+c6nSEfvcAl$Et<+A?%Cg_?m)?qC$Je;^e2cZ7D;KmAhb8oPx~+zn z2eqOXQEb*zZ$Z+7U|G3os@q{STWe^7q;eO(^N^PLzO2X9FTF`0Q@1%S{nBDZ(GWi_ zlRxa>z(Z{!1Pm9otxZ0OCONsy`Cf^EFr88p@jItWwW&$z^O(a6>{PqaP~vk>ZJqY*KlNR5)pC3aI>4)* zZtCUuR3_`xy_6YcnEF+93Q%`DG4)=bryL&o8z_0h-l!8E%wKR*wOlm=XcK2}ep2}K zB)6)2HM8`Xwv9X!Xs4dI3ADNFAr6n_zsId-ztQe|kVmruZMh6RK;JXY`^NGbfkQ1x z#s_YRb(b<nh2M9}j zUP_WX0>8u@4{-xjy_ACF_K`6xro{eB!W9HL@Vh=_R+Zh_;GiAF67BN8PA}%x~73fTb}G|T1H&8%7av)54ggnp@>>90e5C9g0B-$y0NgVGxUKLC zuN{Z9=PaLfTl4Ub`lW==07JH`wY1-1c2<74pvjmni!H2kJ0vzMoF+&@huSKoebOg4 zE!O+{>$Ghv7Fev`pNsC3{+{PQ$UHD0uai%@(W`kM`m~RAV4zMnN$^8mx*%xW5MK@! z`XPO04QV!x{dZl4ASiaItzo1udoM|fW3%>U3W8=1@f%0_RvsX&#T^H%;$5!V=hhco zpCikj{3sl(Ja&t0G`;^T>q^^ybkP_C!v@_+PO&*u}rv>g`5X-XqD7soTLB)V@a+ zJ9Q^`xVJ}^J@p;%-~c@n`lMbAc2upk`Mr|-J-L7|*@VREO--V}3a;@- zNb5#7fpe=Ov0rNDvi*IBG+O0c4ghqTAcOe4Im)!BSL3L{lq*PiK)EO_2`HZc%Dm@d zty}*#P&Os?W7+jB-@i24)0lGQf0QW?Z8UlBdnHw*m6UQpUxeV#FeNx2(}wd6-PWfq zf1Gsy7;$~vHYcD6f0(8LDHnZCpMLXZYu zLk;eHIq+|o)h|sK9$$`Mi5@8P{Zo8nIlRKKN0Qt(>p>cz+j==J7(a>OU#H!l34(i^ zCJ4H!l$FoPjTCGT2llS|4xx&;^`pok49_g;rz`BvxQSb|CwXm~;uq1{L6* zsh0_XVYevA4rI@QzXtGXBkmcH<>zBZ$=hT#1NoNp4p4KBASrf;pHY{I%~m~qKxz@P zSsb^6ZnnZ+U{Acp6BnYNn&7Md^*N5)eH`T1r>O#B#>zoHexH`HT-Ni?p_asnat|Rc zpteG1^ajrj3^^9wikjwmI59UC-j15O-}77xaQB%*;Vph6wCG##ARVCV)`?(%u4$Y7 z0k9$R8UXA^kqfbv5B{FZTlwi>cfL^tpwa3-oL^zH?kri>CpCKm%yAaUN3o{bjvlc4 z&s+@ll+Bb{Npk9-Zf0dEAi(ajB@XFJwY;lcX%g~{P7-HXL$It`KGY1QE+$3E<2QHGd*-6*}%_|&dca9V0@W?VT zSr_mXj_trj?%4()pPu6)ZE=$t0y;!&i->I#Mef;5pVvDs9mqBW+yl)@ImZD$FyTxf z{EnM+5C{iZl#!$@9AMbpJ1!FlXNP9yWRedCIFy*|C_nZ^sjHCh_pG{K5=2;z6!AUX zA4d`1Ml>Qrmjvt1ru0dbIJQ3mb{ErHiv&B*O=(7c=cCn}V8TjdqX_7Y+>S?#C&&@l zQ#AP;L;m5%j9pZ1k8@cK91mxl-A=YT0zH7PGdhM|JP?H z!!H@`n06cT9j2q3yR4L0K}PW)e+%M4KlYWw${kEsu_At&H2xp-xzwZu*Ki}PdlkI{G%W`BI^znmbUz!wqCrY3XP z?_8rrqm7y?ixu@r)56)TfMJKxW<{g0Ou$byXc>gvB)o=TVuYz^^K!6vGfW&gVm5S|@D1efM^E6fMUUJB;O24SZV zo_HMkq?j7Mlq#4*jZUI+$mHn1;MiZ_li$LZtnid}@A4M!EjVA}pwD%o?+czUEYO)} z>3<9{vBFG0gqq|l!i)tm#*i4}kr*U^T$9qQ$~>%E(4eZ@kGGkX-Jj!bf2tg~jCg~iBNu>Fx9RW^r)4-#TCAfKY<_DkRNX+KW-u$f~W?VYKW#1x|Amte#pr= z<;?j&Qq%%%sgP{hWZJTkvvY%RSGhCpGgHzvPOuAN$^XaX{oLUDZ;6utz9=3(r@T$A zGF|Klbr*yg&(f(=CMi_M>QuBp{lO7yydcT32pqAv!wy{NcOh_7{=ATlpR_YZkoQt7J4X(SbV#4;1iEC*067+Y4l$^xm13zVcZSq@1lkmV- z{p%rcTN~Tvhl4HcebW!(csuY(jyU~d6TAXGN_9wX^H$?n<;+{LRqDx|?~^teOZ1l& LH1MB0V?X~3NyVZV delta 10523 zcmb7q3s_Uf_HUj$0g{mL+!!E%0HOjW2#A0&0R#l9h>D=7fe50aqV-v$c|kypCJ04* z)u?Fk)dta4Ewu>*5|mn0)Yzg14pnMxPoP$VhuS+E63;#VbH97P%a@PLn!VR!X4Y@5 zH8ZiTYuKiSF%9ue6Do1eU4FMVo!*Y!dmdGD0k;jizGPE#F#ZKL?pV&cbEAFT#iKP_ zSKd_}nVXzDCsPuMLJ3fKl!k;tAv6k&LQzpDR0-%$Owv6K0R4wZHOtXQnk`NxknaO$ z6v`bJL36>OP^sX(s4kR8b^ug6|9WkDO#wAroazIq7x=SK!MqMwdgsW;L`aBZ5@k$S zNs};%tgVA_n0-YjCacPh`PTSz|_A!k^K^t()~7k-> zHV~bKxaZ$~ae4X}yO;&WjAB7fD49U>MCMnH4r^(htb~J5M443KvW+Q*v=--!>_Rn) zNraX}SoCnOEbK~a6(1vE!X-D)a#V3ndK8mU7`O$i2sB7zY$tQLKPaZ zYx7Hi3pLi_pnffLxjSVbarQsT@c69k8Tqr(y@DR6l<+O}7PNm|T;>qfHN!7thr03% z<$gj}n-uY7$J+iM8l}af%P9?8<%qFAL7KEpmOM?diK*xij}=*%K@myqoMp z(rMA0+A+q&F@gq&uq|e50nkx8!UH;Db~OSWKXJ{7j)rj^6A-?Dae@zs>`E2G3RFCD z9RVu-5EFLgzO??;Hl~9aP{g1Fn0 zc^Atk;lepbs3^~FIb}LdfQFh$dK#&Qj0v37<-W`#1$x{(W4R}^L45^1fhV5A$%^3_ zceqTsds*+(Qj!Jz1D5c=+(N3G^=KsbAAM}x0#Yrx8+|GH7PJcWDH;c55emBTd1@>z zn(onz>j;zj)V8{3p)*SGGtn%F2%yk?68}+4qQD)DDyuwGXZP8)8{IEc2Mi^NsM0O$ zimSQ%3b27?m14B{Wtns7U9UDM*-F7`AD}&d#DpuzRVaT*a3N{(wTdNR8uaswis7Mdl*!2;A*aaUydhITEQ*3*XSatp(H zw#|sD&qmKH!LM`J*N4v=O%!+`_KC}L9R}{)=+#ecXa@%NpuO1R(|LSF@7@-pO1)itB>wlR>YJ&_^F-fxJXSBRep_#4|)SWDl-Ni+s6m;1i zD0v>V%IS`)@~R-hk|Y+8+-1PLG3Elsb=rWTN{@s(-?w_Yes1X&p3~bh6xgLg9<0C)d##f=j?Nh?8{*%~Kc%kj1 z*QvXKyGYrn*Ula6DOEq%jhuYXpTE>@eN&*7*3zCs_>5Zp7aSvIVhT_tUdn={)Dw0q zmnU;E*Wq#Vu_-TEnthij1semch_|((y2If%9rJ_as7(z0GP~sYtar2lAh}sU^Yj6J z3IuyA3yP>8O!n(e7`R zte|0U=^n)2Xn`0z#(p#HsY+1?0v|4u7A*C9B}?7D5+I-)!ISsQeioQtHUgR!Yqc+8 zOd&wVK)dRd2_VA*;EX?27nG_Xi>q`9ns(AcCP#wt838ygE*x|XSV|rOz!l0p^#}kX zQO&q+UVFFKr*9T^2QHDS9H?2H&C=3(O#n3>9F`q5en%~)Qe0dlK+P5~y76H5HYC1~ z&Q~F$n8bFBqEoy_HIRY|L7+%J;E=h+Eu@8}>_lV+eUSN?x^n}rc$2E>5xjF>(;;|g zC4ksnUb|#o7B|atpmUL6;u3750Kaq7ba;zwzE?LSy4bYemdi63j|FhOqO5k0Ov-tg z+^Djzb+Nd8F799U#g^v`C+i$f*36z)J_;Y8VqX08vdsUI+xL-~2YFIXu~X=jgSOn0 z24nd?ZiwJDhhL+@yNXIJ142H|;X$qK3l#!8KsV0#RF@oCW8)*)Kd*cS#-6^Z;mL8Y7yRYW4L49!C$u<%X!=@ zK5ZB@7p%26Nf(BW&ML4-gEHG_nAoDoj6~5y(#BS52rl57j{PrMe3c5n0p&3B z9X=l;X4|KwZAC{g)!oH;q;!jfw(~A_EzSnkJ&}#-AdFx@d|)m|;=^7LAF`47unP_1 zgNrlKSIHT#b22(#Ww7lqzI7!-7XqS7EDp=-7bt011pT>L9V=w^Y0rU{%ccXbycHmZ zQGo;ym5_2ue>pP1-HxTc$Uodnom%upiXNq&0SgT}B;0u&3OH<^*aP)Vhct6RVAxEA zB;9&=yb9AAx;k<8Iqc57iQ5jG`eG6r)j;WhIcy{#RTM7_v9I?(ifzGSGjR1&elj$3 zE4#xUFQ?y+)Y}6`+#ge=C%`=XlS)Eemvd4`BoKiGcYW%e>@Xhmsdh>%GE1r|1*kQ% zM)Ac?>PwUj+0&w@0W>v4g4|>=6t6D^$V@K+2sCtlZ|VXFtiJ_-rglGeQhXR7E%sA@ zTK2>ltZ85+C6fU1Bt)D?03F|V_&At4*&-iFAnm9$57Us2 zE7Hhn?$WS0FwKL8j-u>f$>F=@DDz9*#6nh#w=N#o(gqY--7il%>SFN&+(ULdc)bpn9DvN5hc!>Q!=*G zFG^NjA)e4Xi&Dh5iS&fF#wp6U)<%{xGH~U9u-s%aR#jK4XhEzKeN}?xiVd-annQi` z1EDXAY@``JBlWV#VNOWVfH32h$tbIps%A`KFKyA#OWbvW}_U6I( zT}k%lsrcQ~%+_hcP3Y1AVUpNvT4ndGXHLfp#+!A|XpW|r)#rG@jRN)gUljcFXX((n zBf;I!WT@qKKM%x(so%P12}mxak$Qp22qketpmI@NTz!|#H^VPeAyS{Age>58W)o^S zj0&QVT0ja^^2<44t3U+FG8vuu+?*Qkz$xOKS!{Sc@kauw*oPS2xO@kr(X#Cd#wN9| z=$jWJLrB^Qu%e--L;?c}4UiD`_xux=oy@DE0#Gku20T8`5#>J;*2&%?^PFuUq>!k< zSv9NxTi#LL?i6>7g(Cct{RR@Qa=IqntH;YP1z&Sc8=OoO2V5$s&|=(g(3NreP?z0c zB14BciKP}HpT(fVwp^ypo^&Y;=abCMcGtHBxH+d7Wj)o7I%8JDEIl5(AC5w5TU^SY zNpX`rM3ZV0!3V^5_7NuTw3D2Dghy(lCI3o#R)*_~Yn$%NZxP?IKHkV3Zo=*w5T?E} z8EaolRg+#~84Df~xG@)1qEZ24#N5pt_8CX;>;t7Gb}$zmSnp_794IT%28aiQ^7kgA z;;#=zZNHM#X2`|H{!)G+So+X{MALK^A zT_ApqRnfoQo3tlOosOhNXNKNhMc-^l5BAXB1F3Og(g%^TSKXZP;x7@I_z{Q9)VbO# ziPA7c=11EdGLPR6yPlPmfyk^2cgTFXGK1q`8IzgwL1z5VZe;v7h{$%So83&pyq3*L z(y55ZU5yTr-`}75OBQwR>6!zK0RMMB+gA-O(#%_|pShYGP~mC4{{-2J9u_27IeJCS z_Y4-T^P{WxsSA6?ci2I(KhLc}Gd;wQ&xxFswOU(l8Ax_$uA>I@oP%$OvggO#;|m4p zUfP2qdlaT!*zFtvml!k%9!@p2e!iga9Lh6y?-}p`-Y$sZ6I0xwf+#7hU=edC-0UL; z)`3_eQ=jQ;PC7myG{$urDO(S!CcVNj#0!3O;-0ttyPS~^Dn_HhN>`mLt56ySZ7Zo2O$a=V8&4sqG zpFJ5!@Ngcf&oWIl?&Wh+wh!mMWX=@_J7@SAoUWu4oRh~^cufl1LY;VbGJY&{RIwpi zhxU{7n)kj@;%4enByME8fViQvxJ*{{ID_sFI*R(K9Pe88WVg+^C&yD#MFs`yw?;3vQQ zb8&d|(j@lM=4kK%{&3nUk$r?sJS}!IuzmTxJyvomH8xrVKs}dy!f#_RBYq&AyS3|6 zQRd+(w)(`yR?e9(EW)H^okr*zFjd=v9aCjm-|yD1-5JYGA?RGYF3C^|6t1$Zj_)elF0r<{} zE?mtn8DD7Z)lK=<^ZmQwx-rD69W0bi#LNb!wH9LR88IDJMM&8sjo;TX5*oQ9FRew$%>t9 zY#!y{c*#_6xo8kfHq^ykdw9et!!Li|_lh%=FCG*dvI&niHOu~;TokOTw}`J}ZX&*3 z^<`f(>*j#4Qq*ZYFmlilsZZt<-?9fq@u}hu?bBO}_mbZPGw8pA>9-tm0BuHeG~JFl z{?!l7IngonQuEXivu?$3)5-6UT&g!hf6G+lzwsyj!`JOeHE+SyQhTahvNYO}YQ;;0 z(S`QzrE8WAhp(Fu;;p{oh31Mu^zg0X*V z>aSkVm;;l4ODBG{H~Skm*`;_>^tlA0pb0D9zZ7@^&VYEr4ysU$1(b!aBm-~QNZ`aE zuHk1eqs;!bbP_0Zmt*C5ifL@QCimA~O}F-fcDg6f6n6iHBBw`Z**CuRgW(U#voBbB8x$z7_{Q88ya(yDZ0UVBGkJ>G6dhjp zNGn@*KT<^gf&J3?^a1uu;%TLI+6X+fYM6uR84xBncCLyIlr)1H2<|VnDOk=k=-i~V zkGN-RkBF3<=n-?_n&Bp0k3~p1-)Y1wl&fZ+4`H}0B!f7LoK0$b@^55dp}IJ0-km0Z4etHxF}W{w ztKwfk8Gbh9i>H!*yW>}Juky@y(f<=2eGnIpXV({H$;Hvcu7~BeTz03id=57zbC}al z1^~h^SROX`q|QjhbDMFK3vOT28+G9t6<#gMlne;5L5$nj&2rVJOL+_z1CJY0B^8xY zu_GQ~U49gIC`s)~qNlB+UPu24twa&#`Nn>dwZE0FPNdgjRyqsIoVV#*79?2tGvR76 zC^nP1DM7=BgH42Z*k;!2j1-7_Hes0abG2%cO4J4S3p=QcX$o7H+kkx0w26!hC3Cqs z4~~IcF~erIZn8F^pIfH+HudEXkyA@&EC!MA=pD~zvpQZUZyx%<4b<@gVhn`I~Ia z-V*%R$Xi@9&=~01i)ef&amC2LSq!$g7d~jrXV=fV?o#@@3@qMjJ+CsrioQYkMDV-b zpOo5__yqqfOpFb+@!7sZ&Re`i%_NPLAbqkd9MmAW8pq*LG(5QCDgNv>zNpxVR{$)3 zuX`%zYToKx6|7Cte~uZR7yut=#NQkrX z)X~pGN^jjfZih>scp`(o*_9jf${!pe%(RhGtFR-U&&tYUYgYhws*(f3?n!y^7f*;T z`kCi(A5wk;To3u6I+lw{a|t8nX|C3$RsI&?4+%PB&`z~#&KoA9<`th?3_MC$rSeG< zDSi5dT~vlpVKZleq9vUhvv9a6K&ldxokXQ+mT4Jk*EU-4(C+r>zVqFzh!Y3X#O>g4 z5}c;U=YQq)dLm=#o_95>OXYuoME)OS05@V7;X{abHT zyaz8#4`9&OCvszY%N$@}RCtb5p`y&Ga%CmPtHH|fe7`bN4k@^Wk&kDKCE0w84yBx6T%U7#dU7hWE~ zeIwIT8FIZPykE$HTV{(gA^F!;D)OcPh6`l`=6DY`p{iA4&&_~#8-bU53~^eR{le`4 ziw&_Pi}0W?WaX@;U~RCEZMG=PW)T)yy@#4m;88JZ!cY?vG-d}fSZ)BLV9Rk|q9T8e zX3*zixgq2s&gv@F9Dw6k?1;Gx8gA+%fdq+R(A{hR(5nDEOJnj`+!*>7VjANp`4Koz z9J@IRvhHw)^v;TN;TcedD`91<95)$0mI)e z_XgTD^x-D{bPzt)n~VnoxOJqVrj=uEXFpj9sN>Ip1~~rq5?ib+5*(E7a2%Sbi`0Os zHQLWVihLSZO8li{K3IfX@`TzAb!e|F;On8T!&v}+i_$6p;1lj70r)LMdt)+ao_kd1 zQke{}B{uK9k|w%169XKhdsQ9ETfyp;&jbSWp1D9knd&VS2*}ZiD|CY7lz!nb&1A%+ za#L8*Zj1{m9ybQ}`f#wWqOaz$DqMcZf+Vfk`gz>^-WAG+j!2pOznPS_Qk;y~Gwz`6fhBs^s@s%_=H56Y>QBi20% zTyD=tt<%`wYl!xYL;XP$C70PVjxYgxpL9SFTNv9Z0aLb#51d44%iUx!x&?uxHryoU zSF6bTM9TU7!ekzUg?k5cx{VN#8&&rlSYsh!YL72^nZV+rp@pnJ_~D$7)TNr zJQ*yl4X$oCeiGRYM1kEq4q)75jGD?#!M)}rYE(4rE>I%a%xuWoBqfbSJb(c)a@U|P zDf^7yD7j_#`rrwgRqV-*Gr*7u7Xfw3eoSlJ1HJO8O&26lPxKLU@;rY&S`=EjoTy;s z7A->H;VS~3B=B5}c+!fJN}cIUe!s8}coHVBT7|C^y~@8A%*}}aPOSADfoa|1RdpIa z1#A789Kc=R+X}d^dFBIdXd~eM@#kgz!e0^Y<$$|dl)3zQF!v3@jq*mg$C-6MFD~Cu zC-wa?fGuh|WP`uO4L51>2ZYiP#!ue6_Ne+YfPdbbjZDPh;F8Kd;ugL)u$xEtn5Yo5 z?#*5Xxcd<9YNx}t`tJa@W!Zob?PD^gon6^440H!L*Z~gY5cmJFAhvM%!0eG?pN9c{ zvc9TMPI?1)W>sz_W)|gya21ijHk0>At_2$A)bBWKgKs0otN=wUz^QC2e8B3x8yVeJ zFuIcB;(oD^1H@y%c^`folX3g-(LJgMnZVr46o_m36DGtQdg6H zOT|W>{Nu7^dS5HwFMn|wK_mc=9s*!Umg&7secl4_?k*}}7n5N2>_Bg=_!#v23KnMp z@}5)x{v+?Im+8gcwm$Eb;N?6j;W0qe){2dm%8$VVU-lODvH-u8iv^(np#w!(WK&eu z;aa|rJ2^dydDnrW`Q%$sOsFpzi*)}VK{Piy>plRH7da;?3$TrYXfgS@IO+q6mPc#u ze?XDsfne?j6tQx!abyHVjXxkL>h1IUA1L~NfJh$?K%|J*^8fo=oSHUq0zeTq;XhE6 z6ZQXtA{PWiO>3>^`A@pP?=`GOeXc(Wv7oW;t7}mg_`SOCe=@D6evUo{h2Vyo1nVur z)?QH9UYCkNnT7nOA%A#6&l)ySe;nF6p=Y)ICL#4EbaMi!)eg&d6Gqo$ITF>YwU!Hf zzCEYuztn#TrLuiFlGQv=#SODvrNJqpuo?YACpVCDK~e+>dN#KsbchoO0s&^15*`#{ zaSVE(O>AcBSJespp~<8qe>3yHz7?#X8Ds=q{=)(6{=F(%u1IO>7jB(U0%WOGG?_>V z4+xKVGg#nKCZO9`CFRCcp+%)Ih%`LNUbK&e(e*Lij|AH`Pu#XW+WdgGSUw(I#n;MW z%#WBN-HUCXL|YyR7GuFhYc88>@T6#>9-}WBUE@}yO9{iO<6hAR7S3uHFdI>w^3j^IH_^LB(wV@ zlQ~rF=iB&%t~*XQt)Qy~Iw+#qrS!DRCbX+|h|Y^G2dUkG*nFwRUZu{c@Pv~hh=e}%4Sx}l>0G{_0k`| zMfYBpj$TDOL8X?+Z*(y?nBGLu$x-`%+m>$9FXcRF%; zzRO&xbB^Du^4#jdnDQ!=8`DrND$Qbzn6)XxO;Q!$V1V-yu1vMR)S3dS$wS}<(HFQP zFIe#lG%*<7t$tUK=yZ!=vM~JBWr?TU_DqNO#4w#2gF19UzgvQeowCJ+b$QYmWg5T}l8 z9eaV3p>}(CneX3j%#VRTx7CN3j92*Fv$SDOOyGd9bfL*;HmOxUSg;qi2s==Wr5@wA znPQoK{&(o#p;)@(M$^1O{SE&P^x?+=^uhI-W;DlsFZdq%hW@IQ*X7n&ev&`A)7Z`X zbU;|5O&{jWJU?-y-v4opC{y+O9I$J#a)c5@VP@SMC&yv1vP^PQ|M-LKAm0Y@2FX_r z;i*o9m-L2pJbOeaXw|=i*3hZo?0}P1+1_@=Gp%OMaEj zvfStf@~mRH)Ab;RdrCStWDuM`bYn;0lZ0W842%jtrPD~t0mq#XI1ogNDaHaXF!PND z-ah>y=>(IU%bdiALeb6>Io*ZUA`LXGaZO8Cqthj=b4XWUkx!#EVGw)JZKcFbQ|5*Z zhgLvqER=VW2Aq!u7kUi*9;slSL5!SX{TYQEWb)^=BE%maB*`965&=2T%!&nWs0bv> zS|16-*hZchYrl^BLLsM8Y%#=?SQy+Cpb#d*M|p$U{PWH9B* zUO$Q!L#KS9xJK6Cu8{=>9a2l4=TLg5XFcKh5%XhX5B#I#neHHiA^^W&>McWo%Mb87 zC^Te1HOE9BM6-8eV$6}|Y#p=|vO1dux7lmZ^irQsBDTxJ+j{XEv_ image_atlas : register(u3, space0); RWTexture2D gradients : register(u4, space0); RWTexture2D image : register(u2, space0); @@ -347,10 +347,7 @@ CmdColor Cmd_Color_read(Alloc a, CmdRef ref) float3 fromsRGB(float3 srgb) { - bool3 cutoff = bool3(srgb.x >= 0.040449999272823333740234375f.xxx.x, srgb.y >= 0.040449999272823333740234375f.xxx.y, srgb.z >= 0.040449999272823333740234375f.xxx.z); - float3 below = srgb / 12.9200000762939453125f.xxx; - float3 above = pow((srgb + 0.054999999701976776123046875f.xxx) / 1.05499994754791259765625f.xxx, 2.400000095367431640625f.xxx); - return float3(cutoff.x ? above.x : below.x, cutoff.y ? above.y : below.y, cutoff.z ? above.z : below.z); + return srgb; } float4 unpacksRGB(uint srgba) @@ -477,10 +474,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 _1721 = fromsRGB(param_1); - fg_rgba.x = _1721.x; - fg_rgba.y = _1721.y; - fg_rgba.z = _1721.z; + float3 _1653 = fromsRGB(param_1); + fg_rgba.x = _1653.x; + fg_rgba.y = _1653.y; + fg_rgba.z = _1653.z; rgba[i] = fg_rgba; } spvReturnValue = rgba; @@ -488,10 +485,7 @@ void fillImage(out float4 spvReturnValue[8], uint2 xy, CmdImage cmd_img) float3 tosRGB(float3 rgb) { - bool3 cutoff = bool3(rgb.x >= 0.003130800090730190277099609375f.xxx.x, rgb.y >= 0.003130800090730190277099609375f.xxx.y, rgb.z >= 0.003130800090730190277099609375f.xxx.z); - float3 below = 12.9200000762939453125f.xxx * rgb; - float3 above = (1.05499994754791259765625f.xxx * pow(rgb, 0.416660010814666748046875f.xxx)) - 0.054999999701976776123046875f.xxx; - return float3(cutoff.x ? above.x : below.x, cutoff.y ? above.y : below.y, cutoff.z ? above.z : below.z); + return rgb; } uint packsRGB(inout float4 rgba) @@ -529,7 +523,10 @@ float3 hard_light(float3 cb, float3 cs) { float3 param = cb; float3 param_1 = (cs * 2.0f) - 1.0f.xxx; - return lerp(screen(param, param_1), (cb * 2.0f) * cs, float3(bool3(cs.x <= 0.5f.xxx.x, cs.y <= 0.5f.xxx.y, cs.z <= 0.5f.xxx.z))); + float3 _889 = screen(param, param_1); + float3 _893 = (cb * 2.0f) * cs; + bool3 _898 = bool3(cs.x <= 0.5f.xxx.x, cs.y <= 0.5f.xxx.y, cs.z <= 0.5f.xxx.z); + return float3(_898.x ? _893.x : _889.x, _898.y ? _893.y : _889.y, _898.z ? _893.z : _889.z); } float color_dodge(float cb, float cs) @@ -572,8 +569,14 @@ float color_burn(float cb, float cs) float3 soft_light(float3 cb, float3 cs) { - float3 d = lerp(sqrt(cb), ((((cb * 16.0f) - 12.0f.xxx) * cb) + 4.0f.xxx) * cb, float3(bool3(cb.x <= 0.25f.xxx.x, cb.y <= 0.25f.xxx.y, cb.z <= 0.25f.xxx.z))); - return lerp(cb + (((cs * 2.0f) - 1.0f.xxx) * (d - cb)), cb - (((1.0f.xxx - (cs * 2.0f)) * cb) * (1.0f.xxx - cb)), float3(bool3(cs.x <= 0.5f.xxx.x, cs.y <= 0.5f.xxx.y, cs.z <= 0.5f.xxx.z))); + float3 _904 = sqrt(cb); + float3 _917 = ((((cb * 16.0f) - 12.0f.xxx) * cb) + 4.0f.xxx) * cb; + bool3 _921 = bool3(cb.x <= 0.25f.xxx.x, cb.y <= 0.25f.xxx.y, cb.z <= 0.25f.xxx.z); + float3 d = float3(_921.x ? _917.x : _904.x, _921.y ? _917.y : _904.y, _921.z ? _917.z : _904.z); + float3 _932 = cb + (((cs * 2.0f) - 1.0f.xxx) * (d - cb)); + float3 _942 = cb - (((1.0f.xxx - (cs * 2.0f)) * cb) * (1.0f.xxx - cb)); + bool3 _944 = bool3(cs.x <= 0.5f.xxx.x, cs.y <= 0.5f.xxx.y, cs.z <= 0.5f.xxx.z); + return float3(_944.x ? _942.x : _932.x, _944.y ? _942.y : _932.y, _944.z ? _942.z : _932.z); } float sat(float3 c) @@ -706,8 +709,8 @@ float3 set_lum(float3 c, float l) { float3 param = c; float3 param_1 = c + (l - lum(param)).xxx; - float3 _1052 = clip_color(param_1); - return _1052; + float3 _1048 = clip_color(param_1); + return _1048; } float3 mix_blend(float3 cb, float3 cs, uint mode) @@ -795,9 +798,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 _1343 = set_sat(param_21, param_22); + float3 _1340 = set_sat(param_21, param_22); float3 param_23 = cb; - float3 param_24 = _1343; + float3 param_24 = _1340; float param_25 = lum(param_23); b = set_lum(param_24, param_25); break; @@ -807,9 +810,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 _1357 = set_sat(param_27, param_28); + float3 _1354 = set_sat(param_27, param_28); float3 param_29 = cb; - float3 param_30 = _1357; + float3 param_30 = _1354; float param_31 = lum(param_29); b = set_lum(param_30, param_31); break; @@ -918,12 +921,6 @@ float4 mix_compose(float3 cb, float3 cs, float ab, float as, uint mode) break; } case 13u: - { - float rev_as = 1.0f - as; - float rev_ab = 1.0f - ab; - return max(0.0f.xxxx, float4((cs * rev_as) + (cb * rev_ab), rev_as + rev_ab)); - } - case 14u: { return min(1.0f.xxxx, float4((cs * as) + (cb * ab), as + ab)); } @@ -940,7 +937,7 @@ float4 mix_compose(float3 cb, float3 cs, float ab, float as, uint mode) float4 mix_blend_compose(float4 backdrop, float4 src, uint mode) { - if (mode == 3u) + if ((mode & 32767u) == 3u) { return (backdrop * (1.0f - src.w)) + src; } @@ -949,12 +946,12 @@ float4 mix_blend_compose(float4 backdrop, float4 src, uint mode) float inv_backdrop_a = 1.0f / (backdrop.w + 1.0000000036274937255387218471014e-15f); float3 cb = backdrop.xyz * inv_backdrop_a; uint blend_mode = mode >> uint(8); - float3 param = cs; - float3 param_1 = cb; + float3 param = cb; + float3 param_1 = cs; uint param_2 = blend_mode; float3 blended = mix_blend(param, param_1, param_2); cs = lerp(cs, blended, backdrop.w.xxx); - uint comp_mode = mode * 255u; + uint comp_mode = mode & 255u; if (comp_mode == 3u) { float3 co = lerp(backdrop.xyz, cs, src.w.xxx); @@ -992,16 +989,16 @@ CmdJump Cmd_Jump_read(Alloc a, CmdRef ref) void comp_main() { - uint tile_ix = (gl_WorkGroupID.y * _1749.Load(8)) + gl_WorkGroupID.x; - Alloc _1764; - _1764.offset = _1749.Load(24); + uint tile_ix = (gl_WorkGroupID.y * _1681.Load(8)) + gl_WorkGroupID.x; + Alloc _1696; + _1696.offset = _1681.Load(24); Alloc param; - param.offset = _1764.offset; + param.offset = _1696.offset; uint param_1 = tile_ix * 1024u; uint param_2 = 1024u; Alloc cmd_alloc = slice_mem(param, param_1, param_2); - CmdRef _1773 = { cmd_alloc.offset }; - CmdRef cmd_ref = _1773; + CmdRef _1705 = { cmd_alloc.offset }; + CmdRef cmd_ref = _1705; 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]; @@ -1035,8 +1032,8 @@ void comp_main() { df[k] = 1000000000.0f; } - TileSegRef _1867 = { stroke.tile_ref }; - tile_seg_ref = _1867; + TileSegRef _1800 = { stroke.tile_ref }; + tile_seg_ref = _1800; do { uint param_7 = tile_seg_ref.offset; @@ -1072,8 +1069,8 @@ void comp_main() { area[k_3] = float(fill.backdrop); } - TileSegRef _1987 = { fill.tile_ref }; - tile_seg_ref = _1987; + TileSegRef _1920 = { fill.tile_ref }; + tile_seg_ref = _1920; do { uint param_15 = tile_seg_ref.offset; @@ -1162,10 +1159,10 @@ 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 _2321 = fromsRGB(param_29); - fg_rgba.x = _2321.x; - fg_rgba.y = _2321.y; - fg_rgba.z = _2321.z; + float3 _2254 = fromsRGB(param_29); + fg_rgba.x = _2254.x; + fg_rgba.y = _2254.y; + fg_rgba.z = _2254.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; } @@ -1188,10 +1185,10 @@ void comp_main() 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 _2431 = fromsRGB(param_33); - fg_rgba_1.x = _2431.x; - fg_rgba_1.y = _2431.y; - fg_rgba_1.z = _2431.z; + float3 _2364 = fromsRGB(param_33); + fg_rgba_1.x = _2364.x; + fg_rgba_1.y = _2364.y; + fg_rgba_1.z = _2364.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; } @@ -1205,9 +1202,9 @@ void comp_main() CmdImage fill_img = Cmd_Image_read(param_34, param_35); uint2 param_36 = xy_uint; CmdImage param_37 = fill_img; - float4 _2474[8]; - fillImage(_2474, param_36, param_37); - float4 img[8] = _2474; + float4 _2407[8]; + fillImage(_2407, param_36, param_37); + float4 img[8] = _2407; for (uint k_11 = 0u; k_11 < 8u; k_11++) { float4 fg_k_3 = img[k_11] * area[k_11]; @@ -1222,8 +1219,8 @@ void comp_main() { uint d_2 = min(clip_depth, 127u); float4 param_38 = float4(rgba[k_12]); - uint _2537 = packsRGB(param_38); - blend_stack[d_2][k_12] = _2537; + uint _2470 = packsRGB(param_38); + blend_stack[d_2][k_12] = _2470; rgba[k_12] = 0.0f.xxxx; } clip_depth++; @@ -1256,8 +1253,8 @@ void comp_main() { Alloc param_45 = cmd_alloc; CmdRef param_46 = cmd_ref; - CmdRef _2615 = { Cmd_Jump_read(param_45, param_46).new_ref }; - cmd_ref = _2615; + CmdRef _2548 = { Cmd_Jump_read(param_45, param_46).new_ref }; + cmd_ref = _2548; cmd_alloc.offset = cmd_ref.offset; break; } diff --git a/piet-gpu/shader/gen/kernel4_gray.msl b/piet-gpu/shader/gen/kernel4_gray.msl index 9647001..8c608c3 100644 --- a/piet-gpu/shader/gen/kernel4_gray.msl +++ b/piet-gpu/shader/gen/kernel4_gray.msl @@ -393,10 +393,7 @@ CmdColor Cmd_Color_read(thread const Alloc& a, thread const CmdRef& ref, device static inline __attribute__((always_inline)) float3 fromsRGB(thread const float3& srgb) { - bool3 cutoff = srgb >= float3(0.040449999272823333740234375); - float3 below = srgb / float3(12.9200000762939453125); - float3 above = pow((srgb + float3(0.054999999701976776123046875)) / float3(1.05499994754791259765625), float3(2.400000095367431640625)); - return select(below, above, cutoff); + return srgb; } static inline __attribute__((always_inline)) @@ -528,10 +525,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 _1721 = fromsRGB(param_1); - fg_rgba.x = _1721.x; - fg_rgba.y = _1721.y; - fg_rgba.z = _1721.z; + float3 _1653 = fromsRGB(param_1); + fg_rgba.x = _1653.x; + fg_rgba.y = _1653.y; + fg_rgba.z = _1653.z; rgba[i] = fg_rgba; } return rgba; @@ -540,10 +537,7 @@ spvUnsafeArray fillImage(thread const uint2& xy, thread const CmdImag static inline __attribute__((always_inline)) float3 tosRGB(thread const float3& rgb) { - bool3 cutoff = rgb >= float3(0.003130800090730190277099609375); - float3 below = float3(12.9200000762939453125) * rgb; - float3 above = (float3(1.05499994754791259765625) * pow(rgb, float3(0.416660010814666748046875))) - float3(0.054999999701976776123046875); - return select(below, above, cutoff); + return rgb; } static inline __attribute__((always_inline)) @@ -585,7 +579,7 @@ float3 hard_light(thread const float3& cb, thread const float3& cs) { float3 param = cb; float3 param_1 = (cs * 2.0) - float3(1.0); - return mix(screen(param, param_1), (cb * 2.0) * cs, float3(cs <= float3(0.5))); + return select(screen(param, param_1), (cb * 2.0) * cs, cs <= float3(0.5)); } static inline __attribute__((always_inline)) @@ -631,8 +625,8 @@ float color_burn(thread const float& cb, thread const float& cs) static inline __attribute__((always_inline)) float3 soft_light(thread const float3& cb, thread const float3& cs) { - float3 d = mix(sqrt(cb), ((((cb * 16.0) - float3(12.0)) * cb) + float3(4.0)) * cb, float3(cb <= float3(0.25))); - return mix(cb + (((cs * 2.0) - float3(1.0)) * (d - cb)), cb - (((float3(1.0) - (cs * 2.0)) * cb) * (float3(1.0) - cb)), float3(cs <= float3(0.5))); + float3 d = select(sqrt(cb), ((((cb * 16.0) - float3(12.0)) * cb) + float3(4.0)) * cb, cb <= float3(0.25)); + return select(cb + (((cs * 2.0) - float3(1.0)) * (d - cb)), cb - (((float3(1.0) - (cs * 2.0)) * cb) * (float3(1.0) - cb)), cs <= float3(0.5)); } static inline __attribute__((always_inline)) @@ -771,8 +765,8 @@ float3 set_lum(thread const float3& c, thread const float& l) { float3 param = c; float3 param_1 = c + float3(l - lum(param)); - float3 _1052 = clip_color(param_1); - return _1052; + float3 _1048 = clip_color(param_1); + return _1048; } static inline __attribute__((always_inline)) @@ -861,9 +855,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 _1343 = set_sat(param_21, param_22); + float3 _1340 = set_sat(param_21, param_22); float3 param_23 = cb; - float3 param_24 = _1343; + float3 param_24 = _1340; float param_25 = lum(param_23); b = set_lum(param_24, param_25); break; @@ -873,9 +867,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 _1357 = set_sat(param_27, param_28); + float3 _1354 = set_sat(param_27, param_28); float3 param_29 = cb; - float3 param_30 = _1357; + float3 param_30 = _1354; float param_31 = lum(param_29); b = set_lum(param_30, param_31); break; @@ -985,12 +979,6 @@ float4 mix_compose(thread const float3& cb, thread const float3& cs, thread cons break; } case 13u: - { - float rev_as = 1.0 - as; - float rev_ab = 1.0 - ab; - return fast::max(float4(0.0), float4((cs * rev_as) + (cb * rev_ab), rev_as + rev_ab)); - } - case 14u: { return fast::min(float4(1.0), float4((cs * as) + (cb * ab), as + ab)); } @@ -1008,7 +996,7 @@ float4 mix_compose(thread const float3& cb, thread const float3& cs, thread cons static inline __attribute__((always_inline)) float4 mix_blend_compose(thread const float4& backdrop, thread const float4& src, thread const uint& mode) { - if (mode == 3u) + if ((mode & 32767u) == 3u) { return (backdrop * (1.0 - src.w)) + src; } @@ -1017,12 +1005,12 @@ float4 mix_blend_compose(thread const float4& backdrop, thread const float4& src float inv_backdrop_a = 1.0 / (backdrop.w + 1.0000000036274937255387218471014e-15); float3 cb = backdrop.xyz * inv_backdrop_a; uint blend_mode = mode >> uint(8); - float3 param = cs; - float3 param_1 = cb; + float3 param = cb; + float3 param_1 = cs; uint param_2 = blend_mode; float3 blended = mix_blend(param, param_1, param_2); cs = mix(cs, blended, float3(backdrop.w)); - uint comp_mode = mode * 255u; + uint comp_mode = mode & 255u; if (comp_mode == 3u) { float3 co = mix(backdrop.xyz, cs, float3(src.w)); @@ -1059,11 +1047,11 @@ CmdJump Cmd_Jump_read(thread const Alloc& a, thread const CmdRef& ref, device Me return CmdJump_read(param, param_1, v_297); } -kernel void main0(device Memory& v_297 [[buffer(0)]], const device ConfigBuf& _1749 [[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_297 [[buffer(0)]], const device ConfigBuf& _1681 [[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 * _1749.conf.width_in_tiles) + gl_WorkGroupID.x; + uint tile_ix = (gl_WorkGroupID.y * _1681.conf.width_in_tiles) + gl_WorkGroupID.x; Alloc param; - param.offset = _1749.conf.ptcl_alloc.offset; + param.offset = _1681.conf.ptcl_alloc.offset; uint param_1 = tile_ix * 1024u; uint param_2 = 1024u; Alloc cmd_alloc = slice_mem(param, param_1, param_2); @@ -1226,10 +1214,10 @@ kernel void main0(device Memory& v_297 [[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 _2321 = fromsRGB(param_29); - fg_rgba.x = _2321.x; - fg_rgba.y = _2321.y; - fg_rgba.z = _2321.z; + float3 _2254 = fromsRGB(param_29); + fg_rgba.x = _2254.x; + fg_rgba.y = _2254.y; + fg_rgba.z = _2254.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; } @@ -1252,10 +1240,10 @@ kernel void main0(device Memory& v_297 [[buffer(0)]], const device ConfigBuf& _1 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 _2431 = fromsRGB(param_33); - fg_rgba_1.x = _2431.x; - fg_rgba_1.y = _2431.y; - fg_rgba_1.z = _2431.z; + float3 _2364 = fromsRGB(param_33); + fg_rgba_1.x = _2364.x; + fg_rgba_1.y = _2364.y; + fg_rgba_1.z = _2364.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; } @@ -1285,8 +1273,8 @@ kernel void main0(device Memory& v_297 [[buffer(0)]], const device ConfigBuf& _1 { uint d_2 = min(clip_depth, 127u); float4 param_38 = float4(rgba[k_12]); - uint _2537 = packsRGB(param_38); - blend_stack[d_2][k_12] = _2537; + uint _2470 = packsRGB(param_38); + blend_stack[d_2][k_12] = _2470; rgba[k_12] = float4(0.0); } clip_depth++; diff --git a/piet-gpu/shader/gen/kernel4_gray.spv b/piet-gpu/shader/gen/kernel4_gray.spv index 2dd46c0c42af01cab37314c1ccd977a619948efb..6ff17912d610740bfa9563c86085fdaf0330ee73 100644 GIT binary patch literal 64424 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 M*nFOgV$a3@4`5AT`Tzg` diff --git a/piet-gpu/shader/kernel4.comp b/piet-gpu/shader/kernel4.comp index a0710d2..99fd22e 100644 --- a/piet-gpu/shader/kernel4.comp +++ b/piet-gpu/shader/kernel4.comp @@ -9,6 +9,11 @@ #version 450 #extension GL_GOOGLE_include_directive : enable +// We can do rendering either in sRGB colorspace (for compatibility) +// or in a linear colorspace, with conversions to sRGB (which will give +// higher quality antialiasing among other things). +#define DO_SRGB_CONVERSION 0 + #include "mem.h" #include "setup.h" @@ -39,18 +44,26 @@ layout(rgba8, set = 0, binding = 4) uniform restrict readonly image2D gradients; #define MAX_BLEND_STACK 128 mediump vec3 tosRGB(mediump vec3 rgb) { +#if DO_SRGB_CONVERSION bvec3 cutoff = greaterThanEqual(rgb, vec3(0.0031308)); mediump vec3 below = vec3(12.92) * rgb; mediump vec3 above = vec3(1.055) * pow(rgb, vec3(0.41666)) - vec3(0.055); return mix(below, above, cutoff); +#else + return rgb; +#endif } mediump vec3 fromsRGB(mediump vec3 srgb) { +#if DO_SRGB_CONVERSION // Formula from EXT_sRGB. bvec3 cutoff = greaterThanEqual(srgb, vec3(0.04045)); mediump vec3 below = srgb / vec3(12.92); mediump vec3 above = pow((srgb + vec3(0.055)) / vec3(1.055), vec3(2.4)); return mix(below, above, cutoff); +#else + return srgb; +#endif } // unpacksRGB unpacks a color in the sRGB color space to a vec4 in the linear color diff --git a/piet-gpu/src/blend.rs b/piet-gpu/src/blend.rs index 7edcb4e..f0ca002 100644 --- a/piet-gpu/src/blend.rs +++ b/piet-gpu/src/blend.rs @@ -33,6 +33,8 @@ pub enum BlendMode { Saturation = 13, Color = 14, Luminosity = 15, + // Clip is the same as normal, but doesn't always push a blend group. + Clip = 128, } #[derive(Copy, Clone, PartialEq, Eq, Debug)] @@ -76,7 +78,7 @@ impl Blend { impl Default for Blend { fn default() -> Self { Self { - mode: BlendMode::Normal, + mode: BlendMode::Clip, composition_mode: CompositionMode::SrcOver, } } diff --git a/piet-gpu/src/encoder.rs b/piet-gpu/src/encoder.rs index a24ddbc..d0ef1eb 100644 --- a/piet-gpu/src/encoder.rs +++ b/piet-gpu/src/encoder.rs @@ -306,16 +306,21 @@ 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 }; + 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); diff --git a/piet-gpu/src/gradient.rs b/piet-gpu/src/gradient.rs index e655908..443eaec 100644 --- a/piet-gpu/src/gradient.rs +++ b/piet-gpu/src/gradient.rs @@ -19,7 +19,7 @@ use std::collections::hash_map::{Entry, HashMap}; use piet::kurbo::Point; -use piet::{Color, FixedLinearGradient, GradientStop, FixedRadialGradient}; +use piet::{Color, FixedLinearGradient, FixedRadialGradient, GradientStop}; /// Radial gradient compatible with COLRv1 spec #[derive(Debug, Clone)] diff --git a/piet-gpu/src/lib.rs b/piet-gpu/src/lib.rs index d32a9c5..ba06e71 100644 --- a/piet-gpu/src/lib.rs +++ b/piet-gpu/src/lib.rs @@ -13,8 +13,8 @@ use std::convert::TryInto; pub use blend::{Blend, BlendMode, CompositionMode}; pub use encoder::EncodedSceneRef; -pub use render_ctx::PietGpuRenderContext; pub use gradient::Colrv1RadialGradient; +pub use render_ctx::PietGpuRenderContext; 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 dca03eb..14f2561 100644 --- a/piet-gpu/src/render_ctx.rs +++ b/piet-gpu/src/render_ctx.rs @@ -1,9 +1,12 @@ +// This should match the value in kernel4.comp for correct rendering. +const DO_SRGB_CONVERSION: bool = false; + use std::borrow::Cow; use crate::encoder::GlyphEncoder; use crate::stages::{Config, Transform}; use crate::MAX_BLEND_STACK; -use piet::kurbo::{Affine, Insets, PathEl, Point, Rect, Shape}; +use piet::kurbo::{Affine, PathEl, Point, Rect, Shape}; use piet::{ Color, Error, FixedGradient, ImageFormat, InterpolationMode, IntoBrush, RenderContext, StrokeStyle, @@ -13,7 +16,7 @@ use piet_gpu_hal::BufWrite; use piet_gpu_types::encoder::{Encode, Encoder}; use piet_gpu_types::scene::Element; -use crate::gradient::{LinearGradient, RadialGradient, RampCache, Colrv1RadialGradient}; +use crate::gradient::{Colrv1RadialGradient, LinearGradient, RadialGradient, RampCache}; use crate::text::Font; pub use crate::text::{PietGpuText, PietGpuTextLayout, PietGpuTextLayoutBuilder}; use crate::Blend; @@ -471,19 +474,27 @@ fn rect_to_f32_4(rect: Rect) -> [f32; 4] { } fn to_srgb(f: f64) -> f64 { - if f <= 0.0031308 { - f * 12.92 + if DO_SRGB_CONVERSION { + if f <= 0.0031308 { + f * 12.92 + } else { + let a = 0.055; + (1. + a) * f64::powf(f, f64::recip(2.4)) - a + } } else { - let a = 0.055; - (1. + a) * f64::powf(f, f64::recip(2.4)) - a + f } } fn from_srgb(f: f64) -> f64 { - if f <= 0.04045 { - f / 12.92 + if DO_SRGB_CONVERSION { + if f <= 0.04045 { + f / 12.92 + } else { + let a = 0.055; + f64::powf((f + a) * f64::recip(1. + a), 2.4) + } } else { - let a = 0.055; - f64::powf((f + a) * f64::recip(1. + a), 2.4) + f } } diff --git a/piet-gpu/src/stages/clip.rs b/piet-gpu/src/stages/clip.rs index 2fd195b..b7b77eb 100644 --- a/piet-gpu/src/stages/clip.rs +++ b/piet-gpu/src/stages/clip.rs @@ -16,7 +16,9 @@ //! The clip processing stage (includes substages). -use piet_gpu_hal::{include_shader, BindType, Buffer, ComputePass, DescriptorSet, Pipeline, Session}; +use piet_gpu_hal::{ + include_shader, BindType, Buffer, ComputePass, DescriptorSet, Pipeline, Session, +}; // Note that this isn't the code/stage/binding pattern of most of the other stages // in the new element processing pipeline. We want to move those temporary buffers diff --git a/piet-gpu/src/test_scenes.rs b/piet-gpu/src/test_scenes.rs index bfd2af2..e3aeaba 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, Colrv1RadialGradient}; +use crate::{Blend, BlendMode, Colrv1RadialGradient, CompositionMode, PietGpuRenderContext}; use piet::kurbo::{Affine, BezPath, Circle, Line, Point, Rect, Shape}; use piet::{ - Color, FixedGradient, FixedRadialGradient, GradientStop, Text, TextAttribute, TextLayoutBuilder, + Color, GradientStop, LinearGradient, Text, TextAttribute, TextLayoutBuilder, UnitPoint, }; use crate::{PicoSvg, RenderContext, Vec2}; @@ -200,6 +200,113 @@ fn render_tiger(rc: &mut impl RenderContext) { println!("flattening and encoding time: {:?}", start.elapsed()); } +pub fn render_blend_square(rc: &mut PietGpuRenderContext, blend: Blend) { + // Inspired by https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode + let rect = Rect::new(0., 0., 200., 200.); + let stops = vec![ + GradientStop { + color: Color::BLACK, + pos: 0.0, + }, + GradientStop { + color: Color::WHITE, + pos: 1.0, + }, + ]; + let linear = LinearGradient::new(UnitPoint::LEFT, UnitPoint::RIGHT, stops); + rc.fill(rect, &linear); + const GRADIENTS: &[(f64, f64, Color)] = &[ + (150., 0., Color::rgb8(255, 240, 64)), + (175., 100., Color::rgb8(255, 96, 240)), + (125., 200., Color::rgb8(64, 192, 255)), + ]; + for (x, y, c) in GRADIENTS { + let stops = vec![ + GradientStop { + color: c.clone(), + pos: 0.0, + }, + GradientStop { + color: Color::rgba8(0, 0, 0, 0), + pos: 1.0, + }, + ]; + let rad = Colrv1RadialGradient { + center0: Point::new(*x, *y), + center1: Point::new(*x, *y), + radius0: 0.0, + radius1: 100.0, + stops, + }; + let brush = rc.radial_gradient_colrv1(&rad); + rc.fill(Rect::new(0., 0., 200., 200.), &brush); + } + const COLORS: &[Color] = &[ + Color::rgb8(255, 0, 0), + Color::rgb8(0, 255, 0), + Color::rgb8(0, 0, 255), + ]; + let _ = rc.with_save(|rc| { + // Isolation (this can be removed for non-isolated version) + rc.blend(rect, BlendMode::Normal.into()); + for (i, c) in COLORS.iter().enumerate() { + let stops = vec![ + GradientStop { + color: Color::WHITE, + pos: 0.0, + }, + GradientStop { + color: c.clone(), + pos: 1.0, + }, + ]; + // squash the ellipse + let a = Affine::translate((100., 100.)) + * Affine::rotate(std::f64::consts::FRAC_PI_3 * (i * 2 + 1) as f64) + * Affine::scale_non_uniform(1.0, 0.357) + * Affine::translate((-100., -100.)); + let linear = LinearGradient::new(UnitPoint::TOP, UnitPoint::BOTTOM, stops); + let _ = rc.with_save(|rc| { + rc.blend(rect, blend); + rc.transform(a); + rc.fill(Circle::new((100., 100.), 90.), &linear); + Ok(()) + }); + } + Ok(()) + }); +} + +pub fn render_blend_grid(rc: &mut PietGpuRenderContext) { + const BLEND_MODES: &[BlendMode] = &[ + BlendMode::Normal, + BlendMode::Multiply, + BlendMode::Darken, + BlendMode::Screen, + BlendMode::Lighten, + BlendMode::Overlay, + BlendMode::ColorDodge, + BlendMode::ColorBurn, + BlendMode::HardLight, + BlendMode::SoftLight, + BlendMode::Difference, + BlendMode::Exclusion, + BlendMode::Hue, + BlendMode::Saturation, + BlendMode::Color, + BlendMode::Luminosity, + ]; + for (ix, &blend) in BLEND_MODES.iter().enumerate() { + let _ = rc.with_save(|rc| { + let i = ix % 4; + let j = ix / 4; + rc.transform(Affine::translate((i as f64 * 225., j as f64 * 225.))); + render_blend_square(rc, blend.into()); + Ok(()) + }); + } +} + pub fn render_anim_frame(rc: &mut impl RenderContext, i: usize) { rc.fill( Rect::new(0.0, 0.0, 1000.0, 1000.0), diff --git a/piet-scene/src/glyph/mod.rs b/piet-scene/src/glyph/mod.rs index 3bfa36c..81d9735 100644 --- a/piet-scene/src/glyph/mod.rs +++ b/piet-scene/src/glyph/mod.rs @@ -114,7 +114,9 @@ impl<'a> GlyphProvider<'a> { }; xform_stack.push(xform); } - Command::PopTransform => { xform_stack.pop(); }, + Command::PopTransform => { + xform_stack.pop(); + } Command::PushClip(path_index) => { let path = glyph.path(*path_index)?; if let Some(xform) = xform_stack.last() {