From bbdd4432f50eb3471fe0ad52b9f5452efa5a0e90 Mon Sep 17 00:00:00 2001 From: Commit by GitHub Action Date: Thu, 14 Jul 2022 14:28:45 +0000 Subject: [PATCH] commit compiled shaders --- piet-gpu/shader/gen/backdrop.dxil | Bin 4576 -> 4692 bytes piet-gpu/shader/gen/backdrop.hlsl | 107 +-- piet-gpu/shader/gen/backdrop.msl | 110 +-- piet-gpu/shader/gen/backdrop.spv | Bin 11508 -> 11832 bytes piet-gpu/shader/gen/backdrop_lg.dxil | Bin 4580 -> 4696 bytes piet-gpu/shader/gen/backdrop_lg.hlsl | 107 +-- piet-gpu/shader/gen/backdrop_lg.msl | 110 +-- piet-gpu/shader/gen/backdrop_lg.spv | Bin 11540 -> 11864 bytes piet-gpu/shader/gen/bbox_clear.dxil | Bin 3160 -> 3160 bytes piet-gpu/shader/gen/bbox_clear.hlsl | 13 +- piet-gpu/shader/gen/bbox_clear.msl | 2 + piet-gpu/shader/gen/bbox_clear.spv | Bin 3212 -> 3328 bytes piet-gpu/shader/gen/binning.dxil | Bin 6336 -> 5980 bytes piet-gpu/shader/gen/binning.hlsl | 214 ++---- piet-gpu/shader/gen/binning.msl | 211 ++---- piet-gpu/shader/gen/binning.spv | Bin 18536 -> 16368 bytes piet-gpu/shader/gen/clip_leaf.dxil | Bin 7228 -> 7228 bytes piet-gpu/shader/gen/clip_leaf.hlsl | 77 +-- piet-gpu/shader/gen/clip_leaf.msl | 18 +- piet-gpu/shader/gen/clip_leaf.spv | Bin 19240 -> 19356 bytes piet-gpu/shader/gen/clip_reduce.dxil | Bin 4624 -> 4628 bytes piet-gpu/shader/gen/clip_reduce.hlsl | 51 +- piet-gpu/shader/gen/clip_reduce.msl | 10 +- piet-gpu/shader/gen/clip_reduce.spv | Bin 9696 -> 9812 bytes piet-gpu/shader/gen/coarse.dxil | Bin 11972 -> 11724 bytes piet-gpu/shader/gen/coarse.hlsl | 742 ++++++++++----------- piet-gpu/shader/gen/coarse.msl | 775 +++++++++++----------- piet-gpu/shader/gen/coarse.spv | Bin 60516 -> 60088 bytes piet-gpu/shader/gen/draw_leaf.dxil | Bin 6764 -> 6768 bytes piet-gpu/shader/gen/draw_leaf.hlsl | 73 +- piet-gpu/shader/gen/draw_leaf.msl | 2 + piet-gpu/shader/gen/draw_leaf.spv | Bin 20104 -> 20204 bytes piet-gpu/shader/gen/draw_reduce.dxil | Bin 4260 -> 4260 bytes piet-gpu/shader/gen/draw_reduce.hlsl | 3 +- piet-gpu/shader/gen/draw_reduce.msl | 2 + piet-gpu/shader/gen/draw_reduce.spv | Bin 7140 -> 7240 bytes piet-gpu/shader/gen/kernel4.dxil | Bin 14484 -> 14524 bytes piet-gpu/shader/gen/kernel4.hlsl | 67 +- piet-gpu/shader/gen/kernel4.msl | 42 +- piet-gpu/shader/gen/kernel4.spv | Bin 66224 -> 66368 bytes piet-gpu/shader/gen/kernel4_gray.dxil | Bin 14564 -> 14600 bytes piet-gpu/shader/gen/kernel4_gray.hlsl | 67 +- piet-gpu/shader/gen/kernel4_gray.msl | 42 +- piet-gpu/shader/gen/kernel4_gray.spv | Bin 65980 -> 66124 bytes piet-gpu/shader/gen/path_coarse.dxil | Bin 7064 -> 7012 bytes piet-gpu/shader/gen/path_coarse.hlsl | 328 ++++----- piet-gpu/shader/gen/path_coarse.msl | 331 ++++----- piet-gpu/shader/gen/path_coarse.spv | Bin 39788 -> 39708 bytes piet-gpu/shader/gen/pathseg.dxil | Bin 9596 -> 9596 bytes piet-gpu/shader/gen/pathseg.hlsl | 115 ++-- piet-gpu/shader/gen/pathseg.msl | 66 +- piet-gpu/shader/gen/pathseg.spv | Bin 35212 -> 35296 bytes piet-gpu/shader/gen/pathtag_reduce.dxil | Bin 4644 -> 4644 bytes piet-gpu/shader/gen/pathtag_reduce.hlsl | 3 +- piet-gpu/shader/gen/pathtag_reduce.msl | 2 + piet-gpu/shader/gen/pathtag_reduce.spv | Bin 8300 -> 8400 bytes piet-gpu/shader/gen/tile_alloc.dxil | Bin 5132 -> 4904 bytes piet-gpu/shader/gen/tile_alloc.hlsl | 154 ++--- piet-gpu/shader/gen/tile_alloc.msl | 152 ++--- piet-gpu/shader/gen/tile_alloc.spv | Bin 13360 -> 12352 bytes piet-gpu/shader/gen/transform_leaf.dxil | Bin 5664 -> 5668 bytes piet-gpu/shader/gen/transform_leaf.hlsl | 53 +- piet-gpu/shader/gen/transform_leaf.msl | 34 +- piet-gpu/shader/gen/transform_leaf.spv | Bin 12972 -> 13088 bytes piet-gpu/shader/gen/transform_reduce.dxil | Bin 4700 -> 4700 bytes piet-gpu/shader/gen/transform_reduce.hlsl | 3 +- piet-gpu/shader/gen/transform_reduce.msl | 2 + piet-gpu/shader/gen/transform_reduce.spv | Bin 8324 -> 8424 bytes 68 files changed, 1994 insertions(+), 2094 deletions(-) diff --git a/piet-gpu/shader/gen/backdrop.dxil b/piet-gpu/shader/gen/backdrop.dxil index 0fb9622eda673c439b74f7538c649b770edef248..50f5badcde2fb7b3b663425d9cbb33292ba1fd60 100644 GIT binary patch delta 2469 zcmb_deM}VT9e!tac9{JDX4wUY4{`PbiOLLn@Fko{_KAn>i|B7usAp2{)IA zEh(If82D2(c)AW~4hq!M0>7R=E#I8OT_V90Y9X^Qgs~i{bAX&!mqeS0eO9=bimpEB z0J*Ud#!9z^#n`;*Vtms(V|zeUFR(@Jvk(Mr@a7THPj(hRiE;Uj@;b#wAmjN2L##nNoY(LerP6NCsaAX>I?dBLFB8 zJS4hP?O=^$G3Js%5I9EykRf21I=76hZbsDley4Ez!rAN5L=?BRDV%{~-06>l2!j_; zZd|Dc34}XIkg3){081VNpnpW%G@O_ z;1v>j!~fKkJT2F(+{PkaVxkY1d$>C)&{_z_Q}L$5JM>C zRVQQ70GWvO6tMr;8yMh~!8ng8 zHo}h8LwSl1{;$rguvtg|5W)0nWN(^yn5u;fnFJaut0H7pHXWRg*QH>?LpSR-Nt>$wn~LMVA2u;-tx#Zik7jjY}@kB>ma zWF}HhS%Vd5y!kjakNZRrE1;~LSR1*r16o86Qr$Qh3oWA2A*DpsMhIuFgJ}$@89ZAn zWe1u%^iP@5ojKWU{EV5z(kIV*lh1>?Dt92P}FP?^P_KI zE7|BeZ{r-)O*>hsWX)wb`v{HP1#@O6JEAp9DWWc?Osh=68%FJsZh?`0(?KX>ab_JD zLISjuR_1E2+t|70y=0R`qQgy~$M>e0pQpo0Cd!y(<2NOT3^@ZTmaQo?``6O4FF-0`f>*(EE@R#+t)l*DCK%~Uknjw? z&YER5ED78@E+LTR#NR-I2f5C2vUh`trs(ezf_OK5E+{_0Q0NL!S|G?a^d$sk@jHm% z7W0llhh;VE2yWVCE9Qjv{43JfCddIrwkP|ag}hb7tS#x#teY?b8a+++q&!G z0D75|*Dt1w|G-~!3N|=?PL$X%P98>N)QBSQtub2-*dXSE(|n7DXRHEKW+U;!mWy{$ z+vz>2{Zb(w6m4A+IT=ww;KF$tCA90Ct_&=|e)2hLCyqq_oy42gG$kR{!2@(NtsGXq vkGuVymMA!5E_2C9qHntPi)3?{NPeg_2<*IEkv-5Nvi}ie8({Gd@Wc2Q0G9*& delta 2127 zcmcIke^3mIUHz1mIC#RS;0_rXa<5~q?+m7fvG`gn1swYEp?h$Pd6)24<%Pg8>}bLkZ{!D#2j!0a?Vs#uFq@!cvDJr4wYzW+ zjKRS3w5KnpsGEIc&ei>yb+&FiQnriMkznET^XdJqpHwcy28km~vg7UCi?#rvmcC6y zY_eAqMApf1s8dJN0FCOvMjcPH09^KvM(i!M3djL;W773Z;jo&&#w~RM;VhzTLpe7r z2!P`Z01fgCxiwGxjRj2OZc8qK@$UKtKgcn+q1H5F-}b*{eEe~(ALN#`$6{jp#6jF%jwAOHtN%&_v`QdZfC=A zeM2$3CwZdj+|8B@ZDZ4k0qsCkBB&Q%gBnxwON$Sb+tH;AVwLNm(CCNH+kc-uKAs*n zuk7S5xTDXGy`$cNAkWHQ;xDpEITK%Q{nayIS1a9>Dy+mp5$}8trCw;Pn&zH^2C*Bx*?;xoXiRL`eYqpleZzezt5)fHAJZSKijhup^^bA|3Y&{^^R6Hli%Y~b=0Ml+>Rz0xSwOv zZ35g^or4ZNj!O{=$k)k2cFmk=1UJSr6j|M5#wRV%oJHb)8MDs6?2_}eiNt&k56)`f z1vse9SE<&I^=d!*AI@d3*KGj+fzN>f+nX7E67=xHY5|$0aAZGGr*LR-{~|f?;W^lsKgr(ZH`m1bB4rmmC3bwq^C72QO|4t^s}#TnIb+d>f>2 zfLBQthI^IM9g=W2TO|Su;l=Sp*DI^>(@=mgP9(ZgZ~~5I$HV0c!gQozAy45fF0%9D z6@;12#++=G6lKbZ9moUxW%e`;CSqM2K1N084#olqf4D5BcBDJJ0gmN1i}9^@lT>7gY4G^7`WkE86= zoUrPN*jliuMqsu9t?AB~x3lqFqwKrTcq`7V=H*(1z3L7494Dy*3-D zzOoR|uzfYh&M0)3k1nzKHV^UR%3FChBYb#vNA75>H2svSvB;vJ=Y@kOJLB?zuUvOf-}uJJ> uint(16), raw1 & 65535u, raw1 >> uint(16)); - TileRef _134 = { raw2 }; - s.tiles = _134; + TileRef _146 = { raw2 }; + s.tiles = _146; return s; } @@ -120,47 +128,52 @@ void write_mem(Alloc alloc, uint offset, uint val) { return; } - _67.Store(offset * 4 + 8, val); + _59.Store(offset * 4 + 12, val); } void comp_main() { + uint param = 7u; + bool _154 = check_deps(param); + if (!_154) + { + return; + } uint th_ix = gl_LocalInvocationIndex; uint element_ix = gl_GlobalInvocationID.x; uint row_count = 0u; - bool mem_ok = _67.Load(4) == 0u; if (gl_LocalInvocationID.y == 0u) { - if (element_ix < _166.Load(0)) + if (element_ix < _181.Load(4)) { - PathRef _180 = { _166.Load(16) + (element_ix * 12u) }; - PathRef path_ref = _180; - Alloc _185; - _185.offset = _166.Load(16); - Alloc param; - param.offset = _185.offset; - PathRef param_1 = path_ref; - Path path = Path_read(param, param_1); + PathRef _195 = { _181.Load(20) + (element_ix * 12u) }; + PathRef path_ref = _195; + Alloc _200; + _200.offset = _181.Load(20); + Alloc param_1; + param_1.offset = _200.offset; + PathRef param_2 = path_ref; + Path path = Path_read(param_1, param_2); sh_row_width[th_ix] = path.bbox.z - path.bbox.x; row_count = path.bbox.w - path.bbox.y; - bool _210 = row_count == 1u; - bool _216; - if (_210) + bool _225 = row_count == 1u; + bool _231; + if (_225) { - _216 = path.bbox.y > 0u; + _231 = path.bbox.y > 0u; } else { - _216 = _210; + _231 = _225; } - if (_216) + if (_231) { row_count = 0u; } - uint param_2 = path.tiles.offset; - uint param_3 = ((path.bbox.z - path.bbox.x) * (path.bbox.w - path.bbox.y)) * 8u; - bool param_4 = mem_ok; - Alloc path_alloc = new_alloc(param_2, param_3, param_4); + uint param_3 = path.tiles.offset; + uint param_4 = ((path.bbox.z - path.bbox.x) * (path.bbox.w - path.bbox.y)) * 8u; + bool param_5 = true; + Alloc path_alloc = new_alloc(param_3, param_4, param_5); sh_row_alloc[th_ix] = path_alloc; } sh_row_count[th_ix] = row_count; @@ -168,17 +181,17 @@ void comp_main() for (uint i = 0u; i < 8u; i++) { GroupMemoryBarrierWithGroupSync(); - bool _262 = gl_LocalInvocationID.y == 0u; - bool _269; - if (_262) + bool _276 = gl_LocalInvocationID.y == 0u; + bool _283; + if (_276) { - _269 = th_ix >= (1u << i); + _283 = th_ix >= (1u << i); } else { - _269 = _262; + _283 = _276; } - if (_269) + if (_283) { row_count += sh_row_count[th_ix - (1u << i)]; } @@ -190,7 +203,7 @@ void comp_main() } GroupMemoryBarrierWithGroupSync(); uint total_rows = sh_row_count[255]; - uint _348; + uint _360; for (uint row = th_ix; row < total_rows; row += 256u) { uint el_ix = 0u; @@ -203,32 +216,32 @@ void comp_main() } } uint width = sh_row_width[el_ix]; - if ((width > 0u) && mem_ok) + if (width > 0u) { Alloc tiles_alloc = sh_row_alloc[el_ix]; if (el_ix > 0u) { - _348 = sh_row_count[el_ix - 1u]; + _360 = sh_row_count[el_ix - 1u]; } else { - _348 = 0u; + _360 = 0u; } - uint seq_ix = row - _348; + uint seq_ix = row - _360; uint tile_el_ix = ((tiles_alloc.offset >> uint(2)) + 1u) + ((seq_ix * 2u) * width); - Alloc param_5 = tiles_alloc; - uint param_6 = tile_el_ix; - uint sum = read_mem(param_5, param_6); + Alloc param_6 = tiles_alloc; + uint param_7 = tile_el_ix; + uint sum = read_mem(param_6, param_7); for (uint x = 1u; x < width; x++) { tile_el_ix += 2u; - Alloc param_7 = tiles_alloc; - uint param_8 = tile_el_ix; - sum += read_mem(param_7, param_8); - Alloc param_9 = tiles_alloc; - uint param_10 = tile_el_ix; - uint param_11 = sum; - write_mem(param_9, param_10, param_11); + Alloc param_8 = tiles_alloc; + uint param_9 = tile_el_ix; + sum += read_mem(param_8, param_9); + Alloc param_10 = tiles_alloc; + uint param_11 = tile_el_ix; + uint param_12 = sum; + write_mem(param_10, param_11, param_12); } } } diff --git a/piet-gpu/shader/gen/backdrop.msl b/piet-gpu/shader/gen/backdrop.msl index 1c0a0bb..3726dff 100644 --- a/piet-gpu/shader/gen/backdrop.msl +++ b/piet-gpu/shader/gen/backdrop.msl @@ -1,7 +1,9 @@ #pragma clang diagnostic ignored "-Wmissing-prototypes" +#pragma clang diagnostic ignored "-Wunused-variable" #include #include +#include using namespace metal; @@ -30,6 +32,7 @@ struct Memory { uint mem_offset; uint mem_error; + uint blend_offset; uint memory[1]; }; @@ -40,6 +43,7 @@ struct Alloc_1 struct Config { + uint mem_size; uint n_elements; uint n_pathseg; uint width_in_tiles; @@ -76,6 +80,13 @@ struct ConfigBuf constant uint3 gl_WorkGroupSize [[maybe_unused]] = uint3(256u, 1u, 1u); +static inline __attribute__((always_inline)) +bool check_deps(thread const uint& dep_stage, device Memory& v_59) +{ + uint _65 = atomic_fetch_or_explicit((device atomic_uint*)&v_59.mem_error, 0u, memory_order_relaxed); + return (_65 & dep_stage) == 0u; +} + static inline __attribute__((always_inline)) bool touch_mem(thread const Alloc& alloc, thread const uint& offset) { @@ -83,7 +94,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_67) +uint read_mem(thread const Alloc& alloc, thread const uint& offset, device Memory& v_59) { Alloc param = alloc; uint param_1 = offset; @@ -91,23 +102,23 @@ uint read_mem(thread const Alloc& alloc, thread const uint& offset, device Memor { return 0u; } - uint v = v_67.memory[offset]; + uint v = v_59.memory[offset]; return v; } static inline __attribute__((always_inline)) -Path Path_read(thread const Alloc& a, thread const PathRef& ref, device Memory& v_67) +Path Path_read(thread const Alloc& a, thread const PathRef& ref, device Memory& v_59) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; - uint raw0 = read_mem(param, param_1, v_67); + uint raw0 = read_mem(param, param_1, v_59); Alloc param_2 = a; uint param_3 = ix + 1u; - uint raw1 = read_mem(param_2, param_3, v_67); + uint raw1 = read_mem(param_2, param_3, v_59); Alloc param_4 = a; uint param_5 = ix + 2u; - uint raw2 = read_mem(param_4, param_5, v_67); + uint raw2 = read_mem(param_4, param_5, v_59); Path s; s.bbox = uint4(raw0 & 65535u, raw0 >> uint(16), raw1 & 65535u, raw1 >> uint(16)); s.tiles = TileRef{ raw2 }; @@ -123,7 +134,7 @@ Alloc new_alloc(thread const uint& offset, thread const uint& size, thread const } static inline __attribute__((always_inline)) -void write_mem(thread const Alloc& alloc, thread const uint& offset, thread const uint& val, device Memory& v_67) +void write_mem(thread const Alloc& alloc, thread const uint& offset, thread const uint& val, device Memory& v_59) { Alloc param = alloc; uint param_1 = offset; @@ -131,47 +142,52 @@ void write_mem(thread const Alloc& alloc, thread const uint& offset, thread cons { return; } - v_67.memory[offset] = val; + v_59.memory[offset] = val; } -kernel void main0(device Memory& v_67 [[buffer(0)]], const device ConfigBuf& _166 [[buffer(1)]], uint gl_LocalInvocationIndex [[thread_index_in_threadgroup]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]]) +kernel void main0(device Memory& v_59 [[buffer(0)]], const device ConfigBuf& _181 [[buffer(1)]], uint gl_LocalInvocationIndex [[thread_index_in_threadgroup]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]]) { threadgroup uint sh_row_width[256]; threadgroup Alloc sh_row_alloc[256]; threadgroup uint sh_row_count[256]; + uint param = 7u; + bool _154 = check_deps(param, v_59); + if (!_154) + { + return; + } uint th_ix = gl_LocalInvocationIndex; uint element_ix = gl_GlobalInvocationID.x; uint row_count = 0u; - bool mem_ok = v_67.mem_error == 0u; if (gl_LocalInvocationID.y == 0u) { - if (element_ix < _166.conf.n_elements) + if (element_ix < _181.conf.n_elements) { - PathRef path_ref = PathRef{ _166.conf.tile_alloc.offset + (element_ix * 12u) }; - Alloc param; - param.offset = _166.conf.tile_alloc.offset; - PathRef param_1 = path_ref; - Path path = Path_read(param, param_1, v_67); + PathRef path_ref = PathRef{ _181.conf.tile_alloc.offset + (element_ix * 12u) }; + Alloc param_1; + param_1.offset = _181.conf.tile_alloc.offset; + PathRef param_2 = path_ref; + Path path = Path_read(param_1, param_2, v_59); sh_row_width[th_ix] = path.bbox.z - path.bbox.x; row_count = path.bbox.w - path.bbox.y; - bool _210 = row_count == 1u; - bool _216; - if (_210) + bool _225 = row_count == 1u; + bool _231; + if (_225) { - _216 = path.bbox.y > 0u; + _231 = path.bbox.y > 0u; } else { - _216 = _210; + _231 = _225; } - if (_216) + if (_231) { row_count = 0u; } - uint param_2 = path.tiles.offset; - uint param_3 = ((path.bbox.z - path.bbox.x) * (path.bbox.w - path.bbox.y)) * 8u; - bool param_4 = mem_ok; - Alloc path_alloc = new_alloc(param_2, param_3, param_4); + uint param_3 = path.tiles.offset; + uint param_4 = ((path.bbox.z - path.bbox.x) * (path.bbox.w - path.bbox.y)) * 8u; + bool param_5 = true; + Alloc path_alloc = new_alloc(param_3, param_4, param_5); sh_row_alloc[th_ix] = path_alloc; } sh_row_count[th_ix] = row_count; @@ -179,17 +195,17 @@ kernel void main0(device Memory& v_67 [[buffer(0)]], const device ConfigBuf& _16 for (uint i = 0u; i < 8u; i++) { threadgroup_barrier(mem_flags::mem_threadgroup); - bool _262 = gl_LocalInvocationID.y == 0u; - bool _269; - if (_262) + bool _276 = gl_LocalInvocationID.y == 0u; + bool _283; + if (_276) { - _269 = th_ix >= (1u << i); + _283 = th_ix >= (1u << i); } else { - _269 = _262; + _283 = _276; } - if (_269) + if (_283) { row_count += sh_row_count[th_ix - (1u << i)]; } @@ -201,7 +217,7 @@ kernel void main0(device Memory& v_67 [[buffer(0)]], const device ConfigBuf& _16 } threadgroup_barrier(mem_flags::mem_threadgroup); uint total_rows = sh_row_count[255]; - uint _348; + uint _360; for (uint row = th_ix; row < total_rows; row += 256u) { uint el_ix = 0u; @@ -214,32 +230,32 @@ kernel void main0(device Memory& v_67 [[buffer(0)]], const device ConfigBuf& _16 } } uint width = sh_row_width[el_ix]; - if ((width > 0u) && mem_ok) + if (width > 0u) { Alloc tiles_alloc = sh_row_alloc[el_ix]; if (el_ix > 0u) { - _348 = sh_row_count[el_ix - 1u]; + _360 = sh_row_count[el_ix - 1u]; } else { - _348 = 0u; + _360 = 0u; } - uint seq_ix = row - _348; + uint seq_ix = row - _360; uint tile_el_ix = ((tiles_alloc.offset >> uint(2)) + 1u) + ((seq_ix * 2u) * width); - Alloc param_5 = tiles_alloc; - uint param_6 = tile_el_ix; - uint sum = read_mem(param_5, param_6, v_67); + Alloc param_6 = tiles_alloc; + uint param_7 = tile_el_ix; + uint sum = read_mem(param_6, param_7, v_59); for (uint x = 1u; x < width; x++) { tile_el_ix += 2u; - Alloc param_7 = tiles_alloc; - uint param_8 = tile_el_ix; - sum += read_mem(param_7, param_8, v_67); - Alloc param_9 = tiles_alloc; - uint param_10 = tile_el_ix; - uint param_11 = sum; - write_mem(param_9, param_10, param_11, v_67); + Alloc param_8 = tiles_alloc; + uint param_9 = tile_el_ix; + sum += read_mem(param_8, param_9, v_59); + Alloc param_10 = tiles_alloc; + uint param_11 = tile_el_ix; + uint param_12 = sum; + write_mem(param_10, param_11, param_12, v_59); } } } diff --git a/piet-gpu/shader/gen/backdrop.spv b/piet-gpu/shader/gen/backdrop.spv index 2bd17d8069b3d234ab7866cc0dfca0df47d22062..b8a74ea44c7209d7c79e5e3b2e3f39466abb90a3 100644 GIT binary patch literal 11832 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 U9ItJR;|I|1MD+W9ihV!74`1Evg#Z8m diff --git a/piet-gpu/shader/gen/backdrop_lg.dxil b/piet-gpu/shader/gen/backdrop_lg.dxil index e24a6d3e8724ffe415eb3595008849f7310679c0..06bacaf62880e910ad420a3b68c87b4b072df196 100644 GIT binary patch delta 2457 zcmb_ce^3+Y8UA*&SvJW62}y7vaBdO^AgBu}a3{UlO#%X<7c?MxPTlb9L@^?IQ@v|1 zn-D^vsL(}=QfC69rJm=|(?g|pjsUf&cp`OfsK+_rMd#|+Dd!(Oy>rg)a_~nx{j1ac zWA}TX_j#Z1-QDN?LdL0tSZkTtQn-2gCe*jVX!7yw_l zzkb;?g#y3=DHsrP*0O>kAUu@hgA%Bz zV6#=mf9gR_;Q=zLIAQm#D0*T-mdA!laQHh(-#^Q0fu{0v2 z@IJ)A-($d&RX|fMP!9?Gdj61nZ8mp;1h-KKnTa8cqt@vG**c#@Z^FLFdzgwQReL~= zF3P;s?_e?3GEt;_jE6vPez_REX=l%ox)yR;c{c&EFfUGba zs5-c#cCVvSjerXC7T>pP)_rT*a=mB8?ZZx|M2nVFXr&Epi1`f^+v|=!59uzsb=ROc ze4mR(OQxot-rqhsc60jcvk0Tj$XW7-jH_2KWnE5z?t1Y%e_GLc`$Cbk&~{Hhvj2od zVNB(Bzh_LX=!zn%#^$z%Za#kSBy|1em;)z!v`Nf8=~X3l{l3uT}}jasG|4ZR-HY zXEx_+7XI*OhXWN~maH+AEv@SfeD#atqM3Kfe>C?=_}|TK6YxcIxAT7uOHLwxFP#}0n zbf?OF#jI3-#)W%+~aQn*J-KL2uYHd|`M~jr+U>rmw1OVk% z;zp22_>%>hN(}_Clo0@W$5rI$^s4PYcz@yzHPNfm5V`B52Z*BwCRVLeYDORe`11#A zuDq1JkKNcIt4TC1y}HLPq`{ehFn4{+Zh~wv8k$(6tm|Bz+d;k1WvcE|R&T-{d$Cd_ z2a_B5v;HWPt1+wAaLM7v3hwvykOmDHy{+PgHA5s!iS=qt{ZP{ZwkeZ;7jBp0IUzmZ z6%u;Q|1_06E!V^svPgiq*`t)Vao1F!B@c|HDxXw?on26XMfrVli+yn%O&E8PA#i!c zejPeWny{{1_CH5)aF<89K^OgSD^|{u7@UdRMTgq~>#^Yp_lGB^P1tK|7!Z)bN*+_Z z4ttU=S`>f$zdEzbhThheCRP-n^4m9PoN|WclN4wDu>y2ZU?v7Wl7^cHX zLt&bC=ohHn{35c$MMH88OGC$)6jVbZ>4_9f&)C+H2rcOg{`fpENCP7(10I(A#GTvA z#I^?g49t;4zOzoXtKWrIQspclG4y&|(Qc~TCN9U~ij1g2D481zS~+*D-%VU%q$eY? zki7uCh`Y6|1OYIQyFIKV4$ngNiJ)24N(iT`hbalG=B@=}T207Moh7O*m^MNqMidj& zY_m*k8XG`Q%OG1(Y`zS#Pt>@iwL*LI*%v`wJ`^X^(JJR6*64||2j{W)-HTYeIi7XL zi@f+ffyR5#@o&&=e~u5xtXL^^4_;O`f?7$O3(v)TI!_5`nDtd?hXXM4TirIdzzBI# z{lR`nwOT^0r*XRrjLxWs<>*g2X$Fx=!VXX^YjMlzG}zObNTJKP0+kR3HjVcX=@d{R zlH4VEjOJXlN9W9MVDWP}e5xwDE$}((*Ww{g0ZE7YfO{)k8Gw}$Hx^6cN*Qf+OjK2P zDHV{c91^$3gzW>J4;3zoaAF%FygDY@xIjM>x4m17MRMuWbQlyfonCtKSj+rQ zVtEg=&Z2sv;cvc8WK+PisZ3D|A*saU**I7(RB%WI^`(tqr04ph=V0-5Eo%`CsJIf8 zU1tZoDUW>Av0NFZJkLIFI)o*I>#jP9wl#Rb;y|>Vq=Sy=_jD&b(+2=C626T>{}SG) zvIin<@X8^%@7VJu4rcKzj#)^skv4OIkmyWqo=I6XnLEXo;4ayVAV*XG&{)nmhU_ zg15{zf5^4P!i4kS2WH`u8I~n8rVH>1P9;GAL-mdInCA5T&3C<^GqFwhcb4)Vw|u7E zzcT>NiNzjCl>V0aHwY)(q+zt764~GJ6DrNW0Da65 AO#lD@ delta 2147 zcmcIkeNYtV9e(%Y*1f$w*gH70aECcQE2!e)Rt0dJu2=f3EfE~0r-VvfnJZP{pwpaprF`!@30certh|NX9TXt{@^Vkb;l=C#V1VFyE8%a#V_m=%R>&A_S04TDW9eaB`0xp!y zS5O80kyCSX=#nB8qZ#-YZ`;8~C?rY;(Ih|hKrcy#o8Js=9(?s1Z}Q;qpdFZ_$C*u2 z@8wSEVa8;V46W9ZtijrWdj;DH3ptQ(KG4$E8iUG7jy>IfpZVMRvH}idr?u6;R@2&c z=tzC`XTMv#f3Lvhv17F?Rxe=tLoydXs>F|R)+@>iR>ybs&s~~J?Z0@dzr|lpRVGGS z$FrotmyWd#nyK%7u=2|1;oG0jE{~w43Ax3mHoeDO&Yc=5yqr6k0qyK2KPtV{{KdQ9 zZ@JjqQqEK*MOxpv*^y;9(t2#zFsw-onuQ;#8ncV{m%o(nXj2(MYo1bt#@~OT@M`YV zREA<*-N_y5j^<6A)op{IJn2(xJCl$f`E>IePlFwu)Ich~n)9Wc^Op#@^~j$_c;l(R z7XO5`=uG2Mj7dehCEvR0QWv+&6{{VN8l_>cQkXIKAny^@oUqNXpjk4Tcx=(1!T)K| zSQTHhXh1UI>CzTx=Xcpux(4y}|7UwvKx7g?q#x_gz-JATmG};q>NJ;bfiy#uFl**a!`TUrCW+csD>iLc%~>k^mob|HD=w+XV8a*lIdD#| zUVv8&n_&2k{OH^0 z*+RJuA&O-4tY3bF5WEZ!V$?P($07t3aO?X(@afO+PW7G1qgPuoPn816m>vWK@Gew( zMv3cGdN^3L(`++uY7Amt#_Jb=9mmRS6-|uy-%?&fUABs33|Fg}>ku7#fWn6L5VJ^K zfoQUjJ_N7{5;FDCc7O+z{B?C=h>Pn>Lqk5q98|J981zZ)AC$Q422rc!U!q-lsPgUs zU6VSkRpAGI&gyEns&%Ys{~GuY$X3bOG%Vrp8rB=O2~ff+)+~2@44quUs(+Ip>z(*+ zx=x9m^dLzT7V1tyBStP$RD6*E!o#=A3&vluXcjpcB0Nkpi_U>tW)iW0#QV;%aL{mx z!Tb@-X(vP3P!11$g|g%XI>YLiR9Nj+_PVKL3{%%HFFMji$DG3#F*Z_t+|N0Ag1lim z5l@bXsi;Yc2W2|^mf40_M8P%F(+;USoc`+|G0NN&Q(hel^HEnp0%^5cDl!iFC(buwB$~ z8Q$eKG(zg4R`@7LCy<49g{~-!E#sBUi@K{IV8M>LkBczVZ9OB9BUU1Ll(qdH_5p=J zUYssrAv$8LWUvKem#NYh#rwn0goqB;;^TqpCj(+M4?hRaKqOTht@Km@U%j7RGe|HYB#A=o&5qXbU_>4NwPZi?oeu24kymE26&xU<1Ea~Q^YB@bdw%m_3$?QZ zM2x|gdz5S>Uzd7qx{8WnyrO2(1^2vjEBbuS+Z32Uf6MB8PBNc|icOHQ61;pqlQ$MX zmc{9+;J^6QD^3@>MdMp+s{iLTk*a;8=ypmli8{BaE5EI*r|1@Zt9nAgA>pKuxyP+n z``&hS!gS{8)KSKctyizsJ}d{H7H-aC?R0b8Lp#;+Oi4QG9jh> uint(16), raw1 & 65535u, raw1 >> uint(16)); - TileRef _134 = { raw2 }; - s.tiles = _134; + TileRef _146 = { raw2 }; + s.tiles = _146; return s; } @@ -120,47 +128,52 @@ void write_mem(Alloc alloc, uint offset, uint val) { return; } - _67.Store(offset * 4 + 8, val); + _59.Store(offset * 4 + 12, val); } void comp_main() { + uint param = 7u; + bool _154 = check_deps(param); + if (!_154) + { + return; + } uint th_ix = gl_LocalInvocationIndex; uint element_ix = gl_GlobalInvocationID.x; uint row_count = 0u; - bool mem_ok = _67.Load(4) == 0u; if (gl_LocalInvocationID.y == 0u) { - if (element_ix < _166.Load(0)) + if (element_ix < _181.Load(4)) { - PathRef _180 = { _166.Load(16) + (element_ix * 12u) }; - PathRef path_ref = _180; - Alloc _185; - _185.offset = _166.Load(16); - Alloc param; - param.offset = _185.offset; - PathRef param_1 = path_ref; - Path path = Path_read(param, param_1); + PathRef _195 = { _181.Load(20) + (element_ix * 12u) }; + PathRef path_ref = _195; + Alloc _200; + _200.offset = _181.Load(20); + Alloc param_1; + param_1.offset = _200.offset; + PathRef param_2 = path_ref; + Path path = Path_read(param_1, param_2); sh_row_width[th_ix] = path.bbox.z - path.bbox.x; row_count = path.bbox.w - path.bbox.y; - bool _210 = row_count == 1u; - bool _216; - if (_210) + bool _225 = row_count == 1u; + bool _231; + if (_225) { - _216 = path.bbox.y > 0u; + _231 = path.bbox.y > 0u; } else { - _216 = _210; + _231 = _225; } - if (_216) + if (_231) { row_count = 0u; } - uint param_2 = path.tiles.offset; - uint param_3 = ((path.bbox.z - path.bbox.x) * (path.bbox.w - path.bbox.y)) * 8u; - bool param_4 = mem_ok; - Alloc path_alloc = new_alloc(param_2, param_3, param_4); + uint param_3 = path.tiles.offset; + uint param_4 = ((path.bbox.z - path.bbox.x) * (path.bbox.w - path.bbox.y)) * 8u; + bool param_5 = true; + Alloc path_alloc = new_alloc(param_3, param_4, param_5); sh_row_alloc[th_ix] = path_alloc; } sh_row_count[th_ix] = row_count; @@ -168,17 +181,17 @@ void comp_main() for (uint i = 0u; i < 8u; i++) { GroupMemoryBarrierWithGroupSync(); - bool _262 = gl_LocalInvocationID.y == 0u; - bool _269; - if (_262) + bool _276 = gl_LocalInvocationID.y == 0u; + bool _283; + if (_276) { - _269 = th_ix >= (1u << i); + _283 = th_ix >= (1u << i); } else { - _269 = _262; + _283 = _276; } - if (_269) + if (_283) { row_count += sh_row_count[th_ix - (1u << i)]; } @@ -190,7 +203,7 @@ void comp_main() } GroupMemoryBarrierWithGroupSync(); uint total_rows = sh_row_count[255]; - uint _348; + uint _360; for (uint row = th_ix; row < total_rows; row += 1024u) { uint el_ix = 0u; @@ -203,32 +216,32 @@ void comp_main() } } uint width = sh_row_width[el_ix]; - if ((width > 0u) && mem_ok) + if (width > 0u) { Alloc tiles_alloc = sh_row_alloc[el_ix]; if (el_ix > 0u) { - _348 = sh_row_count[el_ix - 1u]; + _360 = sh_row_count[el_ix - 1u]; } else { - _348 = 0u; + _360 = 0u; } - uint seq_ix = row - _348; + uint seq_ix = row - _360; uint tile_el_ix = ((tiles_alloc.offset >> uint(2)) + 1u) + ((seq_ix * 2u) * width); - Alloc param_5 = tiles_alloc; - uint param_6 = tile_el_ix; - uint sum = read_mem(param_5, param_6); + Alloc param_6 = tiles_alloc; + uint param_7 = tile_el_ix; + uint sum = read_mem(param_6, param_7); for (uint x = 1u; x < width; x++) { tile_el_ix += 2u; - Alloc param_7 = tiles_alloc; - uint param_8 = tile_el_ix; - sum += read_mem(param_7, param_8); - Alloc param_9 = tiles_alloc; - uint param_10 = tile_el_ix; - uint param_11 = sum; - write_mem(param_9, param_10, param_11); + Alloc param_8 = tiles_alloc; + uint param_9 = tile_el_ix; + sum += read_mem(param_8, param_9); + Alloc param_10 = tiles_alloc; + uint param_11 = tile_el_ix; + uint param_12 = sum; + write_mem(param_10, param_11, param_12); } } } diff --git a/piet-gpu/shader/gen/backdrop_lg.msl b/piet-gpu/shader/gen/backdrop_lg.msl index de43ebe..68f0905 100644 --- a/piet-gpu/shader/gen/backdrop_lg.msl +++ b/piet-gpu/shader/gen/backdrop_lg.msl @@ -1,7 +1,9 @@ #pragma clang diagnostic ignored "-Wmissing-prototypes" +#pragma clang diagnostic ignored "-Wunused-variable" #include #include +#include using namespace metal; @@ -30,6 +32,7 @@ struct Memory { uint mem_offset; uint mem_error; + uint blend_offset; uint memory[1]; }; @@ -40,6 +43,7 @@ struct Alloc_1 struct Config { + uint mem_size; uint n_elements; uint n_pathseg; uint width_in_tiles; @@ -76,6 +80,13 @@ struct ConfigBuf constant uint3 gl_WorkGroupSize [[maybe_unused]] = uint3(256u, 4u, 1u); +static inline __attribute__((always_inline)) +bool check_deps(thread const uint& dep_stage, device Memory& v_59) +{ + uint _65 = atomic_fetch_or_explicit((device atomic_uint*)&v_59.mem_error, 0u, memory_order_relaxed); + return (_65 & dep_stage) == 0u; +} + static inline __attribute__((always_inline)) bool touch_mem(thread const Alloc& alloc, thread const uint& offset) { @@ -83,7 +94,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_67) +uint read_mem(thread const Alloc& alloc, thread const uint& offset, device Memory& v_59) { Alloc param = alloc; uint param_1 = offset; @@ -91,23 +102,23 @@ uint read_mem(thread const Alloc& alloc, thread const uint& offset, device Memor { return 0u; } - uint v = v_67.memory[offset]; + uint v = v_59.memory[offset]; return v; } static inline __attribute__((always_inline)) -Path Path_read(thread const Alloc& a, thread const PathRef& ref, device Memory& v_67) +Path Path_read(thread const Alloc& a, thread const PathRef& ref, device Memory& v_59) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; - uint raw0 = read_mem(param, param_1, v_67); + uint raw0 = read_mem(param, param_1, v_59); Alloc param_2 = a; uint param_3 = ix + 1u; - uint raw1 = read_mem(param_2, param_3, v_67); + uint raw1 = read_mem(param_2, param_3, v_59); Alloc param_4 = a; uint param_5 = ix + 2u; - uint raw2 = read_mem(param_4, param_5, v_67); + uint raw2 = read_mem(param_4, param_5, v_59); Path s; s.bbox = uint4(raw0 & 65535u, raw0 >> uint(16), raw1 & 65535u, raw1 >> uint(16)); s.tiles = TileRef{ raw2 }; @@ -123,7 +134,7 @@ Alloc new_alloc(thread const uint& offset, thread const uint& size, thread const } static inline __attribute__((always_inline)) -void write_mem(thread const Alloc& alloc, thread const uint& offset, thread const uint& val, device Memory& v_67) +void write_mem(thread const Alloc& alloc, thread const uint& offset, thread const uint& val, device Memory& v_59) { Alloc param = alloc; uint param_1 = offset; @@ -131,47 +142,52 @@ void write_mem(thread const Alloc& alloc, thread const uint& offset, thread cons { return; } - v_67.memory[offset] = val; + v_59.memory[offset] = val; } -kernel void main0(device Memory& v_67 [[buffer(0)]], const device ConfigBuf& _166 [[buffer(1)]], uint gl_LocalInvocationIndex [[thread_index_in_threadgroup]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]]) +kernel void main0(device Memory& v_59 [[buffer(0)]], const device ConfigBuf& _181 [[buffer(1)]], uint gl_LocalInvocationIndex [[thread_index_in_threadgroup]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]]) { threadgroup uint sh_row_width[256]; threadgroup Alloc sh_row_alloc[256]; threadgroup uint sh_row_count[256]; + uint param = 7u; + bool _154 = check_deps(param, v_59); + if (!_154) + { + return; + } uint th_ix = gl_LocalInvocationIndex; uint element_ix = gl_GlobalInvocationID.x; uint row_count = 0u; - bool mem_ok = v_67.mem_error == 0u; if (gl_LocalInvocationID.y == 0u) { - if (element_ix < _166.conf.n_elements) + if (element_ix < _181.conf.n_elements) { - PathRef path_ref = PathRef{ _166.conf.tile_alloc.offset + (element_ix * 12u) }; - Alloc param; - param.offset = _166.conf.tile_alloc.offset; - PathRef param_1 = path_ref; - Path path = Path_read(param, param_1, v_67); + PathRef path_ref = PathRef{ _181.conf.tile_alloc.offset + (element_ix * 12u) }; + Alloc param_1; + param_1.offset = _181.conf.tile_alloc.offset; + PathRef param_2 = path_ref; + Path path = Path_read(param_1, param_2, v_59); sh_row_width[th_ix] = path.bbox.z - path.bbox.x; row_count = path.bbox.w - path.bbox.y; - bool _210 = row_count == 1u; - bool _216; - if (_210) + bool _225 = row_count == 1u; + bool _231; + if (_225) { - _216 = path.bbox.y > 0u; + _231 = path.bbox.y > 0u; } else { - _216 = _210; + _231 = _225; } - if (_216) + if (_231) { row_count = 0u; } - uint param_2 = path.tiles.offset; - uint param_3 = ((path.bbox.z - path.bbox.x) * (path.bbox.w - path.bbox.y)) * 8u; - bool param_4 = mem_ok; - Alloc path_alloc = new_alloc(param_2, param_3, param_4); + uint param_3 = path.tiles.offset; + uint param_4 = ((path.bbox.z - path.bbox.x) * (path.bbox.w - path.bbox.y)) * 8u; + bool param_5 = true; + Alloc path_alloc = new_alloc(param_3, param_4, param_5); sh_row_alloc[th_ix] = path_alloc; } sh_row_count[th_ix] = row_count; @@ -179,17 +195,17 @@ kernel void main0(device Memory& v_67 [[buffer(0)]], const device ConfigBuf& _16 for (uint i = 0u; i < 8u; i++) { threadgroup_barrier(mem_flags::mem_threadgroup); - bool _262 = gl_LocalInvocationID.y == 0u; - bool _269; - if (_262) + bool _276 = gl_LocalInvocationID.y == 0u; + bool _283; + if (_276) { - _269 = th_ix >= (1u << i); + _283 = th_ix >= (1u << i); } else { - _269 = _262; + _283 = _276; } - if (_269) + if (_283) { row_count += sh_row_count[th_ix - (1u << i)]; } @@ -201,7 +217,7 @@ kernel void main0(device Memory& v_67 [[buffer(0)]], const device ConfigBuf& _16 } threadgroup_barrier(mem_flags::mem_threadgroup); uint total_rows = sh_row_count[255]; - uint _348; + uint _360; for (uint row = th_ix; row < total_rows; row += 1024u) { uint el_ix = 0u; @@ -214,32 +230,32 @@ kernel void main0(device Memory& v_67 [[buffer(0)]], const device ConfigBuf& _16 } } uint width = sh_row_width[el_ix]; - if ((width > 0u) && mem_ok) + if (width > 0u) { Alloc tiles_alloc = sh_row_alloc[el_ix]; if (el_ix > 0u) { - _348 = sh_row_count[el_ix - 1u]; + _360 = sh_row_count[el_ix - 1u]; } else { - _348 = 0u; + _360 = 0u; } - uint seq_ix = row - _348; + uint seq_ix = row - _360; uint tile_el_ix = ((tiles_alloc.offset >> uint(2)) + 1u) + ((seq_ix * 2u) * width); - Alloc param_5 = tiles_alloc; - uint param_6 = tile_el_ix; - uint sum = read_mem(param_5, param_6, v_67); + Alloc param_6 = tiles_alloc; + uint param_7 = tile_el_ix; + uint sum = read_mem(param_6, param_7, v_59); for (uint x = 1u; x < width; x++) { tile_el_ix += 2u; - Alloc param_7 = tiles_alloc; - uint param_8 = tile_el_ix; - sum += read_mem(param_7, param_8, v_67); - Alloc param_9 = tiles_alloc; - uint param_10 = tile_el_ix; - uint param_11 = sum; - write_mem(param_9, param_10, param_11, v_67); + Alloc param_8 = tiles_alloc; + uint param_9 = tile_el_ix; + sum += read_mem(param_8, param_9, v_59); + Alloc param_10 = tiles_alloc; + uint param_11 = tile_el_ix; + uint param_12 = sum; + write_mem(param_10, param_11, param_12, v_59); } } } diff --git a/piet-gpu/shader/gen/backdrop_lg.spv b/piet-gpu/shader/gen/backdrop_lg.spv index ff2b1d72fea710d523ddc3d06141513d45abef9c..2819ec57ec091a6da676686f566120489b033a4e 100644 GIT binary patch literal 11864 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 literal 11540 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 diff --git a/piet-gpu/shader/gen/bbox_clear.dxil b/piet-gpu/shader/gen/bbox_clear.dxil index 6655b7f9ca1149d804b413fba4d5c3313c10bf74..82cfb036bbf224f135b70444348c78c5fd18307a 100644 GIT binary patch delta 243 zcmca1aYI7HCBn)1lUPgqs*{)VckQ^$E1$lAd!tASo50!Il|Pml``Eqe$yjA{_ig>= z4mKgy`h-*e|1T(E<}z8ZL2ID_*OGt}Qx0%2fPgX^Cqq-hf`Zt+@vCa@D37y$KIROTKGQqc_d80@Qn}FV~u*)JJ4|BelpDw3%&Y@s) z2b&OU{h$B*Ugir7n7LLZXf0IWTI|5p>ciQ?00hcxoD59~3rhMXq+aQ8WNJ{5(730Z z5p9~3z@Wgv#v);IyMqxVY9g;g z99SoY2^{QjWCm)mN#9_|*j^~}e2Tz9d#F&x0aM56rLo_yz!ha)uxu=6oA=z&)x{v` Z0?5FAsS5uO3lDy;y{OaJ0CFJ^008zxQoR5G diff --git a/piet-gpu/shader/gen/bbox_clear.hlsl b/piet-gpu/shader/gen/bbox_clear.hlsl index 8a884d3..5d29894 100644 --- a/piet-gpu/shader/gen/bbox_clear.hlsl +++ b/piet-gpu/shader/gen/bbox_clear.hlsl @@ -5,6 +5,7 @@ struct Alloc struct Config { + uint mem_size; uint n_elements; uint n_pathseg; uint width_in_tiles; @@ -48,13 +49,13 @@ struct SPIRV_Cross_Input void comp_main() { uint ix = gl_GlobalInvocationID.x; - if (ix < _21.Load(76)) + if (ix < _21.Load(80)) { - uint out_ix = (_21.Load(40) >> uint(2)) + (6u * ix); - _45.Store(out_ix * 4 + 8, 65535u); - _45.Store((out_ix + 1u) * 4 + 8, 65535u); - _45.Store((out_ix + 2u) * 4 + 8, 0u); - _45.Store((out_ix + 3u) * 4 + 8, 0u); + uint out_ix = (_21.Load(44) >> uint(2)) + (6u * ix); + _45.Store(out_ix * 4 + 12, 65535u); + _45.Store((out_ix + 1u) * 4 + 12, 65535u); + _45.Store((out_ix + 2u) * 4 + 12, 0u); + _45.Store((out_ix + 3u) * 4 + 12, 0u); } } diff --git a/piet-gpu/shader/gen/bbox_clear.msl b/piet-gpu/shader/gen/bbox_clear.msl index c278c68..289fc9a 100644 --- a/piet-gpu/shader/gen/bbox_clear.msl +++ b/piet-gpu/shader/gen/bbox_clear.msl @@ -10,6 +10,7 @@ struct Alloc struct Config { + uint mem_size; uint n_elements; uint n_pathseg; uint width_in_tiles; @@ -48,6 +49,7 @@ struct Memory { uint mem_offset; uint mem_error; + uint blend_offset; uint memory[1]; }; diff --git a/piet-gpu/shader/gen/bbox_clear.spv b/piet-gpu/shader/gen/bbox_clear.spv index 58a270e31e9ca8418dc37845943753f44fd4208d..f1ef3719d108fff7d35416261738ff4ef3f9c63f 100644 GIT binary patch delta 862 zcmY+BzjD(+5XSFxvLqXuFt!z=Xo$_Epa}nrArL?bJOo7wMkq!Jo{?pPMFEY|W(JyU zMZqwX6cm}z@&FXf@B%yl1|UdbMn|5ZO~aRUdSrCH1}cZiXj)bloU`;6HB0o# z=*n~S&G3(uLqCkRY?4&I+d^9!W-p?2hJ#h|;oH<#E!WK*M)Jr7Y?*eHFFW*7buXNU z&j-(<{cy6kH;c2f&ZA@0t&=cp2Y?E8Pgi8skecQ^J7Co;H=F8~2 zy69gQCUz9!I&^v}P*to4SW8H+ZzJYu_4*!S-e0e`5Ocw0(D+ZJu*?CF*utJ0fI_`-S_Gj{N!9hLtE+qVr`|SdM&ERa6jjKh=bvhAH8F^i zEa@kMd`RTr8zaoQuY#rq+eugQ^(Y-gd734K!z~@>uFWx106JLaQ3ovGg?l2 zHq60Ir1NF|0^b$>jy+fTw+{K2_PAxnJ2J%uV7~vn~QflPaC_8uQ>SU>|QL zwc3Da5^HlFfZH6IOO9w4a~6sA{t0>n14NR0*`UYZHb~|YBw7`)g`R-709)u8xM=bo SHfIUk=Ez)fmWY2;um1sgm25@; diff --git a/piet-gpu/shader/gen/binning.dxil b/piet-gpu/shader/gen/binning.dxil index 3050aa83bdb31b0655c4e6a2c8d80987840b6532..5c89a15f37e2f6add9cdd72a00bec9f8e8e4fc8b 100644 GIT binary patch literal 5980 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 literal 6336 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 diff --git a/piet-gpu/shader/gen/binning.hlsl b/piet-gpu/shader/gen/binning.hlsl index 986f42b..7096371 100644 --- a/piet-gpu/shader/gen/binning.hlsl +++ b/piet-gpu/shader/gen/binning.hlsl @@ -3,22 +3,6 @@ struct Alloc uint offset; }; -struct MallocResult -{ - Alloc alloc; - bool failed; -}; - -struct BinInstanceRef -{ - uint offset; -}; - -struct BinInstance -{ - uint element_ix; -}; - struct DrawMonoid { uint path_ix; @@ -29,6 +13,7 @@ struct DrawMonoid struct Config { + uint mem_size; uint n_elements; uint n_pathseg; uint width_in_tiles; @@ -60,8 +45,8 @@ struct Config static const uint3 gl_WorkGroupSize = uint3(256u, 1u, 1u); -RWByteAddressBuffer _81 : register(u0, space0); -ByteAddressBuffer _156 : register(t1, space0); +RWByteAddressBuffer _57 : register(u0, space0); +ByteAddressBuffer _101 : register(t1, space0); static uint3 gl_WorkGroupID; static uint3 gl_LocalInvocationID; @@ -72,39 +57,38 @@ struct SPIRV_Cross_Input }; groupshared uint bitmaps[8][256]; -groupshared bool sh_alloc_failed; groupshared uint count[8][256]; -groupshared Alloc sh_chunk_alloc[256]; +groupshared uint sh_chunk_offset[256]; DrawMonoid load_draw_monoid(uint element_ix) { - uint base = (_156.Load(44) >> uint(2)) + (4u * element_ix); - uint path_ix = _81.Load(base * 4 + 8); - uint clip_ix = _81.Load((base + 1u) * 4 + 8); - uint scene_offset = _81.Load((base + 2u) * 4 + 8); - uint info_offset = _81.Load((base + 3u) * 4 + 8); - DrawMonoid _190 = { path_ix, clip_ix, scene_offset, info_offset }; - return _190; + uint base = (_101.Load(48) >> uint(2)) + (4u * element_ix); + uint path_ix = _57.Load(base * 4 + 12); + uint clip_ix = _57.Load((base + 1u) * 4 + 12); + uint scene_offset = _57.Load((base + 2u) * 4 + 12); + uint info_offset = _57.Load((base + 3u) * 4 + 12); + DrawMonoid _136 = { path_ix, clip_ix, scene_offset, info_offset }; + return _136; } float4 load_clip_bbox(uint clip_ix) { - uint base = (_156.Load(60) >> uint(2)) + (4u * clip_ix); - float x0 = asfloat(_81.Load(base * 4 + 8)); - float y0 = asfloat(_81.Load((base + 1u) * 4 + 8)); - float x1 = asfloat(_81.Load((base + 2u) * 4 + 8)); - float y1 = asfloat(_81.Load((base + 3u) * 4 + 8)); + uint base = (_101.Load(64) >> uint(2)) + (4u * clip_ix); + float x0 = asfloat(_57.Load(base * 4 + 12)); + float y0 = asfloat(_57.Load((base + 1u) * 4 + 12)); + float x1 = asfloat(_57.Load((base + 2u) * 4 + 12)); + float y1 = asfloat(_57.Load((base + 3u) * 4 + 12)); float4 bbox = float4(x0, y0, x1, y1); return bbox; } float4 load_path_bbox(uint path_ix) { - uint base = (_156.Load(40) >> uint(2)) + (6u * path_ix); - float bbox_l = float(_81.Load(base * 4 + 8)) - 32768.0f; - float bbox_t = float(_81.Load((base + 1u) * 4 + 8)) - 32768.0f; - float bbox_r = float(_81.Load((base + 2u) * 4 + 8)) - 32768.0f; - float bbox_b = float(_81.Load((base + 3u) * 4 + 8)) - 32768.0f; + uint base = (_101.Load(44) >> uint(2)) + (6u * path_ix); + float bbox_l = float(_57.Load(base * 4 + 12)) - 32768.0f; + float bbox_t = float(_57.Load((base + 1u) * 4 + 12)) - 32768.0f; + float bbox_r = float(_57.Load((base + 2u) * 4 + 12)) - 32768.0f; + float bbox_b = float(_57.Load((base + 3u) * 4 + 12)) - 32768.0f; float4 bbox = float4(bbox_l, bbox_t, bbox_r, bbox_b); return bbox; } @@ -116,41 +100,25 @@ float4 bbox_intersect(float4 a, float4 b) void store_draw_bbox(uint draw_ix, float4 bbox) { - uint base = (_156.Load(64) >> uint(2)) + (4u * draw_ix); - _81.Store(base * 4 + 8, asuint(bbox.x)); - _81.Store((base + 1u) * 4 + 8, asuint(bbox.y)); - _81.Store((base + 2u) * 4 + 8, asuint(bbox.z)); - _81.Store((base + 3u) * 4 + 8, asuint(bbox.w)); + uint base = (_101.Load(68) >> uint(2)) + (4u * draw_ix); + _57.Store(base * 4 + 12, asuint(bbox.x)); + _57.Store((base + 1u) * 4 + 12, asuint(bbox.y)); + _57.Store((base + 2u) * 4 + 12, asuint(bbox.z)); + _57.Store((base + 3u) * 4 + 12, asuint(bbox.w)); } -Alloc new_alloc(uint offset, uint size, bool mem_ok) +uint malloc_stage(uint size, uint mem_size, uint stage) { - Alloc a; - a.offset = offset; - return a; -} - -MallocResult malloc(uint size) -{ - uint _87; - _81.InterlockedAdd(0, size, _87); - uint offset = _87; - uint _94; - _81.GetDimensions(_94); - _94 = (_94 - 8) / 4; - MallocResult r; - r.failed = (offset + size) > uint(int(_94) * 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 _65; + _57.InterlockedAdd(0, size, _65); + uint offset = _65; + if ((offset + size) > mem_size) { - uint _116; - _81.InterlockedMax(4, 1u, _116); - return r; + uint _76; + _57.InterlockedOr(4, stage, _76); + offset = 0u; } - return r; + return offset; } bool touch_mem(Alloc alloc, uint offset) @@ -166,16 +134,7 @@ void write_mem(Alloc alloc, uint offset, uint val) { return; } - _81.Store(offset * 4 + 8, val); -} - -void BinInstance_write(Alloc a, BinInstanceRef ref, BinInstance s) -{ - uint ix = ref.offset >> uint(2); - Alloc param = a; - uint param_1 = ix + 0u; - uint param_2 = s.element_ix; - write_mem(param, param_1, param_2); + _57.Store(offset * 4 + 12, val); } void comp_main() @@ -185,17 +144,12 @@ void comp_main() { bitmaps[i][gl_LocalInvocationID.x] = 0u; } - if (gl_LocalInvocationID.x == 0u) - { - sh_alloc_failed = false; - } - GroupMemoryBarrierWithGroupSync(); uint element_ix = (my_partition * 256u) + gl_LocalInvocationID.x; int x0 = 0; int y0 = 0; int x1 = 0; int y1 = 0; - if (element_ix < _156.Load(0)) + if (element_ix < _101.Load(4)) { uint param = element_ix; DrawMonoid draw_monoid = load_draw_monoid(param); @@ -212,11 +166,11 @@ void comp_main() float4 param_3 = path_bbox; float4 param_4 = clip_bbox; float4 bbox = bbox_intersect(param_3, param_4); - float4 _417 = bbox; - float4 _419 = bbox; - float2 _421 = max(_417.xy, _419.zw); - bbox.z = _421.x; - bbox.w = _421.y; + float4 _354 = bbox; + float4 _356 = bbox; + float2 _358 = max(_354.xy, _356.zw); + bbox.z = _358.x; + bbox.w = _358.y; uint param_5 = element_ix; float4 param_6 = bbox; store_draw_bbox(param_5, param_6); @@ -225,8 +179,8 @@ void comp_main() x1 = int(ceil(bbox.z * 0.00390625f)); y1 = int(ceil(bbox.w * 0.00390625f)); } - uint width_in_bins = ((_156.Load(8) + 16u) - 1u) / 16u; - uint height_in_bins = ((_156.Load(12) + 16u) - 1u) / 16u; + uint width_in_bins = ((_101.Load(12) + 16u) - 1u) / 16u; + uint height_in_bins = ((_101.Load(16) + 16u) - 1u) / 16u; x0 = clamp(x0, 0, int(width_in_bins)); x1 = clamp(x1, x0, int(width_in_bins)); y0 = clamp(y0, 0, int(height_in_bins)); @@ -241,8 +195,8 @@ void comp_main() uint my_mask = 1u << (gl_LocalInvocationID.x & 31u); while (y < y1) { - uint _523; - InterlockedOr(bitmaps[my_slice][(uint(y) * width_in_bins) + uint(x)], my_mask, _523); + uint _460; + InterlockedOr(bitmaps[my_slice][(uint(y) * width_in_bins) + uint(x)], my_mask, _460); x++; if (x == x1) { @@ -257,51 +211,32 @@ void comp_main() element_count += uint(int(countbits(bitmaps[i_1][gl_LocalInvocationID.x]))); count[i_1][gl_LocalInvocationID.x] = element_count; } - uint param_7 = 0u; - uint param_8 = 0u; - bool param_9 = true; - Alloc chunk_alloc = new_alloc(param_7, param_8, param_9); + uint chunk_offset = 0u; if (element_count != 0u) { - uint param_10 = element_count * 4u; - MallocResult _573 = malloc(param_10); - MallocResult chunk = _573; - chunk_alloc = chunk.alloc; - sh_chunk_alloc[gl_LocalInvocationID.x] = chunk_alloc; - if (chunk.failed) - { - sh_alloc_failed = true; - } + uint param_7 = element_count * 4u; + uint param_8 = _101.Load(0); + uint param_9 = 1u; + uint _510 = malloc_stage(param_7, param_8, param_9); + chunk_offset = _510; + sh_chunk_offset[gl_LocalInvocationID.x] = chunk_offset; } - uint out_ix = (_156.Load(20) >> uint(2)) + (((my_partition * 256u) + gl_LocalInvocationID.x) * 2u); - Alloc _603; - _603.offset = _156.Load(20); - Alloc param_11; - param_11.offset = _603.offset; - uint param_12 = out_ix; - uint param_13 = element_count; - write_mem(param_11, param_12, param_13); - Alloc _615; - _615.offset = _156.Load(20); - Alloc param_14; - param_14.offset = _615.offset; - uint param_15 = out_ix + 1u; - uint param_16 = chunk_alloc.offset; - write_mem(param_14, param_15, param_16); + uint out_ix = (_101.Load(24) >> uint(2)) + (((my_partition * 256u) + gl_LocalInvocationID.x) * 2u); + Alloc _532; + _532.offset = _101.Load(24); + Alloc param_10; + param_10.offset = _532.offset; + uint param_11 = out_ix; + uint param_12 = element_count; + write_mem(param_10, param_11, param_12); + Alloc _544; + _544.offset = _101.Load(24); + Alloc param_13; + param_13.offset = _544.offset; + uint param_14 = out_ix + 1u; + uint param_15 = chunk_offset; + write_mem(param_13, param_14, param_15); GroupMemoryBarrierWithGroupSync(); - bool _630; - if (!sh_alloc_failed) - { - _630 = _81.Load(4) != 0u; - } - else - { - _630 = sh_alloc_failed; - } - if (_630) - { - return; - } x = x0; y = y0; while (y < y1) @@ -315,14 +250,11 @@ void comp_main() { idx += count[my_slice - 1u][bin_ix]; } - Alloc out_alloc = sh_chunk_alloc[bin_ix]; - uint out_offset = out_alloc.offset + (idx * 4u); - BinInstanceRef _692 = { out_offset }; - BinInstance _694 = { element_ix }; - Alloc param_17 = out_alloc; - BinInstanceRef param_18 = _692; - BinInstance param_19 = _694; - BinInstance_write(param_17, param_18, param_19); + uint chunk_offset_1 = sh_chunk_offset[bin_ix]; + if (chunk_offset_1 != 0u) + { + _57.Store(((chunk_offset_1 >> uint(2)) + idx) * 4 + 12, element_ix); + } } x++; if (x == x1) diff --git a/piet-gpu/shader/gen/binning.msl b/piet-gpu/shader/gen/binning.msl index 2ee5168..d3ef95c 100644 --- a/piet-gpu/shader/gen/binning.msl +++ b/piet-gpu/shader/gen/binning.msl @@ -12,22 +12,6 @@ struct Alloc uint offset; }; -struct MallocResult -{ - Alloc alloc; - bool failed; -}; - -struct BinInstanceRef -{ - uint offset; -}; - -struct BinInstance -{ - uint element_ix; -}; - struct DrawMonoid { uint path_ix; @@ -40,6 +24,7 @@ struct Memory { uint mem_offset; uint mem_error; + uint blend_offset; uint memory[1]; }; @@ -50,6 +35,7 @@ struct Alloc_1 struct Config { + uint mem_size; uint n_elements; uint n_pathseg; uint width_in_tiles; @@ -87,36 +73,36 @@ struct ConfigBuf constant uint3 gl_WorkGroupSize [[maybe_unused]] = uint3(256u, 1u, 1u); static inline __attribute__((always_inline)) -DrawMonoid load_draw_monoid(thread const uint& element_ix, device Memory& v_81, constant uint& v_81BufferSize, const device ConfigBuf& v_156) +DrawMonoid load_draw_monoid(thread const uint& element_ix, device Memory& v_57, const device ConfigBuf& v_101) { - uint base = (v_156.conf.drawmonoid_alloc.offset >> uint(2)) + (4u * element_ix); - uint path_ix = v_81.memory[base]; - uint clip_ix = v_81.memory[base + 1u]; - uint scene_offset = v_81.memory[base + 2u]; - uint info_offset = v_81.memory[base + 3u]; + uint base = (v_101.conf.drawmonoid_alloc.offset >> uint(2)) + (4u * element_ix); + uint path_ix = v_57.memory[base]; + uint clip_ix = v_57.memory[base + 1u]; + uint scene_offset = v_57.memory[base + 2u]; + uint info_offset = v_57.memory[base + 3u]; return DrawMonoid{ path_ix, clip_ix, scene_offset, info_offset }; } static inline __attribute__((always_inline)) -float4 load_clip_bbox(thread const uint& clip_ix, device Memory& v_81, constant uint& v_81BufferSize, const device ConfigBuf& v_156) +float4 load_clip_bbox(thread const uint& clip_ix, device Memory& v_57, const device ConfigBuf& v_101) { - uint base = (v_156.conf.clip_bbox_alloc.offset >> uint(2)) + (4u * clip_ix); - float x0 = as_type(v_81.memory[base]); - float y0 = as_type(v_81.memory[base + 1u]); - float x1 = as_type(v_81.memory[base + 2u]); - float y1 = as_type(v_81.memory[base + 3u]); + uint base = (v_101.conf.clip_bbox_alloc.offset >> uint(2)) + (4u * clip_ix); + float x0 = as_type(v_57.memory[base]); + float y0 = as_type(v_57.memory[base + 1u]); + float x1 = as_type(v_57.memory[base + 2u]); + float y1 = as_type(v_57.memory[base + 3u]); float4 bbox = float4(x0, y0, x1, y1); return bbox; } static inline __attribute__((always_inline)) -float4 load_path_bbox(thread const uint& path_ix, device Memory& v_81, constant uint& v_81BufferSize, const device ConfigBuf& v_156) +float4 load_path_bbox(thread const uint& path_ix, device Memory& v_57, const device ConfigBuf& v_101) { - uint base = (v_156.conf.path_bbox_alloc.offset >> uint(2)) + (6u * path_ix); - float bbox_l = float(v_81.memory[base]) - 32768.0; - float bbox_t = float(v_81.memory[base + 1u]) - 32768.0; - float bbox_r = float(v_81.memory[base + 2u]) - 32768.0; - float bbox_b = float(v_81.memory[base + 3u]) - 32768.0; + uint base = (v_101.conf.path_bbox_alloc.offset >> uint(2)) + (6u * path_ix); + float bbox_l = float(v_57.memory[base]) - 32768.0; + float bbox_t = float(v_57.memory[base + 1u]) - 32768.0; + float bbox_r = float(v_57.memory[base + 2u]) - 32768.0; + float bbox_b = float(v_57.memory[base + 3u]) - 32768.0; float4 bbox = float4(bbox_l, bbox_t, bbox_r, bbox_b); return bbox; } @@ -128,40 +114,26 @@ float4 bbox_intersect(thread const float4& a, thread const float4& b) } static inline __attribute__((always_inline)) -void store_draw_bbox(thread const uint& draw_ix, thread const float4& bbox, device Memory& v_81, constant uint& v_81BufferSize, const device ConfigBuf& v_156) +void store_draw_bbox(thread const uint& draw_ix, thread const float4& bbox, device Memory& v_57, const device ConfigBuf& v_101) { - uint base = (v_156.conf.draw_bbox_alloc.offset >> uint(2)) + (4u * draw_ix); - v_81.memory[base] = as_type(bbox.x); - v_81.memory[base + 1u] = as_type(bbox.y); - v_81.memory[base + 2u] = as_type(bbox.z); - v_81.memory[base + 3u] = as_type(bbox.w); + uint base = (v_101.conf.draw_bbox_alloc.offset >> uint(2)) + (4u * draw_ix); + v_57.memory[base] = as_type(bbox.x); + v_57.memory[base + 1u] = as_type(bbox.y); + v_57.memory[base + 2u] = as_type(bbox.z); + v_57.memory[base + 3u] = as_type(bbox.w); } static inline __attribute__((always_inline)) -Alloc new_alloc(thread const uint& offset, thread const uint& size, thread const bool& mem_ok) +uint malloc_stage(thread const uint& size, thread const uint& mem_size, thread const uint& stage, device Memory& v_57) { - Alloc a; - a.offset = offset; - return a; -} - -static inline __attribute__((always_inline)) -MallocResult malloc(thread const uint& size, device Memory& v_81, constant uint& v_81BufferSize) -{ - uint _87 = atomic_fetch_add_explicit((device atomic_uint*)&v_81.mem_offset, size, memory_order_relaxed); - uint offset = _87; - MallocResult r; - r.failed = (offset + size) > uint(int((v_81BufferSize - 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 _65 = atomic_fetch_add_explicit((device atomic_uint*)&v_57.mem_offset, size, memory_order_relaxed); + uint offset = _65; + if ((offset + size) > mem_size) { - uint _116 = atomic_fetch_max_explicit((device atomic_uint*)&v_81.mem_error, 1u, memory_order_relaxed); - return r; + uint _76 = atomic_fetch_or_explicit((device atomic_uint*)&v_57.mem_error, stage, memory_order_relaxed); + offset = 0u; } - return r; + return offset; } static inline __attribute__((always_inline)) @@ -171,7 +143,7 @@ bool touch_mem(thread const Alloc& alloc, thread const uint& offset) } static inline __attribute__((always_inline)) -void write_mem(thread const Alloc& alloc, thread const uint& offset, thread const uint& val, device Memory& v_81, constant uint& v_81BufferSize) +void write_mem(thread const Alloc& alloc, thread const uint& offset, thread const uint& val, device Memory& v_57) { Alloc param = alloc; uint param_1 = offset; @@ -179,73 +151,56 @@ void write_mem(thread const Alloc& alloc, thread const uint& offset, thread cons { return; } - v_81.memory[offset] = val; + v_57.memory[offset] = val; } -static inline __attribute__((always_inline)) -void BinInstance_write(thread const Alloc& a, thread const BinInstanceRef& ref, thread const BinInstance& s, device Memory& v_81, constant uint& v_81BufferSize) -{ - uint ix = ref.offset >> uint(2); - Alloc param = a; - uint param_1 = ix + 0u; - uint param_2 = s.element_ix; - write_mem(param, param_1, param_2, v_81, v_81BufferSize); -} - -kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device Memory& v_81 [[buffer(0)]], const device ConfigBuf& v_156 [[buffer(1)]], uint3 gl_WorkGroupID [[threadgroup_position_in_grid]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]]) +kernel void main0(device Memory& v_57 [[buffer(0)]], const device ConfigBuf& v_101 [[buffer(1)]], uint3 gl_WorkGroupID [[threadgroup_position_in_grid]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]]) { threadgroup uint bitmaps[8][256]; - threadgroup short sh_alloc_failed; threadgroup uint count[8][256]; - threadgroup Alloc sh_chunk_alloc[256]; - constant uint& v_81BufferSize = spvBufferSizeConstants[0]; + threadgroup uint sh_chunk_offset[256]; uint my_partition = gl_WorkGroupID.x; for (uint i = 0u; i < 8u; i++) { bitmaps[i][gl_LocalInvocationID.x] = 0u; } - if (gl_LocalInvocationID.x == 0u) - { - sh_alloc_failed = short(false); - } - threadgroup_barrier(mem_flags::mem_threadgroup); uint element_ix = (my_partition * 256u) + gl_LocalInvocationID.x; int x0 = 0; int y0 = 0; int x1 = 0; int y1 = 0; - if (element_ix < v_156.conf.n_elements) + if (element_ix < v_101.conf.n_elements) { uint param = element_ix; - DrawMonoid draw_monoid = load_draw_monoid(param, v_81, v_81BufferSize, v_156); + DrawMonoid draw_monoid = load_draw_monoid(param, v_57, v_101); uint path_ix = draw_monoid.path_ix; float4 clip_bbox = float4(-1000000000.0, -1000000000.0, 1000000000.0, 1000000000.0); uint clip_ix = draw_monoid.clip_ix; if (clip_ix > 0u) { uint param_1 = clip_ix - 1u; - clip_bbox = load_clip_bbox(param_1, v_81, v_81BufferSize, v_156); + clip_bbox = load_clip_bbox(param_1, v_57, v_101); } uint param_2 = path_ix; - float4 path_bbox = load_path_bbox(param_2, v_81, v_81BufferSize, v_156); + float4 path_bbox = load_path_bbox(param_2, v_57, v_101); float4 param_3 = path_bbox; float4 param_4 = clip_bbox; float4 bbox = bbox_intersect(param_3, param_4); - float4 _417 = bbox; - float4 _419 = bbox; - float2 _421 = fast::max(_417.xy, _419.zw); - bbox.z = _421.x; - bbox.w = _421.y; + float4 _354 = bbox; + float4 _356 = bbox; + float2 _358 = fast::max(_354.xy, _356.zw); + bbox.z = _358.x; + bbox.w = _358.y; uint param_5 = element_ix; float4 param_6 = bbox; - store_draw_bbox(param_5, param_6, v_81, v_81BufferSize, v_156); + store_draw_bbox(param_5, param_6, v_57, v_101); x0 = int(floor(bbox.x * 0.00390625)); y0 = int(floor(bbox.y * 0.00390625)); x1 = int(ceil(bbox.z * 0.00390625)); y1 = int(ceil(bbox.w * 0.00390625)); } - uint width_in_bins = ((v_156.conf.width_in_tiles + 16u) - 1u) / 16u; - uint height_in_bins = ((v_156.conf.height_in_tiles + 16u) - 1u) / 16u; + uint width_in_bins = ((v_101.conf.width_in_tiles + 16u) - 1u) / 16u; + uint height_in_bins = ((v_101.conf.height_in_tiles + 16u) - 1u) / 16u; x0 = clamp(x0, 0, int(width_in_bins)); x1 = clamp(x1, x0, int(width_in_bins)); y0 = clamp(y0, 0, int(height_in_bins)); @@ -260,7 +215,7 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M uint my_mask = 1u << (gl_LocalInvocationID.x & 31u); while (y < y1) { - uint _523 = atomic_fetch_or_explicit((threadgroup atomic_uint*)&bitmaps[my_slice][(uint(y) * width_in_bins) + uint(x)], my_mask, memory_order_relaxed); + uint _460 = atomic_fetch_or_explicit((threadgroup atomic_uint*)&bitmaps[my_slice][(uint(y) * width_in_bins) + uint(x)], my_mask, memory_order_relaxed); x++; if (x == x1) { @@ -275,47 +230,28 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M element_count += uint(int(popcount(bitmaps[i_1][gl_LocalInvocationID.x]))); count[i_1][gl_LocalInvocationID.x] = element_count; } - uint param_7 = 0u; - uint param_8 = 0u; - bool param_9 = true; - Alloc chunk_alloc = new_alloc(param_7, param_8, param_9); + uint chunk_offset = 0u; if (element_count != 0u) { - uint param_10 = element_count * 4u; - MallocResult _573 = malloc(param_10, v_81, v_81BufferSize); - MallocResult chunk = _573; - chunk_alloc = chunk.alloc; - sh_chunk_alloc[gl_LocalInvocationID.x] = chunk_alloc; - if (chunk.failed) - { - sh_alloc_failed = short(true); - } + uint param_7 = element_count * 4u; + uint param_8 = v_101.conf.mem_size; + uint param_9 = 1u; + uint _510 = malloc_stage(param_7, param_8, param_9, v_57); + chunk_offset = _510; + sh_chunk_offset[gl_LocalInvocationID.x] = chunk_offset; } - uint out_ix = (v_156.conf.bin_alloc.offset >> uint(2)) + (((my_partition * 256u) + gl_LocalInvocationID.x) * 2u); - Alloc param_11; - param_11.offset = v_156.conf.bin_alloc.offset; - uint param_12 = out_ix; - uint param_13 = element_count; - write_mem(param_11, param_12, param_13, v_81, v_81BufferSize); - Alloc param_14; - param_14.offset = v_156.conf.bin_alloc.offset; - uint param_15 = out_ix + 1u; - uint param_16 = chunk_alloc.offset; - write_mem(param_14, param_15, param_16, v_81, v_81BufferSize); + uint out_ix = (v_101.conf.bin_alloc.offset >> uint(2)) + (((my_partition * 256u) + gl_LocalInvocationID.x) * 2u); + Alloc param_10; + param_10.offset = v_101.conf.bin_alloc.offset; + uint param_11 = out_ix; + uint param_12 = element_count; + write_mem(param_10, param_11, param_12, v_57); + Alloc param_13; + param_13.offset = v_101.conf.bin_alloc.offset; + uint param_14 = out_ix + 1u; + uint param_15 = chunk_offset; + write_mem(param_13, param_14, param_15, v_57); threadgroup_barrier(mem_flags::mem_threadgroup); - bool _630; - if (!bool(sh_alloc_failed)) - { - _630 = v_81.mem_error != 0u; - } - else - { - _630 = bool(sh_alloc_failed); - } - if (_630) - { - return; - } x = x0; y = y0; while (y < y1) @@ -329,12 +265,11 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M { idx += count[my_slice - 1u][bin_ix]; } - Alloc out_alloc = sh_chunk_alloc[bin_ix]; - uint out_offset = out_alloc.offset + (idx * 4u); - Alloc param_17 = out_alloc; - BinInstanceRef param_18 = BinInstanceRef{ out_offset }; - BinInstance param_19 = BinInstance{ element_ix }; - BinInstance_write(param_17, param_18, param_19, v_81, v_81BufferSize); + uint chunk_offset_1 = sh_chunk_offset[bin_ix]; + if (chunk_offset_1 != 0u) + { + v_57.memory[(chunk_offset_1 >> uint(2)) + idx] = element_ix; + } } x++; if (x == x1) diff --git a/piet-gpu/shader/gen/binning.spv b/piet-gpu/shader/gen/binning.spv index 30eacd6b33c706f9056c8d9762669211821c186c..1a5c2e1edd0acd497212d2f89dc169c0ee7039b1 100644 GIT binary patch literal 16368 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 literal 18536 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
n|T@w5iRyS_V(w2EpSgwp~H(+|FrYUD9y(ZszXQ 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 ZUB5Z~k~bNjL!c}vKTlep1ZtyR#&5l|OWby{ z9=(GYC{Z=Jbcl>>rsg)Uj2G)t5s}&?TK1s14Caf9O(i(^6)e(G59WxrlMj&Q8nUhB zXA(w4T3^XBI6<_gP!w0HBtJ( z0GkXZif~K^Y3L{~$t5`p;m-2l-ZjQAiE*=YpD->5kN#wBlSBfcX381fj`Nk_z7pD} zS3%(*08-?OMRvHkuqHur+~cnnMdL%f_dT zr$a_B@bnke7d$%2i{qBt$YFFI!CU7iqmm=FP}8VY!GvX!o0ZtYwwW;3E2%**k=Q2b zj3oKBImfL^8=oUdCm|t+y)9XNI67cTGN_|iF6+wVpYvMA z_R@112h?GVWOE>j7}#}qt~Xx)>R>(8acKlTl8Y{mDH$-p;gu4qi>g-&@lZ8K{& z>rKgW)EM6IL?DUohG0^NojMiZ)uFW&nekBA0(l+R@?3{=?@YBJe}U#QyG%1!2z@3g zXkTD1XD5(|>$~y=9peecjo1-WjL!o{%Guf}I%ZXMq*s9q4L8!mMzj@n8v@~}AE30< zzj?9{)RS`&3N=M#tbQVz8`~$yZYm&=lUUk73!>tVwZ&SIk6_EF)#V(DN-_Ls|2x|FrO^&DDXD=Pji5@gDWSA2f2zuo z_OK$0Nqx^X<#E;(BOh@?S+&#Y%e?2ce}L|&1nJwv`=g0ZR11giZ|lV4w|#}FbkCz^n%oQBfm~HUl1w?n zd@{Hi+5UJO9~_9=9qD$yClV)oAMsz*9(?*ytq-SZ1e2nIIHJPHq~waNci;1zd(K;; zCk&9)RTb-os?al*^OK1->V!srQ$~e~qDp)?IOlX+0d}X*EUR(Ynd^6?x-Z)f97{4P zvGRmOU#yil7-{0r4yZ{{Q#F4lX#RsijmJ7#yrTezB}q`b>nd>FdI`89Srd`v-9ZTS z)>{fH@`&7Ga=tE(Hk?+NfD#Z1G*E&5`Q1z~YmpW<7>AwT)h{t` z0&3s|X}$o)u47dSm+N)gz@W)_4bGHkVVHX{6T`T3arA6M+f2kSFuUt1p6Q~Z`dOmL z1ESdOX=?^iob}zRW{b<lWKiz1d!(Ptm@VP{6G@yf@h=hEvurF)H0W9qx^_ZZNfg zY`oXq@PC4K=2D7pHJc+wS9Wv6!t@bbL~B2~Hd5=?^F9~!D2uZ(!^ioe=x)9L{(Nvb z?>1i=m92#x`Bpt!45d~f*&{+*k)#=)ukG#}ueAuV`I5Wm$}Uxb0jq~4=>*UXOV6|V zn`^8x&NJyiAHNM>Lj=RmU?QmU4G4QDAa0!tSxkK6c>VS_;<0X*eBngP{3K&3OX03B zq`Ttd$Hf_~8zpQ7y16`Noex(`FsTHzWDII0ggwSn&RsDX2J)`~SM(*|KM+H-Zd}OD zKtU^SmKaOT8S*?|OzIvUEmd8(SHz6@1xV+<+b9ZfJWZyJWU?d+XKjKSbW?@==UD4{ z#ubTCK-Nte(2Mip6X!k&r&T(nP9E3}iUo?sl(4!C+3?NAuF(@QAT-jFiSiBeq(_^< z5tcr8F-fI2ER&}Go`Dy;7|7ouJ!)WJf8Y_@C`~=Uz~NyAs<9bBI`KOP4?G{BryDZi zP`q?679xI-zP{*xgeO&M#?}xXLB9iNb?aP>#nfP?*v?~;d4?hDrcFIV#;r6lA{@pf zy$Uxa@f<3CNhAc+JB7nSIb@a8_C9{}^mE)|GYU28C zcMC>DHCl=sVg4}O zg>%=!m-Sq>4$sM{7+`d!?3=0O{hVVjbY8sEd2txa_E>JW`qC`3dMWL{wYjVQ5(S>*0~Grd>~|DZXs0(jkf`xWMW;QpvN$H1wSJq+YcX> uint(2)) + (2u * ix); - Bic _286 = { _96.Load(base * 4 + 8), _96.Load((base + 1u) * 4 + 8) }; - return _286; + uint base = (_80.Load(56) >> uint(2)) + (2u * ix); + Bic _287 = { _96.Load(base * 4 + 12), _96.Load((base + 1u) * 4 + 12) }; + return _287; } Bic bic_combine(Bic x, Bic y) @@ -85,15 +86,15 @@ Bic bic_combine(Bic x, Bic y) ClipEl load_clip_el(uint ix) { - uint base = (_80.Load(56) >> uint(2)) + (5u * ix); - uint parent_ix = _96.Load(base * 4 + 8); - float x0 = asfloat(_96.Load((base + 1u) * 4 + 8)); - float y0 = asfloat(_96.Load((base + 2u) * 4 + 8)); - float x1 = asfloat(_96.Load((base + 3u) * 4 + 8)); - float y1 = asfloat(_96.Load((base + 4u) * 4 + 8)); + uint base = (_80.Load(60) >> uint(2)) + (5u * ix); + uint parent_ix = _96.Load(base * 4 + 12); + float x0 = asfloat(_96.Load((base + 1u) * 4 + 12)); + float y0 = asfloat(_96.Load((base + 2u) * 4 + 12)); + float x1 = asfloat(_96.Load((base + 3u) * 4 + 12)); + float y1 = asfloat(_96.Load((base + 4u) * 4 + 12)); float4 bbox = float4(x0, y0, x1, y1); - ClipEl _335 = { parent_ix, bbox }; - return _335; + ClipEl _336 = { parent_ix, bbox }; + return _336; } float4 bbox_intersect(float4 a, float4 b) @@ -103,9 +104,9 @@ float4 bbox_intersect(float4 a, float4 b) uint load_path_ix(uint ix) { - if (ix < _80.Load(80)) + if (ix < _80.Load(84)) { - return _96.Load(((_80.Load(48) >> uint(2)) + ix) * 4 + 8); + return _96.Load(((_80.Load(52) >> uint(2)) + ix) * 4 + 12); } else { @@ -115,11 +116,11 @@ uint load_path_ix(uint ix) float4 load_path_bbox(uint path_ix) { - uint base = (_80.Load(40) >> uint(2)) + (6u * path_ix); - float bbox_l = float(_96.Load(base * 4 + 8)) - 32768.0f; - float bbox_t = float(_96.Load((base + 1u) * 4 + 8)) - 32768.0f; - float bbox_r = float(_96.Load((base + 2u) * 4 + 8)) - 32768.0f; - float bbox_b = float(_96.Load((base + 3u) * 4 + 8)) - 32768.0f; + uint base = (_80.Load(44) >> uint(2)) + (6u * path_ix); + float bbox_l = float(_96.Load(base * 4 + 12)) - 32768.0f; + float bbox_t = float(_96.Load((base + 1u) * 4 + 12)) - 32768.0f; + float bbox_r = float(_96.Load((base + 2u) * 4 + 12)) - 32768.0f; + float bbox_b = float(_96.Load((base + 3u) * 4 + 12)) - 32768.0f; float4 bbox = float4(bbox_l, bbox_t, bbox_r, bbox_b); return bbox; } @@ -173,17 +174,17 @@ uint search_link(inout Bic bic) void store_clip_bbox(uint ix, float4 bbox) { - uint base = (_80.Load(60) >> uint(2)) + (4u * ix); - _96.Store(base * 4 + 8, asuint(bbox.x)); - _96.Store((base + 1u) * 4 + 8, asuint(bbox.y)); - _96.Store((base + 2u) * 4 + 8, asuint(bbox.z)); - _96.Store((base + 3u) * 4 + 8, asuint(bbox.w)); + uint base = (_80.Load(64) >> uint(2)) + (4u * ix); + _96.Store(base * 4 + 12, asuint(bbox.x)); + _96.Store((base + 1u) * 4 + 12, asuint(bbox.y)); + _96.Store((base + 2u) * 4 + 12, asuint(bbox.z)); + _96.Store((base + 3u) * 4 + 12, asuint(bbox.w)); } void comp_main() { uint th = gl_LocalInvocationID.x; - Bic bic = _393; + Bic bic = _394; if (th < gl_WorkGroupID.x) { uint param = th; @@ -240,8 +241,8 @@ void comp_main() uint param_6 = gl_GlobalInvocationID.x; uint inp = load_path_ix(param_6); bool is_push = int(inp) >= 0; - Bic _559 = { 1u - uint(is_push), uint(is_push) }; - bic = _559; + Bic _560 = { 1u - uint(is_push), uint(is_push) }; + bic = _560; sh_bic[th] = bic; if (is_push) { @@ -266,11 +267,11 @@ void comp_main() inbase = outbase; } GroupMemoryBarrierWithGroupSync(); - bic = _393; + bic = _394; Bic param_10 = bic; - uint _618 = search_link(param_10); + uint _619 = search_link(param_10); bic = param_10; - uint link = _618; + uint link = _619; sh_link[th] = link; GroupMemoryBarrierWithGroupSync(); uint grandparent; @@ -324,22 +325,22 @@ void comp_main() sh_bbox[th] = bbox; GroupMemoryBarrierWithGroupSync(); uint path_ix = inp; - bool _717 = !is_push; - bool _725; - if (_717) + bool _718 = !is_push; + bool _726; + if (_718) { - _725 = gl_GlobalInvocationID.x < _80.Load(80); + _726 = gl_GlobalInvocationID.x < _80.Load(84); } else { - _725 = _717; + _726 = _718; } - if (_725) + if (_726) { uint param_15 = parent; path_ix = load_path_ix(param_15); - uint drawmonoid_out_base = (_80.Load(44) >> uint(2)) + (4u * (~inp)); - _96.Store(drawmonoid_out_base * 4 + 8, path_ix); + uint drawmonoid_out_base = (_80.Load(48) >> uint(2)) + (4u * (~inp)); + _96.Store(drawmonoid_out_base * 4 + 12, path_ix); if (int(grandparent) >= 0) { bbox = sh_bbox[grandparent]; diff --git a/piet-gpu/shader/gen/clip_leaf.msl b/piet-gpu/shader/gen/clip_leaf.msl index 5f5e0a7..c9456e8 100644 --- a/piet-gpu/shader/gen/clip_leaf.msl +++ b/piet-gpu/shader/gen/clip_leaf.msl @@ -24,6 +24,7 @@ struct Alloc struct Config { + uint mem_size; uint n_elements; uint n_pathseg; uint width_in_tiles; @@ -62,6 +63,7 @@ struct Memory { uint mem_offset; uint mem_error; + uint blend_offset; uint memory[1]; }; @@ -275,9 +277,9 @@ kernel void main0(device Memory& v_96 [[buffer(0)]], const device ConfigBuf& v_8 threadgroup_barrier(mem_flags::mem_threadgroup); bic = Bic{ 0u, 0u }; Bic param_10 = bic; - uint _618 = search_link(param_10, gl_LocalInvocationID, sh_bic); + uint _619 = search_link(param_10, gl_LocalInvocationID, sh_bic); bic = param_10; - uint link = _618; + uint link = _619; sh_link[th] = link; threadgroup_barrier(mem_flags::mem_threadgroup); uint grandparent; @@ -331,17 +333,17 @@ kernel void main0(device Memory& v_96 [[buffer(0)]], const device ConfigBuf& v_8 sh_bbox[th] = bbox; threadgroup_barrier(mem_flags::mem_threadgroup); uint path_ix = inp; - bool _717 = !is_push; - bool _725; - if (_717) + bool _718 = !is_push; + bool _726; + if (_718) { - _725 = gl_GlobalInvocationID.x < v_80.conf.n_clip; + _726 = gl_GlobalInvocationID.x < v_80.conf.n_clip; } else { - _725 = _717; + _726 = _718; } - if (_725) + if (_726) { uint param_15 = parent; path_ix = load_path_ix(param_15, v_80, v_96); diff --git a/piet-gpu/shader/gen/clip_leaf.spv b/piet-gpu/shader/gen/clip_leaf.spv index beac64bdaa072ba89007bfba4e7c1aac3ffa7c77..fe626323c1913a1cdaec2a0ca3a4a58477f67e93 100644 GIT binary patch literal 19356 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 literal 19240 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 delta 941 zcmYLGZ)_7~9DeV5|JGiv*Xx~JU58i7U}YfJWlmrN?%FcDF=MxMP(bB2!JwO4_kjeW zNw5D#WBQ@cVho?Uh%!HzbwQKq7yEY8FZ9C*nh>*)jSyYbm}(3eQvX~Diyz+P_ddVh z^SrmjyrYjAN!p0crxsJ|2zT!VCNlQllw2+_CJpNTOXUe_}9zi zSIeG2q;Ehn1E2vMWKaMacVLXO27@wipTB(1MFSAKX``Max*r;_9eZVWqs z89bat>FH+l5J;XNwo$z_4KP?Prn@5PwdpET)fPtRlL-B$!|WEl3ShCM=b69^eNW?i z?P$@wZ-GN+HU9I&kZwy7K$U05*Z8|q5Z@sTxr7HrY;Y5wK!hKp5FUF;2&=-6+6QIP zD;sjAGh6!OJjLjP<57#e!d6j7wZj=KCF0Jg8i5M)rJMsar+ZhV8Y)&f$s~ZO^|Uwi zJ4+rEU%(IC%C)I`{Na+hlt8vFxx_9h(Ie^tU6YxLVcQY}Rj$oV5JqnLtZ7fIT8SpN z_83-`WW%b9ZI=!ff#@bEqc4BD`20qEcdhayCCiWx2(`qqRm;-|?L8^K2fHs{W5Jg9 z&c=6@Z)8vFHWOz2`oo{0Gwj-T>2?Y%thQTTM-F|lfo4U?2nk-d{!%j|-Ps*j89#l3 zS1dIT)uJr{L}BSqVmf(}x}PU)dtE2GorboG+g&3J3_9Ij&JCHLz$yRXaz-^7afds++&WuGg}By1?zgD5H2h$b zbj02|!@xdj=M=XSv69FsGH8(6pRl^7xL?`psT}9I%>5Cym9B1VveI_X8Uy>O_Ia*7 IziR9J4|Jd;4gdfE diff --git a/piet-gpu/shader/gen/clip_reduce.hlsl b/piet-gpu/shader/gen/clip_reduce.hlsl index 1276b5f..e031f84 100644 --- a/piet-gpu/shader/gen/clip_reduce.hlsl +++ b/piet-gpu/shader/gen/clip_reduce.hlsl @@ -17,6 +17,7 @@ struct Alloc struct Config { + uint mem_size; uint n_elements; uint n_pathseg; uint width_in_tiles; @@ -48,7 +49,7 @@ struct Config static const uint3 gl_WorkGroupSize = uint3(256u, 1u, 1u); -static const Bic _267 = { 0u, 0u }; +static const Bic _268 = { 0u, 0u }; ByteAddressBuffer _64 : register(t1, space0); RWByteAddressBuffer _80 : register(u0, space0); @@ -77,39 +78,39 @@ Bic bic_combine(Bic x, Bic y) void store_bic(uint ix, Bic bic) { - uint base = (_64.Load(52) >> uint(2)) + (2u * ix); - _80.Store(base * 4 + 8, bic.a); - _80.Store((base + 1u) * 4 + 8, bic.b); + uint base = (_64.Load(56) >> uint(2)) + (2u * ix); + _80.Store(base * 4 + 12, bic.a); + _80.Store((base + 1u) * 4 + 12, bic.b); } float4 load_path_bbox(uint path_ix) { - uint base = (_64.Load(40) >> uint(2)) + (6u * path_ix); - float bbox_l = float(_80.Load(base * 4 + 8)) - 32768.0f; - float bbox_t = float(_80.Load((base + 1u) * 4 + 8)) - 32768.0f; - float bbox_r = float(_80.Load((base + 2u) * 4 + 8)) - 32768.0f; - float bbox_b = float(_80.Load((base + 3u) * 4 + 8)) - 32768.0f; + uint base = (_64.Load(44) >> uint(2)) + (6u * path_ix); + float bbox_l = float(_80.Load(base * 4 + 12)) - 32768.0f; + float bbox_t = float(_80.Load((base + 1u) * 4 + 12)) - 32768.0f; + float bbox_r = float(_80.Load((base + 2u) * 4 + 12)) - 32768.0f; + float bbox_b = float(_80.Load((base + 3u) * 4 + 12)) - 32768.0f; float4 bbox = float4(bbox_l, bbox_t, bbox_r, bbox_b); return bbox; } void store_clip_el(uint ix, ClipEl el) { - uint base = (_64.Load(56) >> uint(2)) + (5u * ix); - _80.Store(base * 4 + 8, el.parent_ix); - _80.Store((base + 1u) * 4 + 8, asuint(el.bbox.x)); - _80.Store((base + 2u) * 4 + 8, asuint(el.bbox.y)); - _80.Store((base + 3u) * 4 + 8, asuint(el.bbox.z)); - _80.Store((base + 4u) * 4 + 8, asuint(el.bbox.w)); + uint base = (_64.Load(60) >> uint(2)) + (5u * ix); + _80.Store(base * 4 + 12, el.parent_ix); + _80.Store((base + 1u) * 4 + 12, asuint(el.bbox.x)); + _80.Store((base + 2u) * 4 + 12, asuint(el.bbox.y)); + _80.Store((base + 3u) * 4 + 12, asuint(el.bbox.z)); + _80.Store((base + 4u) * 4 + 12, asuint(el.bbox.w)); } void comp_main() { uint th = gl_LocalInvocationID.x; - uint inp = _80.Load(((_64.Load(48) >> uint(2)) + gl_GlobalInvocationID.x) * 4 + 8); + uint inp = _80.Load(((_64.Load(52) >> uint(2)) + gl_GlobalInvocationID.x) * 4 + 12); bool is_push = int(inp) >= 0; - Bic _207 = { 1u - uint(is_push), uint(is_push) }; - Bic bic = _207; + Bic _208 = { 1u - uint(is_push), uint(is_push) }; + Bic bic = _208; sh_bic[gl_LocalInvocationID.x] = bic; for (uint i = 0u; i < 8u; i++) { @@ -132,21 +133,21 @@ void comp_main() } GroupMemoryBarrierWithGroupSync(); uint size = sh_bic[0].b; - bic = _267; + bic = _268; if ((th + 1u) < 256u) { bic = sh_bic[th + 1u]; } - bool _283; + bool _284; if (is_push) { - _283 = bic.a == 0u; + _284 = bic.a == 0u; } else { - _283 = is_push; + _284 = is_push; } - if (_283) + if (_284) { uint local_ix = (size - bic.b) - 1u; sh_parent[local_ix] = th; @@ -163,8 +164,8 @@ void comp_main() if (th < size) { uint parent_ix = sh_parent[th] + (gl_WorkGroupID.x * 256u); - ClipEl _331 = { parent_ix, bbox }; - ClipEl el = _331; + ClipEl _332 = { parent_ix, bbox }; + ClipEl el = _332; uint param_5 = gl_GlobalInvocationID.x; ClipEl param_6 = el; store_clip_el(param_5, param_6); diff --git a/piet-gpu/shader/gen/clip_reduce.msl b/piet-gpu/shader/gen/clip_reduce.msl index 26214f1..dd34e64 100644 --- a/piet-gpu/shader/gen/clip_reduce.msl +++ b/piet-gpu/shader/gen/clip_reduce.msl @@ -24,6 +24,7 @@ struct Alloc struct Config { + uint mem_size; uint n_elements; uint n_pathseg; uint width_in_tiles; @@ -62,6 +63,7 @@ struct Memory { uint mem_offset; uint mem_error; + uint blend_offset; uint memory[1]; }; @@ -142,16 +144,16 @@ kernel void main0(device Memory& v_80 [[buffer(0)]], const device ConfigBuf& v_6 { bic = sh_bic[th + 1u]; } - bool _283; + bool _284; if (is_push) { - _283 = bic.a == 0u; + _284 = bic.a == 0u; } else { - _283 = is_push; + _284 = is_push; } - if (_283) + if (_284) { uint local_ix = (size - bic.b) - 1u; sh_parent[local_ix] = th; diff --git a/piet-gpu/shader/gen/clip_reduce.spv b/piet-gpu/shader/gen/clip_reduce.spv index ce0b9bb3caf196d74fc50dd627ba9bbf971c9794..40121e75edcd0425ae3c04046dc041f913c379f8 100644 GIT binary patch literal 9812 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 CNZB6% diff --git a/piet-gpu/shader/gen/coarse.dxil b/piet-gpu/shader/gen/coarse.dxil index f71cc0441f5852ebbb2a904e3dc8c03be2439447..58e2da88187b24296162ab87caa54531ded9a85b 100644 GIT binary patch literal 11724 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 literal 11972 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 G^}hg|0Gb{E diff --git a/piet-gpu/shader/gen/coarse.hlsl b/piet-gpu/shader/gen/coarse.hlsl index a7f769f..673e879 100644 --- a/piet-gpu/shader/gen/coarse.hlsl +++ b/piet-gpu/shader/gen/coarse.hlsl @@ -3,12 +3,6 @@ struct Alloc uint offset; }; -struct MallocResult -{ - Alloc alloc; - bool failed; -}; - struct BinInstanceRef { uint offset; @@ -144,6 +138,7 @@ struct CmdRef struct Config { + uint mem_size; uint n_elements; uint n_pathseg; uint width_in_tiles; @@ -175,9 +170,9 @@ struct Config static const uint3 gl_WorkGroupSize = uint3(256u, 1u, 1u); -RWByteAddressBuffer _266 : register(u0, space0); -ByteAddressBuffer _1020 : register(t1, space0); -ByteAddressBuffer _1399 : register(t2, space0); +RWByteAddressBuffer _267 : register(u0, space0); +ByteAddressBuffer _891 : register(t1, space0); +ByteAddressBuffer _1390 : register(t2, space0); static uint3 gl_WorkGroupID; static uint3 gl_LocalInvocationID; @@ -187,6 +182,7 @@ struct SPIRV_Cross_Input uint3 gl_LocalInvocationID : SV_GroupThreadID; }; +static bool mem_ok; groupshared uint sh_bitmaps[8][256]; groupshared Alloc sh_part_elements[256]; groupshared uint sh_part_count[256]; @@ -198,10 +194,17 @@ groupshared uint sh_tile_y0[256]; groupshared uint sh_tile_base[256]; groupshared uint sh_tile_count[256]; +bool check_deps(uint dep_stage) +{ + uint _273; + _267.InterlockedOr(4, 0u, _273); + return (_273 & dep_stage) == 0u; +} + Alloc slice_mem(Alloc a, uint offset, uint size) { - Alloc _343 = { a.offset + offset }; - return _343; + Alloc _331 = { a.offset + offset }; + return _331; } bool touch_mem(Alloc alloc, uint offset) @@ -217,11 +220,11 @@ uint read_mem(Alloc alloc, uint offset) { return 0u; } - uint v = _266.Load(offset * 4 + 8); + uint v = _267.Load(offset * 4 + 12); return v; } -Alloc new_alloc(uint offset, uint size, bool mem_ok) +Alloc new_alloc(uint offset, uint size, bool mem_ok_1) { Alloc a; a.offset = offset; @@ -230,8 +233,8 @@ Alloc new_alloc(uint offset, uint size, bool mem_ok) BinInstanceRef BinInstance_index(BinInstanceRef ref, uint index) { - BinInstanceRef _361 = { ref.offset + (index * 4u) }; - return _361; + BinInstanceRef _340 = { ref.offset + (index * 4u) }; + return _340; } BinInstance BinInstance_read(Alloc a, BinInstanceRef ref) @@ -259,8 +262,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 _424 = { raw2 }; - s.tiles = _424; + TileRef _404 = { raw2 }; + s.tiles = _404; return s; } @@ -268,14 +271,11 @@ void write_tile_alloc(uint el_ix, Alloc a) { } -Alloc read_tile_alloc(uint el_ix, bool mem_ok) +Alloc read_tile_alloc(uint el_ix, bool mem_ok_1) { - uint _907; - _266.GetDimensions(_907); - _907 = (_907 - 8) / 4; uint param = 0u; - uint param_1 = uint(int(_907) * 4); - bool param_2 = mem_ok; + uint param_1 = _891.Load(0); + bool param_2 = mem_ok_1; return new_alloc(param, param_1, param_2); } @@ -288,34 +288,25 @@ 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 _449 = { raw0 }; + TileSegRef _429 = { raw0 }; Tile s; - s.tile = _449; + s.tile = _429; s.backdrop = int(raw1); return s; } -MallocResult malloc(uint size) +uint malloc_stage(uint size, uint mem_size, uint stage) { - uint _272; - _266.InterlockedAdd(0, size, _272); - uint offset = _272; - uint _279; - _266.GetDimensions(_279); - _279 = (_279 - 8) / 4; - MallocResult r; - r.failed = (offset + size) > uint(int(_279) * 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 _282; + _267.InterlockedAdd(0, size, _282); + uint offset = _282; + if ((offset + size) > mem_size) { - uint _301; - _266.InterlockedMax(4, 1u, _301); - return r; + uint _292; + _267.InterlockedOr(4, stage, _292); + offset = 0u; } - return r; + return offset; } void write_mem(Alloc alloc, uint offset, uint val) @@ -326,7 +317,7 @@ void write_mem(Alloc alloc, uint offset, uint val) { return; } - _266.Store(offset * 4 + 8, val); + _267.Store(offset * 4 + 12, val); } void CmdJump_write(Alloc a, CmdJumpRef ref, CmdJump s) @@ -344,37 +335,44 @@ void Cmd_Jump_write(Alloc a, CmdRef ref, CmdJump s) uint param_1 = ref.offset >> uint(2); uint param_2 = 11u; write_mem(param, param_1, param_2); - CmdJumpRef _900 = { ref.offset + 4u }; + CmdJumpRef _880 = { ref.offset + 4u }; Alloc param_3 = a; - CmdJumpRef param_4 = _900; + CmdJumpRef param_4 = _880; CmdJump param_5 = s; CmdJump_write(param_3, param_4, param_5); } -bool alloc_cmd(inout Alloc cmd_alloc, inout CmdRef cmd_ref, inout uint cmd_limit) +void alloc_cmd(inout Alloc cmd_alloc, inout CmdRef cmd_ref, inout uint cmd_limit) { if (cmd_ref.offset < cmd_limit) { - return true; + return; } uint param = 1024u; - MallocResult _928 = malloc(param); - MallocResult new_cmd = _928; - if (new_cmd.failed) + uint param_1 = _891.Load(0); + uint param_2 = 8u; + uint _915 = malloc_stage(param, param_1, param_2); + uint new_cmd = _915; + if (new_cmd == 0u) { - return false; + mem_ok = false; } - CmdJump _938 = { new_cmd.alloc.offset }; - CmdJump jump = _938; - 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 _950 = { cmd_alloc.offset }; - cmd_ref = _950; - cmd_limit = (cmd_alloc.offset + 1024u) - 144u; - return true; + if (mem_ok) + { + CmdJump _926 = { new_cmd }; + CmdJump jump = _926; + Alloc param_3 = cmd_alloc; + CmdRef param_4 = cmd_ref; + CmdJump param_5 = jump; + Cmd_Jump_write(param_3, param_4, param_5); + } + uint param_6 = new_cmd; + uint param_7 = 1024u; + bool param_8 = true; + cmd_alloc = new_alloc(param_6, param_7, param_8); + CmdRef _940 = { new_cmd }; + cmd_ref = _940; + cmd_limit = (new_cmd + 1024u) - 144u; } void CmdFill_write(Alloc a, CmdFillRef ref, CmdFill s) @@ -396,9 +394,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 _757 = { ref.offset + 4u }; + CmdFillRef _737 = { ref.offset + 4u }; Alloc param_3 = a; - CmdFillRef param_4 = _757; + CmdFillRef param_4 = _737; CmdFill param_5 = s; CmdFill_write(param_3, param_4, param_5); } @@ -430,9 +428,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 _775 = { ref.offset + 4u }; + CmdStrokeRef _755 = { ref.offset + 4u }; Alloc param_3 = a; - CmdStrokeRef param_4 = _775; + CmdStrokeRef param_4 = _755; CmdStroke param_5 = s; CmdStroke_write(param_3, param_4, param_5); } @@ -443,30 +441,39 @@ void write_fill(Alloc alloc, inout CmdRef cmd_ref, Tile tile, float linewidth) { if (tile.tile.offset != 0u) { - CmdFill _973 = { tile.tile.offset, tile.backdrop }; - CmdFill cmd_fill = _973; - Alloc param = alloc; - CmdRef param_1 = cmd_ref; - CmdFill param_2 = cmd_fill; - Cmd_Fill_write(param, param_1, param_2); + CmdFill _960 = { tile.tile.offset, tile.backdrop }; + CmdFill cmd_fill = _960; + if (mem_ok) + { + Alloc param = alloc; + CmdRef param_1 = cmd_ref; + CmdFill param_2 = cmd_fill; + Cmd_Fill_write(param, param_1, param_2); + } cmd_ref.offset += 12u; } else { - Alloc param_3 = alloc; - CmdRef param_4 = cmd_ref; - Cmd_Solid_write(param_3, param_4); + if (mem_ok) + { + Alloc param_3 = alloc; + CmdRef param_4 = cmd_ref; + Cmd_Solid_write(param_3, param_4); + } cmd_ref.offset += 4u; } } else { - CmdStroke _1003 = { tile.tile.offset, 0.5f * linewidth }; - CmdStroke cmd_stroke = _1003; - Alloc param_5 = alloc; - CmdRef param_6 = cmd_ref; - CmdStroke param_7 = cmd_stroke; - Cmd_Stroke_write(param_5, param_6, param_7); + CmdStroke _996 = { tile.tile.offset, 0.5f * linewidth }; + CmdStroke cmd_stroke = _996; + if (mem_ok) + { + Alloc param_5 = alloc; + CmdRef param_6 = cmd_ref; + CmdStroke param_7 = cmd_stroke; + Cmd_Stroke_write(param_5, param_6, param_7); + } cmd_ref.offset += 12u; } } @@ -486,9 +493,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 _801 = { ref.offset + 4u }; + CmdColorRef _781 = { ref.offset + 4u }; Alloc param_3 = a; - CmdColorRef param_4 = _801; + CmdColorRef param_4 = _781; CmdColor param_5 = s; CmdColor_write(param_3, param_4, param_5); } @@ -520,9 +527,9 @@ 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 _819 = { ref.offset + 4u }; + CmdLinGradRef _799 = { ref.offset + 4u }; Alloc param_3 = a; - CmdLinGradRef param_4 = _819; + CmdLinGradRef param_4 = _799; CmdLinGrad param_5 = s; CmdLinGrad_write(param_3, param_4, param_5); } @@ -582,9 +589,9 @@ void Cmd_RadGrad_write(Alloc a, CmdRef ref, CmdRadGrad s) uint param_1 = ref.offset >> uint(2); uint param_2 = 7u; write_mem(param, param_1, param_2); - CmdRadGradRef _837 = { ref.offset + 4u }; + CmdRadGradRef _817 = { ref.offset + 4u }; Alloc param_3 = a; - CmdRadGradRef param_4 = _837; + CmdRadGradRef param_4 = _817; CmdRadGrad param_5 = s; CmdRadGrad_write(param_3, param_4, param_5); } @@ -608,9 +615,9 @@ void Cmd_Image_write(Alloc a, CmdRef ref, CmdImage s) uint param_1 = ref.offset >> uint(2); uint param_2 = 8u; write_mem(param, param_1, param_2); - CmdImageRef _855 = { ref.offset + 4u }; + CmdImageRef _835 = { ref.offset + 4u }; Alloc param_3 = a; - CmdImageRef param_4 = _855; + CmdImageRef param_4 = _835; CmdImage param_5 = s; CmdImage_write(param_3, param_4, param_5); } @@ -638,9 +645,9 @@ void Cmd_EndClip_write(Alloc a, CmdRef ref, CmdEndClip s) uint param_1 = ref.offset >> uint(2); uint param_2 = 10u; write_mem(param, param_1, param_2); - CmdEndClipRef _881 = { ref.offset + 4u }; + CmdEndClipRef _861 = { ref.offset + 4u }; Alloc param_3 = a; - CmdEndClipRef param_4 = _881; + CmdEndClipRef param_4 = _861; CmdEndClip param_5 = s; CmdEndClip_write(param_3, param_4, param_5); } @@ -653,35 +660,34 @@ void Cmd_End_write(Alloc a, CmdRef ref) write_mem(param, param_1, param_2); } -void alloc_write(Alloc a, uint offset, Alloc alloc) -{ - Alloc param = a; - uint param_1 = offset >> uint(2); - uint param_2 = alloc.offset; - write_mem(param, param_1, param_2); -} - void comp_main() { - uint width_in_bins = ((_1020.Load(8) + 16u) - 1u) / 16u; + mem_ok = true; + uint param = 7u; + bool _1012 = check_deps(param); + if (!_1012) + { + return; + } + uint width_in_bins = ((_891.Load(12) + 16u) - 1u) / 16u; uint bin_ix = (width_in_bins * gl_WorkGroupID.y) + gl_WorkGroupID.x; uint partition_ix = 0u; - uint n_partitions = ((_1020.Load(0) + 256u) - 1u) / 256u; + uint n_partitions = ((_891.Load(4) + 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) * _1020.Load(8)) + bin_tile_x) + tile_x; - Alloc _1085; - _1085.offset = _1020.Load(24); - Alloc param; - param.offset = _1085.offset; - uint param_1 = this_tile_ix * 1024u; - uint param_2 = 1024u; - Alloc cmd_alloc = slice_mem(param, param_1, param_2); - CmdRef _1094 = { cmd_alloc.offset }; - CmdRef cmd_ref = _1094; + uint this_tile_ix = (((bin_tile_y + tile_y) * _891.Load(12)) + bin_tile_x) + tile_x; + Alloc _1082; + _1082.offset = _891.Load(28); + Alloc param_1; + param_1.offset = _1082.offset; + uint param_2 = this_tile_ix * 1024u; + uint param_3 = 1024u; + Alloc cmd_alloc = slice_mem(param_1, param_2, param_3); + CmdRef _1091 = { cmd_alloc.offset }; + CmdRef cmd_ref = _1091; uint cmd_limit = (cmd_ref.offset + 1024u) - 144u; uint clip_depth = 0u; uint clip_zero_depth = 0u; @@ -689,25 +695,24 @@ void comp_main() uint wr_ix = 0u; uint part_start_ix = 0u; uint ready_ix = 0u; - Alloc param_3 = cmd_alloc; - uint param_4 = 0u; - uint param_5 = 8u; - Alloc scratch_alloc = slice_mem(param_3, param_4, param_5); + Alloc param_4 = cmd_alloc; + uint param_5 = 0u; + uint param_6 = 8u; + Alloc scratch_alloc = slice_mem(param_4, param_5, param_6); cmd_ref.offset += 4u; uint render_blend_depth = 0u; uint max_blend_depth = 0u; - uint drawmonoid_start = _1020.Load(44) >> uint(2); - uint drawtag_start = _1020.Load(100) >> uint(2); - uint drawdata_start = _1020.Load(104) >> uint(2); - uint drawinfo_start = _1020.Load(68) >> uint(2); - bool mem_ok = _266.Load(4) == 0u; - Alloc param_6; - Alloc param_8; - uint _1331; + uint drawmonoid_start = _891.Load(48) >> uint(2); + uint drawtag_start = _891.Load(104) >> uint(2); + uint drawdata_start = _891.Load(108) >> uint(2); + uint drawinfo_start = _891.Load(72) >> uint(2); + Alloc param_7; + Alloc param_9; + uint _1322; uint element_ix; - Alloc param_17; + Alloc param_18; uint tile_count; - uint _1632; + uint _1622; float linewidth; CmdLinGrad cmd_lin; CmdRadGrad cmd_rad; @@ -717,40 +722,40 @@ void comp_main() { sh_bitmaps[i][th_ix] = 0u; } - bool _1383; + bool _1374; for (;;) { if ((ready_ix == wr_ix) && (partition_ix < n_partitions)) { part_start_ix = ready_ix; uint count = 0u; - bool _1181 = th_ix < 256u; - bool _1189; - if (_1181) + bool _1174 = th_ix < 256u; + bool _1182; + if (_1174) { - _1189 = (partition_ix + th_ix) < n_partitions; + _1182 = (partition_ix + th_ix) < n_partitions; } else { - _1189 = _1181; + _1182 = _1174; } - if (_1189) + if (_1182) { - uint in_ix = (_1020.Load(20) >> uint(2)) + ((((partition_ix + th_ix) * 256u) + bin_ix) * 2u); - Alloc _1206; - _1206.offset = _1020.Load(20); - param_6.offset = _1206.offset; - uint param_7 = in_ix; - count = read_mem(param_6, param_7); - Alloc _1217; - _1217.offset = _1020.Load(20); - param_8.offset = _1217.offset; - uint param_9 = in_ix + 1u; - uint offset = read_mem(param_8, param_9); - uint param_10 = offset; - uint param_11 = count * 4u; - bool param_12 = mem_ok; - sh_part_elements[th_ix] = new_alloc(param_10, param_11, param_12); + uint in_ix = (_891.Load(24) >> uint(2)) + ((((partition_ix + th_ix) * 256u) + bin_ix) * 2u); + Alloc _1200; + _1200.offset = _891.Load(24); + param_7.offset = _1200.offset; + uint param_8 = in_ix; + count = read_mem(param_7, param_8); + Alloc _1211; + _1211.offset = _891.Load(24); + param_9.offset = _1211.offset; + uint param_10 = in_ix + 1u; + uint offset = read_mem(param_9, param_10); + uint param_11 = offset; + uint param_12 = count * 4u; + bool param_13 = true; + sh_part_elements[th_ix] = new_alloc(param_11, param_12, param_13); } for (uint i_1 = 0u; i_1 < 8u; i_1++) { @@ -777,7 +782,7 @@ void comp_main() partition_ix += 256u; } uint ix = rd_ix + th_ix; - if (((ix >= wr_ix) && (ix < ready_ix)) && mem_ok) + if ((ix >= wr_ix) && (ix < ready_ix)) { uint part_ix = 0u; for (uint i_2 = 0u; i_2 < 8u; i_2++) @@ -790,35 +795,35 @@ void comp_main() } if (part_ix > 0u) { - _1331 = sh_part_count[part_ix - 1u]; + _1322 = sh_part_count[part_ix - 1u]; } else { - _1331 = part_start_ix; + _1322 = part_start_ix; } - ix -= _1331; + ix -= _1322; Alloc bin_alloc = sh_part_elements[part_ix]; - BinInstanceRef _1350 = { bin_alloc.offset }; - BinInstanceRef inst_ref = _1350; - BinInstanceRef param_13 = inst_ref; - uint param_14 = ix; - Alloc param_15 = bin_alloc; - BinInstanceRef param_16 = BinInstance_index(param_13, param_14); - BinInstance inst = BinInstance_read(param_15, param_16); + BinInstanceRef _1341 = { bin_alloc.offset }; + BinInstanceRef inst_ref = _1341; + BinInstanceRef param_14 = inst_ref; + uint param_15 = ix; + Alloc param_16 = bin_alloc; + BinInstanceRef param_17 = BinInstance_index(param_14, param_15); + BinInstance inst = BinInstance_read(param_16, param_17); sh_elements[th_ix] = inst.element_ix; } GroupMemoryBarrierWithGroupSync(); wr_ix = min((rd_ix + 256u), ready_ix); - bool _1373 = (wr_ix - rd_ix) < 256u; - if (_1373) + bool _1364 = (wr_ix - rd_ix) < 256u; + if (_1364) { - _1383 = (wr_ix < ready_ix) || (partition_ix < n_partitions); + _1374 = (wr_ix < ready_ix) || (partition_ix < n_partitions); } else { - _1383 = _1373; + _1374 = _1364; } - if (_1383) + if (_1374) { continue; } @@ -831,7 +836,7 @@ void comp_main() if ((th_ix + rd_ix) < wr_ix) { element_ix = sh_elements[th_ix]; - tag = _1399.Load((drawtag_start + element_ix) * 4 + 0); + tag = _1390.Load((drawtag_start + element_ix) * 4 + 0); } switch (tag) { @@ -843,13 +848,13 @@ void comp_main() case 37u: { uint drawmonoid_base = drawmonoid_start + (4u * element_ix); - uint path_ix = _266.Load(drawmonoid_base * 4 + 8); - PathRef _1424 = { _1020.Load(16) + (path_ix * 12u) }; - Alloc _1427; - _1427.offset = _1020.Load(16); - param_17.offset = _1427.offset; - PathRef param_18 = _1424; - Path path = Path_read(param_17, param_18); + uint path_ix = _267.Load(drawmonoid_base * 4 + 12); + PathRef _1415 = { _891.Load(20) + (path_ix * 12u) }; + Alloc _1418; + _1418.offset = _891.Load(20); + param_18.offset = _1418.offset; + PathRef param_19 = _1415; + Path path = Path_read(param_18, param_19); uint stride = path.bbox.z - path.bbox.x; sh_tile_stride[th_ix] = stride; int dx = int(path.bbox.x) - int(bin_tile_x); @@ -864,13 +869,13 @@ void comp_main() tile_count = uint(x1 - x0) * uint(y1 - y0); uint base = path.tiles.offset - (((uint(dy) * stride) + uint(dx)) * 8u); sh_tile_base[th_ix] = base; - uint param_19 = path.tiles.offset; - uint param_20 = ((path.bbox.z - path.bbox.x) * (path.bbox.w - path.bbox.y)) * 8u; - bool param_21 = mem_ok; - Alloc path_alloc = new_alloc(param_19, param_20, param_21); - uint param_22 = th_ix; - Alloc param_23 = path_alloc; - write_tile_alloc(param_22, param_23); + uint param_20 = path.tiles.offset; + uint param_21 = ((path.bbox.z - path.bbox.x) * (path.bbox.w - path.bbox.y)) * 8u; + bool param_22 = true; + Alloc path_alloc = new_alloc(param_20, param_21, param_22); + uint param_23 = th_ix; + Alloc param_24 = path_alloc; + write_tile_alloc(param_23, param_24); break; } default: @@ -904,62 +909,59 @@ void comp_main() } } uint element_ix_1 = sh_elements[el_ix]; - uint tag_1 = _1399.Load((drawtag_start + element_ix_1) * 4 + 0); + uint tag_1 = _1390.Load((drawtag_start + element_ix_1) * 4 + 0); if (el_ix > 0u) { - _1632 = sh_tile_count[el_ix - 1u]; + _1622 = sh_tile_count[el_ix - 1u]; } else { - _1632 = 0u; + _1622 = 0u; } - uint seq_ix = ix_1 - _1632; + uint seq_ix = ix_1 - _1622; 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); bool include_tile = false; - if (mem_ok) + uint param_25 = el_ix; + bool param_26 = true; + TileRef _1670 = { sh_tile_base[el_ix] + (((sh_tile_stride[el_ix] * y) + x) * 8u) }; + Alloc param_27 = read_tile_alloc(param_25, param_26); + TileRef param_28 = _1670; + Tile tile = Tile_read(param_27, param_28); + bool is_clip = (tag_1 & 1u) != 0u; + bool is_blend = false; + if (is_clip) { - uint param_24 = el_ix; - bool param_25 = mem_ok; - TileRef _1684 = { sh_tile_base[el_ix] + (((sh_tile_stride[el_ix] * y) + x) * 8u) }; - Alloc param_26 = read_tile_alloc(param_24, param_25); - TileRef param_27 = _1684; - Tile tile = Tile_read(param_26, param_27); - 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 = _266.Load((drawmonoid_base_1 + 2u) * 4 + 8); - uint dd = drawdata_start + (scene_offset >> uint(2)); - uint blend = _1399.Load(dd * 4 + 0); - is_blend = blend != 32771u; - } - bool _1720 = tile.tile.offset != 0u; - bool _1729; - if (!_1720) - { - _1729 = (tile.backdrop == 0) == is_clip; - } - else - { - _1729 = _1720; - } - include_tile = _1729 || is_blend; + uint drawmonoid_base_1 = drawmonoid_start + (4u * element_ix_1); + uint scene_offset = _267.Load((drawmonoid_base_1 + 2u) * 4 + 12); + uint dd = drawdata_start + (scene_offset >> uint(2)); + uint blend = _1390.Load(dd * 4 + 0); + is_blend = blend != 32771u; } + bool _1706 = tile.tile.offset != 0u; + bool _1715; + if (!_1706) + { + _1715 = (tile.backdrop == 0) == is_clip; + } + else + { + _1715 = _1706; + } + include_tile = _1715 || is_blend; if (include_tile) { uint el_slice = el_ix / 32u; uint el_mask = 1u << (el_ix & 31u); - uint _1751; - InterlockedOr(sh_bitmaps[el_slice][(y * 16u) + x], el_mask, _1751); + uint _1737; + InterlockedOr(sh_bitmaps[el_slice][(y * 16u) + x], el_mask, _1737); } } GroupMemoryBarrierWithGroupSync(); uint slice_ix = 0u; uint bitmap = sh_bitmaps[0][th_ix]; - while (mem_ok) + while (true) { if (bitmap == 0u) { @@ -977,178 +979,173 @@ 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 = _1399.Load((drawtag_start + element_ix_2) * 4 + 0); + uint drawtag = _1390.Load((drawtag_start + element_ix_2) * 4 + 0); if (clip_zero_depth == 0u) { - uint param_28 = element_ref_ix; - bool param_29 = mem_ok; - TileRef _1828 = { sh_tile_base[element_ref_ix] + (((sh_tile_stride[element_ref_ix] * tile_y) + tile_x) * 8u) }; - Alloc param_30 = read_tile_alloc(param_28, param_29); - TileRef param_31 = _1828; - Tile tile_1 = Tile_read(param_30, param_31); + uint param_29 = element_ref_ix; + bool param_30 = true; + TileRef _1812 = { sh_tile_base[element_ref_ix] + (((sh_tile_stride[element_ref_ix] * tile_y) + tile_x) * 8u) }; + Alloc param_31 = read_tile_alloc(param_29, param_30); + TileRef param_32 = _1812; + Tile tile_1 = Tile_read(param_31, param_32); uint drawmonoid_base_2 = drawmonoid_start + (4u * element_ix_2); - uint scene_offset_1 = _266.Load((drawmonoid_base_2 + 2u) * 4 + 8); - uint info_offset = _266.Load((drawmonoid_base_2 + 3u) * 4 + 8); + uint scene_offset_1 = _267.Load((drawmonoid_base_2 + 2u) * 4 + 12); + uint info_offset = _267.Load((drawmonoid_base_2 + 3u) * 4 + 12); uint dd_1 = drawdata_start + (scene_offset_1 >> uint(2)); uint di = drawinfo_start + (info_offset >> uint(2)); switch (drawtag) { case 68u: { - linewidth = asfloat(_266.Load(di * 4 + 8)); - Alloc param_32 = cmd_alloc; - CmdRef param_33 = cmd_ref; - uint param_34 = cmd_limit; - bool _1876 = alloc_cmd(param_32, param_33, param_34); - cmd_alloc = param_32; - cmd_ref = param_33; - cmd_limit = param_34; - if (!_1876) + linewidth = asfloat(_267.Load(di * 4 + 12)); + Alloc param_33 = cmd_alloc; + CmdRef param_34 = cmd_ref; + uint param_35 = cmd_limit; + alloc_cmd(param_33, param_34, param_35); + cmd_alloc = param_33; + cmd_ref = param_34; + cmd_limit = param_35; + Alloc param_36 = cmd_alloc; + CmdRef param_37 = cmd_ref; + Tile param_38 = tile_1; + float param_39 = linewidth; + write_fill(param_36, param_37, param_38, param_39); + cmd_ref = param_37; + uint rgba = _1390.Load(dd_1 * 4 + 0); + if (mem_ok) { - break; + CmdColor _1882 = { rgba }; + Alloc param_40 = cmd_alloc; + CmdRef param_41 = cmd_ref; + CmdColor param_42 = _1882; + Cmd_Color_write(param_40, param_41, param_42); } - Alloc param_35 = cmd_alloc; - CmdRef param_36 = cmd_ref; - Tile param_37 = tile_1; - float param_38 = linewidth; - write_fill(param_35, param_36, param_37, param_38); - cmd_ref = param_36; - uint rgba = _1399.Load(dd_1 * 4 + 0); - CmdColor _1899 = { rgba }; - Alloc param_39 = cmd_alloc; - CmdRef param_40 = cmd_ref; - CmdColor param_41 = _1899; - Cmd_Color_write(param_39, param_40, param_41); cmd_ref.offset += 8u; break; } case 276u: { - Alloc param_42 = cmd_alloc; - CmdRef param_43 = cmd_ref; - uint param_44 = cmd_limit; - bool _1917 = alloc_cmd(param_42, param_43, param_44); - cmd_alloc = param_42; - cmd_ref = param_43; - cmd_limit = param_44; - if (!_1917) + Alloc param_43 = cmd_alloc; + CmdRef param_44 = cmd_ref; + uint param_45 = cmd_limit; + alloc_cmd(param_43, param_44, param_45); + cmd_alloc = param_43; + cmd_ref = param_44; + cmd_limit = param_45; + linewidth = asfloat(_267.Load(di * 4 + 12)); + Alloc param_46 = cmd_alloc; + CmdRef param_47 = cmd_ref; + Tile param_48 = tile_1; + float param_49 = linewidth; + write_fill(param_46, param_47, param_48, param_49); + cmd_ref = param_47; + cmd_lin.index = _1390.Load(dd_1 * 4 + 0); + cmd_lin.line_x = asfloat(_267.Load((di + 1u) * 4 + 12)); + cmd_lin.line_y = asfloat(_267.Load((di + 2u) * 4 + 12)); + cmd_lin.line_c = asfloat(_267.Load((di + 3u) * 4 + 12)); + if (mem_ok) { - break; + Alloc param_50 = cmd_alloc; + CmdRef param_51 = cmd_ref; + CmdLinGrad param_52 = cmd_lin; + Cmd_LinGrad_write(param_50, param_51, param_52); } - linewidth = asfloat(_266.Load(di * 4 + 8)); - Alloc param_45 = cmd_alloc; - CmdRef param_46 = cmd_ref; - Tile param_47 = tile_1; - float param_48 = linewidth; - write_fill(param_45, param_46, param_47, param_48); - cmd_ref = param_46; - cmd_lin.index = _1399.Load(dd_1 * 4 + 0); - cmd_lin.line_x = asfloat(_266.Load((di + 1u) * 4 + 8)); - cmd_lin.line_y = asfloat(_266.Load((di + 2u) * 4 + 8)); - cmd_lin.line_c = asfloat(_266.Load((di + 3u) * 4 + 8)); - Alloc param_49 = cmd_alloc; - CmdRef param_50 = cmd_ref; - CmdLinGrad param_51 = cmd_lin; - Cmd_LinGrad_write(param_49, param_50, param_51); cmd_ref.offset += 20u; break; } case 732u: { - Alloc param_52 = cmd_alloc; - CmdRef param_53 = cmd_ref; - uint param_54 = cmd_limit; - bool _1981 = alloc_cmd(param_52, param_53, param_54); - cmd_alloc = param_52; - cmd_ref = param_53; - cmd_limit = param_54; - if (!_1981) + Alloc param_53 = cmd_alloc; + CmdRef param_54 = cmd_ref; + uint param_55 = cmd_limit; + alloc_cmd(param_53, param_54, param_55); + cmd_alloc = param_53; + cmd_ref = param_54; + cmd_limit = param_55; + linewidth = asfloat(_267.Load(di * 4 + 12)); + Alloc param_56 = cmd_alloc; + CmdRef param_57 = cmd_ref; + Tile param_58 = tile_1; + float param_59 = linewidth; + write_fill(param_56, param_57, param_58, param_59); + cmd_ref = param_57; + cmd_rad.index = _1390.Load(dd_1 * 4 + 0); + cmd_rad.mat = asfloat(uint4(_267.Load((di + 1u) * 4 + 12), _267.Load((di + 2u) * 4 + 12), _267.Load((di + 3u) * 4 + 12), _267.Load((di + 4u) * 4 + 12))); + cmd_rad.xlat = asfloat(uint2(_267.Load((di + 5u) * 4 + 12), _267.Load((di + 6u) * 4 + 12))); + cmd_rad.c1 = asfloat(uint2(_267.Load((di + 7u) * 4 + 12), _267.Load((di + 8u) * 4 + 12))); + cmd_rad.ra = asfloat(_267.Load((di + 9u) * 4 + 12)); + cmd_rad.roff = asfloat(_267.Load((di + 10u) * 4 + 12)); + if (mem_ok) { - break; + Alloc param_60 = cmd_alloc; + CmdRef param_61 = cmd_ref; + CmdRadGrad param_62 = cmd_rad; + Cmd_RadGrad_write(param_60, param_61, param_62); } - linewidth = asfloat(_266.Load(di * 4 + 8)); - Alloc param_55 = cmd_alloc; - CmdRef param_56 = cmd_ref; - Tile param_57 = tile_1; - float param_58 = linewidth; - write_fill(param_55, param_56, param_57, param_58); - cmd_ref = param_56; - cmd_rad.index = _1399.Load(dd_1 * 4 + 0); - cmd_rad.mat = asfloat(uint4(_266.Load((di + 1u) * 4 + 8), _266.Load((di + 2u) * 4 + 8), _266.Load((di + 3u) * 4 + 8), _266.Load((di + 4u) * 4 + 8))); - cmd_rad.xlat = asfloat(uint2(_266.Load((di + 5u) * 4 + 8), _266.Load((di + 6u) * 4 + 8))); - cmd_rad.c1 = asfloat(uint2(_266.Load((di + 7u) * 4 + 8), _266.Load((di + 8u) * 4 + 8))); - cmd_rad.ra = asfloat(_266.Load((di + 9u) * 4 + 8)); - cmd_rad.roff = asfloat(_266.Load((di + 10u) * 4 + 8)); - Alloc param_59 = cmd_alloc; - CmdRef param_60 = cmd_ref; - CmdRadGrad param_61 = cmd_rad; - Cmd_RadGrad_write(param_59, param_60, param_61); cmd_ref.offset += 48u; break; } case 72u: { - linewidth = asfloat(_266.Load(di * 4 + 8)); - Alloc param_62 = cmd_alloc; - CmdRef param_63 = cmd_ref; - uint param_64 = cmd_limit; - bool _2087 = alloc_cmd(param_62, param_63, param_64); - cmd_alloc = param_62; - cmd_ref = param_63; - cmd_limit = param_64; - if (!_2087) - { - break; - } - Alloc param_65 = cmd_alloc; - CmdRef param_66 = cmd_ref; - Tile param_67 = tile_1; - float param_68 = linewidth; - write_fill(param_65, param_66, param_67, param_68); - cmd_ref = param_66; - uint index = _1399.Load(dd_1 * 4 + 0); - uint raw1 = _1399.Load((dd_1 + 1u) * 4 + 0); + Alloc param_63 = cmd_alloc; + CmdRef param_64 = cmd_ref; + uint param_65 = cmd_limit; + alloc_cmd(param_63, param_64, param_65); + cmd_alloc = param_63; + cmd_ref = param_64; + cmd_limit = param_65; + linewidth = asfloat(_267.Load(di * 4 + 12)); + Alloc param_66 = cmd_alloc; + CmdRef param_67 = cmd_ref; + Tile param_68 = tile_1; + float param_69 = linewidth; + write_fill(param_66, param_67, param_68, param_69); + cmd_ref = param_67; + uint index = _1390.Load(dd_1 * 4 + 0); + uint raw1 = _1390.Load((dd_1 + 1u) * 4 + 0); int2 offset_1 = int2(int(raw1 << uint(16)) >> 16, int(raw1) >> 16); - CmdImage _2126 = { index, offset_1 }; - Alloc param_69 = cmd_alloc; - CmdRef param_70 = cmd_ref; - CmdImage param_71 = _2126; - Cmd_Image_write(param_69, param_70, param_71); + if (mem_ok) + { + CmdImage _2106 = { index, offset_1 }; + Alloc param_70 = cmd_alloc; + CmdRef param_71 = cmd_ref; + CmdImage param_72 = _2106; + Cmd_Image_write(param_70, param_71, param_72); + } cmd_ref.offset += 12u; break; } case 5u: { - bool _2140 = tile_1.tile.offset == 0u; - bool _2146; - if (_2140) + bool _2120 = tile_1.tile.offset == 0u; + bool _2126; + if (_2120) { - _2146 = tile_1.backdrop == 0; + _2126 = tile_1.backdrop == 0; } else { - _2146 = _2140; + _2126 = _2120; } - if (_2146) + if (_2126) { clip_zero_depth = clip_depth + 1u; } else { - Alloc param_72 = cmd_alloc; - CmdRef param_73 = cmd_ref; - uint param_74 = cmd_limit; - bool _2158 = alloc_cmd(param_72, param_73, param_74); - cmd_alloc = param_72; - cmd_ref = param_73; - cmd_limit = param_74; - if (!_2158) + Alloc param_73 = cmd_alloc; + CmdRef param_74 = cmd_ref; + uint param_75 = cmd_limit; + alloc_cmd(param_73, param_74, param_75); + cmd_alloc = param_73; + cmd_ref = param_74; + cmd_limit = param_75; + if (mem_ok) { - break; + Alloc param_76 = cmd_alloc; + CmdRef param_77 = cmd_ref; + Cmd_BeginClip_write(param_76, param_77); } - Alloc param_75 = cmd_alloc; - CmdRef param_76 = cmd_ref; - Cmd_BeginClip_write(param_75, param_76); cmd_ref.offset += 4u; render_blend_depth++; max_blend_depth = max(max_blend_depth, render_blend_depth); @@ -1159,29 +1156,21 @@ void comp_main() case 37u: { clip_depth--; - Alloc param_77 = cmd_alloc; - CmdRef param_78 = cmd_ref; - uint param_79 = cmd_limit; - bool _2191 = alloc_cmd(param_77, param_78, param_79); - cmd_alloc = param_77; - cmd_ref = param_78; - cmd_limit = param_79; - if (!_2191) + Alloc param_78 = cmd_alloc; + CmdRef param_79 = cmd_ref; + Tile param_80 = tile_1; + float param_81 = -1.0f; + write_fill(param_78, param_79, param_80, param_81); + cmd_ref = param_79; + uint blend_1 = _1390.Load(dd_1 * 4 + 0); + if (mem_ok) { - break; + CmdEndClip _2182 = { blend_1 }; + Alloc param_82 = cmd_alloc; + CmdRef param_83 = cmd_ref; + CmdEndClip param_84 = _2182; + Cmd_EndClip_write(param_82, param_83, param_84); } - Alloc param_80 = cmd_alloc; - CmdRef param_81 = cmd_ref; - Tile param_82 = tile_1; - float param_83 = -1.0f; - write_fill(param_80, param_81, param_82, param_83); - cmd_ref = param_81; - uint blend_1 = _1399.Load(dd_1 * 4 + 0); - CmdEndClip _2214 = { blend_1 }; - Alloc param_84 = cmd_alloc; - CmdRef param_85 = cmd_ref; - CmdEndClip param_86 = _2214; - Cmd_EndClip_write(param_84, param_85, param_86); cmd_ref.offset += 8u; render_blend_depth--; break; @@ -1216,31 +1205,34 @@ void comp_main() break; } } - bool _2263 = (bin_tile_x + tile_x) < _1020.Load(8); - bool _2272; - if (_2263) + bool _2231 = (bin_tile_x + tile_x) < _891.Load(12); + bool _2240; + if (_2231) { - _2272 = (bin_tile_y + tile_y) < _1020.Load(12); + _2240 = (bin_tile_y + tile_y) < _891.Load(16); } else { - _2272 = _2263; + _2240 = _2231; } - if (_2272) + if (_2240) { - Alloc param_87 = cmd_alloc; - CmdRef param_88 = cmd_ref; - Cmd_End_write(param_87, param_88); + if (mem_ok) + { + Alloc param_85 = cmd_alloc; + CmdRef param_86 = cmd_ref; + Cmd_End_write(param_85, param_86); + } if (max_blend_depth > 4u) { uint scratch_size = (((max_blend_depth * 16u) * 16u) * 1u) * 4u; - uint param_89 = scratch_size; - MallocResult _2293 = malloc(param_89); - MallocResult scratch = _2293; - Alloc param_90 = scratch_alloc; - uint param_91 = scratch_alloc.offset; - Alloc param_92 = scratch.alloc; - alloc_write(param_90, param_91, param_92); + uint _2264; + _267.InterlockedAdd(8, scratch_size, _2264); + uint scratch = _2264; + Alloc param_87 = scratch_alloc; + uint param_88 = scratch_alloc.offset >> uint(2); + uint param_89 = scratch; + write_mem(param_87, param_88, param_89); } } } diff --git a/piet-gpu/shader/gen/coarse.msl b/piet-gpu/shader/gen/coarse.msl index d84add1..5df99b9 100644 --- a/piet-gpu/shader/gen/coarse.msl +++ b/piet-gpu/shader/gen/coarse.msl @@ -19,12 +19,6 @@ struct Alloc uint offset; }; -struct MallocResult -{ - Alloc alloc; - bool failed; -}; - struct BinInstanceRef { uint offset; @@ -162,6 +156,7 @@ struct Memory { uint mem_offset; uint mem_error; + uint blend_offset; uint memory[1]; }; @@ -172,6 +167,7 @@ struct Alloc_1 struct Config { + uint mem_size; uint n_elements; uint n_pathseg; uint width_in_tiles; @@ -213,6 +209,13 @@ struct SceneBuf constant uint3 gl_WorkGroupSize [[maybe_unused]] = uint3(256u, 1u, 1u); +static inline __attribute__((always_inline)) +bool check_deps(thread const uint& dep_stage, device Memory& v_267) +{ + uint _273 = atomic_fetch_or_explicit((device atomic_uint*)&v_267.mem_error, 0u, memory_order_relaxed); + return (_273 & dep_stage) == 0u; +} + static inline __attribute__((always_inline)) Alloc slice_mem(thread const Alloc& a, thread const uint& offset, thread const uint& size) { @@ -226,7 +229,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_266, constant uint& v_266BufferSize) +uint read_mem(thread const Alloc& alloc, thread const uint& offset, device Memory& v_267) { Alloc param = alloc; uint param_1 = offset; @@ -234,7 +237,7 @@ uint read_mem(thread const Alloc& alloc, thread const uint& offset, device Memor { return 0u; } - uint v = v_266.memory[offset]; + uint v = v_267.memory[offset]; return v; } @@ -253,30 +256,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_266, constant uint& v_266BufferSize) +BinInstance BinInstance_read(thread const Alloc& a, thread const BinInstanceRef& ref, device Memory& v_267) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; - uint raw0 = read_mem(param, param_1, v_266, v_266BufferSize); + uint raw0 = read_mem(param, param_1, v_267); 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_266, constant uint& v_266BufferSize) +Path Path_read(thread const Alloc& a, thread const PathRef& ref, device Memory& v_267) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; - uint raw0 = read_mem(param, param_1, v_266, v_266BufferSize); + uint raw0 = read_mem(param, param_1, v_267); Alloc param_2 = a; uint param_3 = ix + 1u; - uint raw1 = read_mem(param_2, param_3, v_266, v_266BufferSize); + uint raw1 = read_mem(param_2, param_3, v_267); Alloc param_4 = a; uint param_5 = ix + 2u; - uint raw2 = read_mem(param_4, param_5, v_266, v_266BufferSize); + uint raw2 = read_mem(param_4, param_5, v_267); Path s; s.bbox = uint4(raw0 & 65535u, raw0 >> uint(16), raw1 & 65535u, raw1 >> uint(16)); s.tiles = TileRef{ raw2 }; @@ -289,24 +292,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_266, constant uint& v_266BufferSize) +Alloc read_tile_alloc(thread const uint& el_ix, thread const bool& mem_ok, const device ConfigBuf& v_891) { uint param = 0u; - uint param_1 = uint(int((v_266BufferSize - 8) / 4) * 4); + uint param_1 = v_891.conf.mem_size; 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_266, constant uint& v_266BufferSize) +Tile Tile_read(thread const Alloc& a, thread const TileRef& ref, device Memory& v_267) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; - uint raw0 = read_mem(param, param_1, v_266, v_266BufferSize); + uint raw0 = read_mem(param, param_1, v_267); Alloc param_2 = a; uint param_3 = ix + 1u; - uint raw1 = read_mem(param_2, param_3, v_266, v_266BufferSize); + uint raw1 = read_mem(param_2, param_3, v_267); Tile s; s.tile = TileSegRef{ raw0 }; s.backdrop = int(raw1); @@ -314,26 +317,20 @@ 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_266, constant uint& v_266BufferSize) +uint malloc_stage(thread const uint& size, thread const uint& mem_size, thread const uint& stage, device Memory& v_267) { - uint _272 = atomic_fetch_add_explicit((device atomic_uint*)&v_266.mem_offset, size, memory_order_relaxed); - uint offset = _272; - MallocResult r; - r.failed = (offset + size) > uint(int((v_266BufferSize - 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 _282 = atomic_fetch_add_explicit((device atomic_uint*)&v_267.mem_offset, size, memory_order_relaxed); + uint offset = _282; + if ((offset + size) > mem_size) { - uint _301 = atomic_fetch_max_explicit((device atomic_uint*)&v_266.mem_error, 1u, memory_order_relaxed); - return r; + uint _292 = atomic_fetch_or_explicit((device atomic_uint*)&v_267.mem_error, stage, memory_order_relaxed); + offset = 0u; } - return r; + return offset; } static inline __attribute__((always_inline)) -void write_mem(thread const Alloc& alloc, thread const uint& offset, thread const uint& val, device Memory& v_266, constant uint& v_266BufferSize) +void write_mem(thread const Alloc& alloc, thread const uint& offset, thread const uint& val, device Memory& v_267) { Alloc param = alloc; uint param_1 = offset; @@ -341,352 +338,359 @@ void write_mem(thread const Alloc& alloc, thread const uint& offset, thread cons { return; } - v_266.memory[offset] = val; + v_267.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_266, constant uint& v_266BufferSize) +void CmdJump_write(thread const Alloc& a, thread const CmdJumpRef& ref, thread const CmdJump& s, device Memory& v_267) { 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_266, v_266BufferSize); + write_mem(param, param_1, param_2, v_267); } static inline __attribute__((always_inline)) -void Cmd_Jump_write(thread const Alloc& a, thread const CmdRef& ref, thread const CmdJump& s, device Memory& v_266, constant uint& v_266BufferSize) +void Cmd_Jump_write(thread const Alloc& a, thread const CmdRef& ref, thread const CmdJump& s, device Memory& v_267) { Alloc param = a; uint param_1 = ref.offset >> uint(2); uint param_2 = 11u; - write_mem(param, param_1, param_2, v_266, v_266BufferSize); + write_mem(param, param_1, param_2, v_267); Alloc param_3 = a; CmdJumpRef param_4 = CmdJumpRef{ ref.offset + 4u }; CmdJump param_5 = s; - CmdJump_write(param_3, param_4, param_5, v_266, v_266BufferSize); + CmdJump_write(param_3, param_4, param_5, v_267); } static inline __attribute__((always_inline)) -bool alloc_cmd(thread Alloc& cmd_alloc, thread CmdRef& cmd_ref, thread uint& cmd_limit, device Memory& v_266, constant uint& v_266BufferSize) +void alloc_cmd(thread Alloc& cmd_alloc, thread CmdRef& cmd_ref, thread uint& cmd_limit, thread bool& mem_ok, device Memory& v_267, const device ConfigBuf& v_891) { if (cmd_ref.offset < cmd_limit) { - return true; + return; } uint param = 1024u; - MallocResult _928 = malloc(param, v_266, v_266BufferSize); - MallocResult new_cmd = _928; - if (new_cmd.failed) + uint param_1 = v_891.conf.mem_size; + uint param_2 = 8u; + uint _915 = malloc_stage(param, param_1, param_2, v_267); + uint new_cmd = _915; + if (new_cmd == 0u) { - return false; + mem_ok = false; } - CmdJump jump = CmdJump{ new_cmd.alloc.offset }; - Alloc param_1 = cmd_alloc; - CmdRef param_2 = cmd_ref; - CmdJump param_3 = jump; - Cmd_Jump_write(param_1, param_2, param_3, v_266, v_266BufferSize); - cmd_alloc = new_cmd.alloc; - cmd_ref = CmdRef{ cmd_alloc.offset }; - cmd_limit = (cmd_alloc.offset + 1024u) - 144u; - return true; + if (mem_ok) + { + CmdJump jump = CmdJump{ new_cmd }; + Alloc param_3 = cmd_alloc; + CmdRef param_4 = cmd_ref; + CmdJump param_5 = jump; + Cmd_Jump_write(param_3, param_4, param_5, v_267); + } + uint param_6 = new_cmd; + uint param_7 = 1024u; + bool param_8 = true; + cmd_alloc = new_alloc(param_6, param_7, param_8); + cmd_ref = CmdRef{ new_cmd }; + cmd_limit = (new_cmd + 1024u) - 144u; } static inline __attribute__((always_inline)) -void CmdFill_write(thread const Alloc& a, thread const CmdFillRef& ref, thread const CmdFill& s, device Memory& v_266, constant uint& v_266BufferSize) +void CmdFill_write(thread const Alloc& a, thread const CmdFillRef& ref, thread const CmdFill& s, device Memory& v_267) { 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_266, v_266BufferSize); + write_mem(param, param_1, param_2, v_267); Alloc param_3 = a; uint param_4 = ix + 1u; uint param_5 = uint(s.backdrop); - write_mem(param_3, param_4, param_5, v_266, v_266BufferSize); + write_mem(param_3, param_4, param_5, v_267); } static inline __attribute__((always_inline)) -void Cmd_Fill_write(thread const Alloc& a, thread const CmdRef& ref, thread const CmdFill& s, device Memory& v_266, constant uint& v_266BufferSize) +void Cmd_Fill_write(thread const Alloc& a, thread const CmdRef& ref, thread const CmdFill& s, device Memory& v_267) { Alloc param = a; uint param_1 = ref.offset >> uint(2); uint param_2 = 1u; - write_mem(param, param_1, param_2, v_266, v_266BufferSize); + write_mem(param, param_1, param_2, v_267); Alloc param_3 = a; CmdFillRef param_4 = CmdFillRef{ ref.offset + 4u }; CmdFill param_5 = s; - CmdFill_write(param_3, param_4, param_5, v_266, v_266BufferSize); + CmdFill_write(param_3, param_4, param_5, v_267); } static inline __attribute__((always_inline)) -void Cmd_Solid_write(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_266, constant uint& v_266BufferSize) +void Cmd_Solid_write(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_267) { Alloc param = a; uint param_1 = ref.offset >> uint(2); uint param_2 = 3u; - write_mem(param, param_1, param_2, v_266, v_266BufferSize); + write_mem(param, param_1, param_2, v_267); } static inline __attribute__((always_inline)) -void CmdStroke_write(thread const Alloc& a, thread const CmdStrokeRef& ref, thread const CmdStroke& s, device Memory& v_266, constant uint& v_266BufferSize) +void CmdStroke_write(thread const Alloc& a, thread const CmdStrokeRef& ref, thread const CmdStroke& s, device Memory& v_267) { 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_266, v_266BufferSize); + write_mem(param, param_1, param_2, v_267); 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_266, v_266BufferSize); + write_mem(param_3, param_4, param_5, v_267); } static inline __attribute__((always_inline)) -void Cmd_Stroke_write(thread const Alloc& a, thread const CmdRef& ref, thread const CmdStroke& s, device Memory& v_266, constant uint& v_266BufferSize) +void Cmd_Stroke_write(thread const Alloc& a, thread const CmdRef& ref, thread const CmdStroke& s, device Memory& v_267) { Alloc param = a; uint param_1 = ref.offset >> uint(2); uint param_2 = 2u; - write_mem(param, param_1, param_2, v_266, v_266BufferSize); + write_mem(param, param_1, param_2, v_267); Alloc param_3 = a; CmdStrokeRef param_4 = CmdStrokeRef{ ref.offset + 4u }; CmdStroke param_5 = s; - CmdStroke_write(param_3, param_4, param_5, v_266, v_266BufferSize); + CmdStroke_write(param_3, param_4, param_5, v_267); } 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_266, constant uint& v_266BufferSize) +void write_fill(thread const Alloc& alloc, thread CmdRef& cmd_ref, thread const Tile& tile, thread const float& linewidth, thread bool& mem_ok, device Memory& v_267) { if (linewidth < 0.0) { if (tile.tile.offset != 0u) { CmdFill cmd_fill = CmdFill{ tile.tile.offset, tile.backdrop }; - Alloc param = alloc; - CmdRef param_1 = cmd_ref; - CmdFill param_2 = cmd_fill; - Cmd_Fill_write(param, param_1, param_2, v_266, v_266BufferSize); + if (mem_ok) + { + Alloc param = alloc; + CmdRef param_1 = cmd_ref; + CmdFill param_2 = cmd_fill; + Cmd_Fill_write(param, param_1, param_2, v_267); + } cmd_ref.offset += 12u; } else { - Alloc param_3 = alloc; - CmdRef param_4 = cmd_ref; - Cmd_Solid_write(param_3, param_4, v_266, v_266BufferSize); + if (mem_ok) + { + Alloc param_3 = alloc; + CmdRef param_4 = cmd_ref; + Cmd_Solid_write(param_3, param_4, v_267); + } cmd_ref.offset += 4u; } } else { CmdStroke cmd_stroke = CmdStroke{ tile.tile.offset, 0.5 * linewidth }; - Alloc param_5 = alloc; - CmdRef param_6 = cmd_ref; - CmdStroke param_7 = cmd_stroke; - Cmd_Stroke_write(param_5, param_6, param_7, v_266, v_266BufferSize); + if (mem_ok) + { + Alloc param_5 = alloc; + CmdRef param_6 = cmd_ref; + CmdStroke param_7 = cmd_stroke; + Cmd_Stroke_write(param_5, param_6, param_7, v_267); + } 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_266, constant uint& v_266BufferSize) +void CmdColor_write(thread const Alloc& a, thread const CmdColorRef& ref, thread const CmdColor& s, device Memory& v_267) { 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_266, v_266BufferSize); + write_mem(param, param_1, param_2, v_267); } static inline __attribute__((always_inline)) -void Cmd_Color_write(thread const Alloc& a, thread const CmdRef& ref, thread const CmdColor& s, device Memory& v_266, constant uint& v_266BufferSize) +void Cmd_Color_write(thread const Alloc& a, thread const CmdRef& ref, thread const CmdColor& s, device Memory& v_267) { Alloc param = a; uint param_1 = ref.offset >> uint(2); uint param_2 = 5u; - write_mem(param, param_1, param_2, v_266, v_266BufferSize); + write_mem(param, param_1, param_2, v_267); Alloc param_3 = a; CmdColorRef param_4 = CmdColorRef{ ref.offset + 4u }; CmdColor param_5 = s; - CmdColor_write(param_3, param_4, param_5, v_266, v_266BufferSize); + CmdColor_write(param_3, param_4, param_5, v_267); } static inline __attribute__((always_inline)) -void CmdLinGrad_write(thread const Alloc& a, thread const CmdLinGradRef& ref, thread const CmdLinGrad& s, device Memory& v_266, constant uint& v_266BufferSize) +void CmdLinGrad_write(thread const Alloc& a, thread const CmdLinGradRef& ref, thread const CmdLinGrad& s, device Memory& v_267) { 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_266, v_266BufferSize); + write_mem(param, param_1, param_2, v_267); 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_266, v_266BufferSize); + write_mem(param_3, param_4, param_5, v_267); 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_266, v_266BufferSize); + write_mem(param_6, param_7, param_8, v_267); 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_266, v_266BufferSize); + write_mem(param_9, param_10, param_11, v_267); } static inline __attribute__((always_inline)) -void Cmd_LinGrad_write(thread const Alloc& a, thread const CmdRef& ref, thread const CmdLinGrad& s, device Memory& v_266, constant uint& v_266BufferSize) +void Cmd_LinGrad_write(thread const Alloc& a, thread const CmdRef& ref, thread const CmdLinGrad& s, device Memory& v_267) { Alloc param = a; uint param_1 = ref.offset >> uint(2); uint param_2 = 6u; - write_mem(param, param_1, param_2, v_266, v_266BufferSize); + write_mem(param, param_1, param_2, v_267); Alloc param_3 = a; CmdLinGradRef param_4 = CmdLinGradRef{ ref.offset + 4u }; CmdLinGrad param_5 = s; - CmdLinGrad_write(param_3, param_4, param_5, v_266, v_266BufferSize); + CmdLinGrad_write(param_3, param_4, param_5, v_267); } static inline __attribute__((always_inline)) -void CmdRadGrad_write(thread const Alloc& a, thread const CmdRadGradRef& ref, thread const CmdRadGrad& s, device Memory& v_266, constant uint& v_266BufferSize) +void CmdRadGrad_write(thread const Alloc& a, thread const CmdRadGradRef& ref, thread const CmdRadGrad& s, device Memory& v_267) { 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_266, v_266BufferSize); + write_mem(param, param_1, param_2, v_267); Alloc param_3 = a; uint param_4 = ix + 1u; uint param_5 = as_type(s.mat.x); - write_mem(param_3, param_4, param_5, v_266, v_266BufferSize); + write_mem(param_3, param_4, param_5, v_267); 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_266, v_266BufferSize); + write_mem(param_6, param_7, param_8, v_267); 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_266, v_266BufferSize); + write_mem(param_9, param_10, param_11, v_267); 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_266, v_266BufferSize); + write_mem(param_12, param_13, param_14, v_267); 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_266, v_266BufferSize); + write_mem(param_15, param_16, param_17, v_267); 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_266, v_266BufferSize); + write_mem(param_18, param_19, param_20, v_267); 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_266, v_266BufferSize); + write_mem(param_21, param_22, param_23, v_267); 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_266, v_266BufferSize); + write_mem(param_24, param_25, param_26, v_267); 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_266, v_266BufferSize); + write_mem(param_27, param_28, param_29, v_267); 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_266, v_266BufferSize); + write_mem(param_30, param_31, param_32, v_267); } static inline __attribute__((always_inline)) -void Cmd_RadGrad_write(thread const Alloc& a, thread const CmdRef& ref, thread const CmdRadGrad& s, device Memory& v_266, constant uint& v_266BufferSize) +void Cmd_RadGrad_write(thread const Alloc& a, thread const CmdRef& ref, thread const CmdRadGrad& s, device Memory& v_267) { Alloc param = a; uint param_1 = ref.offset >> uint(2); uint param_2 = 7u; - write_mem(param, param_1, param_2, v_266, v_266BufferSize); + write_mem(param, param_1, param_2, v_267); Alloc param_3 = a; CmdRadGradRef param_4 = CmdRadGradRef{ ref.offset + 4u }; CmdRadGrad param_5 = s; - CmdRadGrad_write(param_3, param_4, param_5, v_266, v_266BufferSize); + CmdRadGrad_write(param_3, param_4, param_5, v_267); } static inline __attribute__((always_inline)) -void CmdImage_write(thread const Alloc& a, thread const CmdImageRef& ref, thread const CmdImage& s, device Memory& v_266, constant uint& v_266BufferSize) +void CmdImage_write(thread const Alloc& a, thread const CmdImageRef& ref, thread const CmdImage& s, device Memory& v_267) { 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_266, v_266BufferSize); + write_mem(param, param_1, param_2, v_267); 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_266, v_266BufferSize); + write_mem(param_3, param_4, param_5, v_267); } static inline __attribute__((always_inline)) -void Cmd_Image_write(thread const Alloc& a, thread const CmdRef& ref, thread const CmdImage& s, device Memory& v_266, constant uint& v_266BufferSize) +void Cmd_Image_write(thread const Alloc& a, thread const CmdRef& ref, thread const CmdImage& s, device Memory& v_267) { Alloc param = a; uint param_1 = ref.offset >> uint(2); uint param_2 = 8u; - write_mem(param, param_1, param_2, v_266, v_266BufferSize); + write_mem(param, param_1, param_2, v_267); Alloc param_3 = a; CmdImageRef param_4 = CmdImageRef{ ref.offset + 4u }; CmdImage param_5 = s; - CmdImage_write(param_3, param_4, param_5, v_266, v_266BufferSize); + CmdImage_write(param_3, param_4, param_5, v_267); } static inline __attribute__((always_inline)) -void Cmd_BeginClip_write(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_266, constant uint& v_266BufferSize) +void Cmd_BeginClip_write(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_267) { Alloc param = a; uint param_1 = ref.offset >> uint(2); uint param_2 = 9u; - write_mem(param, param_1, param_2, v_266, v_266BufferSize); + write_mem(param, param_1, param_2, v_267); } static inline __attribute__((always_inline)) -void CmdEndClip_write(thread const Alloc& a, thread const CmdEndClipRef& ref, thread const CmdEndClip& s, device Memory& v_266, constant uint& v_266BufferSize) +void CmdEndClip_write(thread const Alloc& a, thread const CmdEndClipRef& ref, thread const CmdEndClip& s, device Memory& v_267) { 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_266, v_266BufferSize); + write_mem(param, param_1, param_2, v_267); } static inline __attribute__((always_inline)) -void Cmd_EndClip_write(thread const Alloc& a, thread const CmdRef& ref, thread const CmdEndClip& s, device Memory& v_266, constant uint& v_266BufferSize) +void Cmd_EndClip_write(thread const Alloc& a, thread const CmdRef& ref, thread const CmdEndClip& s, device Memory& v_267) { Alloc param = a; uint param_1 = ref.offset >> uint(2); uint param_2 = 10u; - write_mem(param, param_1, param_2, v_266, v_266BufferSize); + write_mem(param, param_1, param_2, v_267); Alloc param_3 = a; CmdEndClipRef param_4 = CmdEndClipRef{ ref.offset + 4u }; CmdEndClip param_5 = s; - CmdEndClip_write(param_3, param_4, param_5, v_266, v_266BufferSize); + CmdEndClip_write(param_3, param_4, param_5, v_267); } static inline __attribute__((always_inline)) -void Cmd_End_write(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_266, constant uint& v_266BufferSize) +void Cmd_End_write(thread const Alloc& a, thread const CmdRef& ref, device Memory& v_267) { Alloc param = a; uint param_1 = ref.offset >> uint(2); uint param_2 = 0u; - write_mem(param, param_1, param_2, v_266, v_266BufferSize); + write_mem(param, param_1, param_2, v_267); } -static inline __attribute__((always_inline)) -void alloc_write(thread const Alloc& a, thread const uint& offset, thread const Alloc& alloc, device Memory& v_266, constant uint& v_266BufferSize) -{ - Alloc param = a; - uint param_1 = offset >> uint(2); - uint param_2 = alloc.offset; - write_mem(param, param_1, param_2, v_266, v_266BufferSize); -} - -kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device Memory& v_266 [[buffer(0)]], const device ConfigBuf& _1020 [[buffer(1)]], const device SceneBuf& _1399 [[buffer(2)]], uint3 gl_WorkGroupID [[threadgroup_position_in_grid]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]]) +kernel void main0(device Memory& v_267 [[buffer(0)]], const device ConfigBuf& v_891 [[buffer(1)]], const device SceneBuf& _1390 [[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]; @@ -698,22 +702,28 @@ 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_266BufferSize = spvBufferSizeConstants[0]; - uint width_in_bins = ((_1020.conf.width_in_tiles + 16u) - 1u) / 16u; + bool mem_ok = true; + uint param = 7u; + bool _1012 = check_deps(param, v_267); + if (!_1012) + { + return; + } + uint width_in_bins = ((v_891.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 = ((_1020.conf.n_elements + 256u) - 1u) / 256u; + uint n_partitions = ((v_891.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) * _1020.conf.width_in_tiles) + bin_tile_x) + tile_x; - Alloc param; - param.offset = _1020.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); + uint this_tile_ix = (((bin_tile_y + tile_y) * v_891.conf.width_in_tiles) + bin_tile_x) + tile_x; + Alloc param_1; + param_1.offset = v_891.conf.ptcl_alloc.offset; + uint param_2 = this_tile_ix * 1024u; + uint param_3 = 1024u; + Alloc cmd_alloc = slice_mem(param_1, param_2, param_3); CmdRef cmd_ref = CmdRef{ cmd_alloc.offset }; uint cmd_limit = (cmd_ref.offset + 1024u) - 144u; uint clip_depth = 0u; @@ -722,25 +732,24 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M uint wr_ix = 0u; uint part_start_ix = 0u; uint ready_ix = 0u; - Alloc param_3 = cmd_alloc; - uint param_4 = 0u; - uint param_5 = 8u; - Alloc scratch_alloc = slice_mem(param_3, param_4, param_5); + Alloc param_4 = cmd_alloc; + uint param_5 = 0u; + uint param_6 = 8u; + Alloc scratch_alloc = slice_mem(param_4, param_5, param_6); cmd_ref.offset += 4u; uint render_blend_depth = 0u; uint max_blend_depth = 0u; - uint drawmonoid_start = _1020.conf.drawmonoid_alloc.offset >> uint(2); - uint drawtag_start = _1020.conf.drawtag_offset >> uint(2); - uint drawdata_start = _1020.conf.drawdata_offset >> uint(2); - uint drawinfo_start = _1020.conf.drawinfo_alloc.offset >> uint(2); - bool mem_ok = v_266.mem_error == 0u; - Alloc param_6; - Alloc param_8; - uint _1331; + uint drawmonoid_start = v_891.conf.drawmonoid_alloc.offset >> uint(2); + uint drawtag_start = v_891.conf.drawtag_offset >> uint(2); + uint drawdata_start = v_891.conf.drawdata_offset >> uint(2); + uint drawinfo_start = v_891.conf.drawinfo_alloc.offset >> uint(2); + Alloc param_7; + Alloc param_9; + uint _1322; uint element_ix; - Alloc param_17; + Alloc param_18; uint tile_count; - uint _1632; + uint _1622; float linewidth; CmdLinGrad cmd_lin; CmdRadGrad cmd_rad; @@ -750,36 +759,36 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M { sh_bitmaps[i][th_ix] = 0u; } - bool _1383; + bool _1374; for (;;) { if ((ready_ix == wr_ix) && (partition_ix < n_partitions)) { part_start_ix = ready_ix; uint count = 0u; - bool _1181 = th_ix < 256u; - bool _1189; - if (_1181) + bool _1174 = th_ix < 256u; + bool _1182; + if (_1174) { - _1189 = (partition_ix + th_ix) < n_partitions; + _1182 = (partition_ix + th_ix) < n_partitions; } else { - _1189 = _1181; + _1182 = _1174; } - if (_1189) + if (_1182) { - uint in_ix = (_1020.conf.bin_alloc.offset >> uint(2)) + ((((partition_ix + th_ix) * 256u) + bin_ix) * 2u); - param_6.offset = _1020.conf.bin_alloc.offset; - uint param_7 = in_ix; - count = read_mem(param_6, param_7, v_266, v_266BufferSize); - param_8.offset = _1020.conf.bin_alloc.offset; - uint param_9 = in_ix + 1u; - uint offset = read_mem(param_8, param_9, v_266, v_266BufferSize); - uint param_10 = offset; - uint param_11 = count * 4u; - bool param_12 = mem_ok; - sh_part_elements[th_ix] = new_alloc(param_10, param_11, param_12); + uint in_ix = (v_891.conf.bin_alloc.offset >> uint(2)) + ((((partition_ix + th_ix) * 256u) + bin_ix) * 2u); + param_7.offset = v_891.conf.bin_alloc.offset; + uint param_8 = in_ix; + count = read_mem(param_7, param_8, v_267); + param_9.offset = v_891.conf.bin_alloc.offset; + uint param_10 = in_ix + 1u; + uint offset = read_mem(param_9, param_10, v_267); + uint param_11 = offset; + uint param_12 = count * 4u; + bool param_13 = true; + sh_part_elements[th_ix] = new_alloc(param_11, param_12, param_13); } for (uint i_1 = 0u; i_1 < 8u; i_1++) { @@ -806,7 +815,7 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M partition_ix += 256u; } uint ix = rd_ix + th_ix; - if (((ix >= wr_ix) && (ix < ready_ix)) && mem_ok) + if ((ix >= wr_ix) && (ix < ready_ix)) { uint part_ix = 0u; for (uint i_2 = 0u; i_2 < 8u; i_2++) @@ -819,34 +828,34 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M } if (part_ix > 0u) { - _1331 = sh_part_count[part_ix - 1u]; + _1322 = sh_part_count[part_ix - 1u]; } else { - _1331 = part_start_ix; + _1322 = part_start_ix; } - ix -= _1331; + ix -= _1322; Alloc bin_alloc = sh_part_elements[part_ix]; BinInstanceRef inst_ref = BinInstanceRef{ bin_alloc.offset }; - BinInstanceRef param_13 = inst_ref; - uint param_14 = ix; - Alloc param_15 = bin_alloc; - BinInstanceRef param_16 = BinInstance_index(param_13, param_14); - BinInstance inst = BinInstance_read(param_15, param_16, v_266, v_266BufferSize); + BinInstanceRef param_14 = inst_ref; + uint param_15 = ix; + Alloc param_16 = bin_alloc; + BinInstanceRef param_17 = BinInstance_index(param_14, param_15); + BinInstance inst = BinInstance_read(param_16, param_17, v_267); sh_elements[th_ix] = inst.element_ix; } threadgroup_barrier(mem_flags::mem_threadgroup); wr_ix = min((rd_ix + 256u), ready_ix); - bool _1373 = (wr_ix - rd_ix) < 256u; - if (_1373) + bool _1364 = (wr_ix - rd_ix) < 256u; + if (_1364) { - _1383 = (wr_ix < ready_ix) || (partition_ix < n_partitions); + _1374 = (wr_ix < ready_ix) || (partition_ix < n_partitions); } else { - _1383 = _1373; + _1374 = _1364; } - if (_1383) + if (_1374) { continue; } @@ -859,7 +868,7 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M if ((th_ix + rd_ix) < wr_ix) { element_ix = sh_elements[th_ix]; - tag = _1399.scene[drawtag_start + element_ix]; + tag = _1390.scene[drawtag_start + element_ix]; } switch (tag) { @@ -871,10 +880,10 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M case 37u: { uint drawmonoid_base = drawmonoid_start + (4u * element_ix); - uint path_ix = v_266.memory[drawmonoid_base]; - param_17.offset = _1020.conf.tile_alloc.offset; - PathRef param_18 = PathRef{ _1020.conf.tile_alloc.offset + (path_ix * 12u) }; - Path path = Path_read(param_17, param_18, v_266, v_266BufferSize); + uint path_ix = v_267.memory[drawmonoid_base]; + param_18.offset = v_891.conf.tile_alloc.offset; + PathRef param_19 = PathRef{ v_891.conf.tile_alloc.offset + (path_ix * 12u) }; + Path path = Path_read(param_18, param_19, v_267); uint stride = path.bbox.z - path.bbox.x; sh_tile_stride[th_ix] = stride; int dx = int(path.bbox.x) - int(bin_tile_x); @@ -889,13 +898,13 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M tile_count = uint(x1 - x0) * uint(y1 - y0); uint base = path.tiles.offset - (((uint(dy) * stride) + uint(dx)) * 8u); sh_tile_base[th_ix] = base; - uint param_19 = path.tiles.offset; - uint param_20 = ((path.bbox.z - path.bbox.x) * (path.bbox.w - path.bbox.y)) * 8u; - bool param_21 = mem_ok; - Alloc path_alloc = new_alloc(param_19, param_20, param_21); - uint param_22 = th_ix; - Alloc param_23 = path_alloc; - write_tile_alloc(param_22, param_23); + uint param_20 = path.tiles.offset; + uint param_21 = ((path.bbox.z - path.bbox.x) * (path.bbox.w - path.bbox.y)) * 8u; + bool param_22 = true; + Alloc path_alloc = new_alloc(param_20, param_21, param_22); + uint param_23 = th_ix; + Alloc param_24 = path_alloc; + write_tile_alloc(param_23, param_24); break; } default: @@ -929,60 +938,57 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M } } uint element_ix_1 = sh_elements[el_ix]; - uint tag_1 = _1399.scene[drawtag_start + element_ix_1]; + uint tag_1 = _1390.scene[drawtag_start + element_ix_1]; if (el_ix > 0u) { - _1632 = sh_tile_count[el_ix - 1u]; + _1622 = sh_tile_count[el_ix - 1u]; } else { - _1632 = 0u; + _1622 = 0u; } - uint seq_ix = ix_1 - _1632; + uint seq_ix = ix_1 - _1622; 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); bool include_tile = false; - if (mem_ok) + uint param_25 = el_ix; + bool param_26 = true; + Alloc param_27 = read_tile_alloc(param_25, param_26, v_891); + TileRef param_28 = TileRef{ sh_tile_base[el_ix] + (((sh_tile_stride[el_ix] * y) + x) * 8u) }; + Tile tile = Tile_read(param_27, param_28, v_267); + bool is_clip = (tag_1 & 1u) != 0u; + bool is_blend = false; + if (is_clip) { - uint param_24 = el_ix; - bool param_25 = mem_ok; - Alloc param_26 = read_tile_alloc(param_24, param_25, v_266, v_266BufferSize); - TileRef param_27 = TileRef{ sh_tile_base[el_ix] + (((sh_tile_stride[el_ix] * y) + x) * 8u) }; - Tile tile = Tile_read(param_26, param_27, v_266, v_266BufferSize); - 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_266.memory[drawmonoid_base_1 + 2u]; - uint dd = drawdata_start + (scene_offset >> uint(2)); - uint blend = _1399.scene[dd]; - is_blend = blend != 32771u; - } - bool _1720 = tile.tile.offset != 0u; - bool _1729; - if (!_1720) - { - _1729 = (tile.backdrop == 0) == is_clip; - } - else - { - _1729 = _1720; - } - include_tile = _1729 || is_blend; + uint drawmonoid_base_1 = drawmonoid_start + (4u * element_ix_1); + uint scene_offset = v_267.memory[drawmonoid_base_1 + 2u]; + uint dd = drawdata_start + (scene_offset >> uint(2)); + uint blend = _1390.scene[dd]; + is_blend = blend != 32771u; } + bool _1706 = tile.tile.offset != 0u; + bool _1715; + if (!_1706) + { + _1715 = (tile.backdrop == 0) == is_clip; + } + else + { + _1715 = _1706; + } + include_tile = _1715 || is_blend; if (include_tile) { uint el_slice = el_ix / 32u; uint el_mask = 1u << (el_ix & 31u); - uint _1751 = atomic_fetch_or_explicit((threadgroup atomic_uint*)&sh_bitmaps[el_slice][(y * 16u) + x], el_mask, memory_order_relaxed); + uint _1737 = 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); uint slice_ix = 0u; uint bitmap = sh_bitmaps[0][th_ix]; - while (mem_ok) + while (true) { if (bitmap == 0u) { @@ -1000,175 +1006,170 @@ 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 = _1399.scene[drawtag_start + element_ix_2]; + uint drawtag = _1390.scene[drawtag_start + element_ix_2]; if (clip_zero_depth == 0u) { - uint param_28 = element_ref_ix; - bool param_29 = mem_ok; - Alloc param_30 = read_tile_alloc(param_28, param_29, v_266, v_266BufferSize); - TileRef param_31 = TileRef{ sh_tile_base[element_ref_ix] + (((sh_tile_stride[element_ref_ix] * tile_y) + tile_x) * 8u) }; - Tile tile_1 = Tile_read(param_30, param_31, v_266, v_266BufferSize); + uint param_29 = element_ref_ix; + bool param_30 = true; + Alloc param_31 = read_tile_alloc(param_29, param_30, v_891); + TileRef param_32 = TileRef{ sh_tile_base[element_ref_ix] + (((sh_tile_stride[element_ref_ix] * tile_y) + tile_x) * 8u) }; + Tile tile_1 = Tile_read(param_31, param_32, v_267); uint drawmonoid_base_2 = drawmonoid_start + (4u * element_ix_2); - uint scene_offset_1 = v_266.memory[drawmonoid_base_2 + 2u]; - uint info_offset = v_266.memory[drawmonoid_base_2 + 3u]; + uint scene_offset_1 = v_267.memory[drawmonoid_base_2 + 2u]; + uint info_offset = v_267.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_266.memory[di]); - Alloc param_32 = cmd_alloc; - CmdRef param_33 = cmd_ref; - uint param_34 = cmd_limit; - bool _1876 = alloc_cmd(param_32, param_33, param_34, v_266, v_266BufferSize); - cmd_alloc = param_32; - cmd_ref = param_33; - cmd_limit = param_34; - if (!_1876) + linewidth = as_type(v_267.memory[di]); + Alloc param_33 = cmd_alloc; + CmdRef param_34 = cmd_ref; + uint param_35 = cmd_limit; + alloc_cmd(param_33, param_34, param_35, mem_ok, v_267, v_891); + cmd_alloc = param_33; + cmd_ref = param_34; + cmd_limit = param_35; + Alloc param_36 = cmd_alloc; + CmdRef param_37 = cmd_ref; + Tile param_38 = tile_1; + float param_39 = linewidth; + write_fill(param_36, param_37, param_38, param_39, mem_ok, v_267); + cmd_ref = param_37; + uint rgba = _1390.scene[dd_1]; + if (mem_ok) { - break; + Alloc param_40 = cmd_alloc; + CmdRef param_41 = cmd_ref; + CmdColor param_42 = CmdColor{ rgba }; + Cmd_Color_write(param_40, param_41, param_42, v_267); } - Alloc param_35 = cmd_alloc; - CmdRef param_36 = cmd_ref; - Tile param_37 = tile_1; - float param_38 = linewidth; - write_fill(param_35, param_36, param_37, param_38, v_266, v_266BufferSize); - cmd_ref = param_36; - uint rgba = _1399.scene[dd_1]; - Alloc param_39 = cmd_alloc; - CmdRef param_40 = cmd_ref; - CmdColor param_41 = CmdColor{ rgba }; - Cmd_Color_write(param_39, param_40, param_41, v_266, v_266BufferSize); cmd_ref.offset += 8u; break; } case 276u: { - Alloc param_42 = cmd_alloc; - CmdRef param_43 = cmd_ref; - uint param_44 = cmd_limit; - bool _1917 = alloc_cmd(param_42, param_43, param_44, v_266, v_266BufferSize); - cmd_alloc = param_42; - cmd_ref = param_43; - cmd_limit = param_44; - if (!_1917) + Alloc param_43 = cmd_alloc; + CmdRef param_44 = cmd_ref; + uint param_45 = cmd_limit; + alloc_cmd(param_43, param_44, param_45, mem_ok, v_267, v_891); + cmd_alloc = param_43; + cmd_ref = param_44; + cmd_limit = param_45; + linewidth = as_type(v_267.memory[di]); + Alloc param_46 = cmd_alloc; + CmdRef param_47 = cmd_ref; + Tile param_48 = tile_1; + float param_49 = linewidth; + write_fill(param_46, param_47, param_48, param_49, mem_ok, v_267); + cmd_ref = param_47; + cmd_lin.index = _1390.scene[dd_1]; + cmd_lin.line_x = as_type(v_267.memory[di + 1u]); + cmd_lin.line_y = as_type(v_267.memory[di + 2u]); + cmd_lin.line_c = as_type(v_267.memory[di + 3u]); + if (mem_ok) { - break; + Alloc param_50 = cmd_alloc; + CmdRef param_51 = cmd_ref; + CmdLinGrad param_52 = cmd_lin; + Cmd_LinGrad_write(param_50, param_51, param_52, v_267); } - linewidth = as_type(v_266.memory[di]); - Alloc param_45 = cmd_alloc; - CmdRef param_46 = cmd_ref; - Tile param_47 = tile_1; - float param_48 = linewidth; - write_fill(param_45, param_46, param_47, param_48, v_266, v_266BufferSize); - cmd_ref = param_46; - cmd_lin.index = _1399.scene[dd_1]; - cmd_lin.line_x = as_type(v_266.memory[di + 1u]); - cmd_lin.line_y = as_type(v_266.memory[di + 2u]); - cmd_lin.line_c = as_type(v_266.memory[di + 3u]); - Alloc param_49 = cmd_alloc; - CmdRef param_50 = cmd_ref; - CmdLinGrad param_51 = cmd_lin; - Cmd_LinGrad_write(param_49, param_50, param_51, v_266, v_266BufferSize); cmd_ref.offset += 20u; break; } case 732u: { - Alloc param_52 = cmd_alloc; - CmdRef param_53 = cmd_ref; - uint param_54 = cmd_limit; - bool _1981 = alloc_cmd(param_52, param_53, param_54, v_266, v_266BufferSize); - cmd_alloc = param_52; - cmd_ref = param_53; - cmd_limit = param_54; - if (!_1981) + Alloc param_53 = cmd_alloc; + CmdRef param_54 = cmd_ref; + uint param_55 = cmd_limit; + alloc_cmd(param_53, param_54, param_55, mem_ok, v_267, v_891); + cmd_alloc = param_53; + cmd_ref = param_54; + cmd_limit = param_55; + linewidth = as_type(v_267.memory[di]); + Alloc param_56 = cmd_alloc; + CmdRef param_57 = cmd_ref; + Tile param_58 = tile_1; + float param_59 = linewidth; + write_fill(param_56, param_57, param_58, param_59, mem_ok, v_267); + cmd_ref = param_57; + cmd_rad.index = _1390.scene[dd_1]; + cmd_rad.mat = as_type(uint4(v_267.memory[di + 1u], v_267.memory[di + 2u], v_267.memory[di + 3u], v_267.memory[di + 4u])); + cmd_rad.xlat = as_type(uint2(v_267.memory[di + 5u], v_267.memory[di + 6u])); + cmd_rad.c1 = as_type(uint2(v_267.memory[di + 7u], v_267.memory[di + 8u])); + cmd_rad.ra = as_type(v_267.memory[di + 9u]); + cmd_rad.roff = as_type(v_267.memory[di + 10u]); + if (mem_ok) { - break; + Alloc param_60 = cmd_alloc; + CmdRef param_61 = cmd_ref; + CmdRadGrad param_62 = cmd_rad; + Cmd_RadGrad_write(param_60, param_61, param_62, v_267); } - linewidth = as_type(v_266.memory[di]); - Alloc param_55 = cmd_alloc; - CmdRef param_56 = cmd_ref; - Tile param_57 = tile_1; - float param_58 = linewidth; - write_fill(param_55, param_56, param_57, param_58, v_266, v_266BufferSize); - cmd_ref = param_56; - cmd_rad.index = _1399.scene[dd_1]; - cmd_rad.mat = as_type(uint4(v_266.memory[di + 1u], v_266.memory[di + 2u], v_266.memory[di + 3u], v_266.memory[di + 4u])); - cmd_rad.xlat = as_type(uint2(v_266.memory[di + 5u], v_266.memory[di + 6u])); - cmd_rad.c1 = as_type(uint2(v_266.memory[di + 7u], v_266.memory[di + 8u])); - cmd_rad.ra = as_type(v_266.memory[di + 9u]); - cmd_rad.roff = as_type(v_266.memory[di + 10u]); - Alloc param_59 = cmd_alloc; - CmdRef param_60 = cmd_ref; - CmdRadGrad param_61 = cmd_rad; - Cmd_RadGrad_write(param_59, param_60, param_61, v_266, v_266BufferSize); cmd_ref.offset += 48u; break; } case 72u: { - linewidth = as_type(v_266.memory[di]); - Alloc param_62 = cmd_alloc; - CmdRef param_63 = cmd_ref; - uint param_64 = cmd_limit; - bool _2087 = alloc_cmd(param_62, param_63, param_64, v_266, v_266BufferSize); - cmd_alloc = param_62; - cmd_ref = param_63; - cmd_limit = param_64; - if (!_2087) - { - break; - } - Alloc param_65 = cmd_alloc; - CmdRef param_66 = cmd_ref; - Tile param_67 = tile_1; - float param_68 = linewidth; - write_fill(param_65, param_66, param_67, param_68, v_266, v_266BufferSize); - cmd_ref = param_66; - uint index = _1399.scene[dd_1]; - uint raw1 = _1399.scene[dd_1 + 1u]; + Alloc param_63 = cmd_alloc; + CmdRef param_64 = cmd_ref; + uint param_65 = cmd_limit; + alloc_cmd(param_63, param_64, param_65, mem_ok, v_267, v_891); + cmd_alloc = param_63; + cmd_ref = param_64; + cmd_limit = param_65; + linewidth = as_type(v_267.memory[di]); + Alloc param_66 = cmd_alloc; + CmdRef param_67 = cmd_ref; + Tile param_68 = tile_1; + float param_69 = linewidth; + write_fill(param_66, param_67, param_68, param_69, mem_ok, v_267); + cmd_ref = param_67; + uint index = _1390.scene[dd_1]; + uint raw1 = _1390.scene[dd_1 + 1u]; int2 offset_1 = int2(int(raw1 << uint(16)) >> 16, int(raw1) >> 16); - Alloc param_69 = cmd_alloc; - CmdRef param_70 = cmd_ref; - CmdImage param_71 = CmdImage{ index, offset_1 }; - Cmd_Image_write(param_69, param_70, param_71, v_266, v_266BufferSize); + if (mem_ok) + { + Alloc param_70 = cmd_alloc; + CmdRef param_71 = cmd_ref; + CmdImage param_72 = CmdImage{ index, offset_1 }; + Cmd_Image_write(param_70, param_71, param_72, v_267); + } cmd_ref.offset += 12u; break; } case 5u: { - bool _2140 = tile_1.tile.offset == 0u; - bool _2146; - if (_2140) + bool _2120 = tile_1.tile.offset == 0u; + bool _2126; + if (_2120) { - _2146 = tile_1.backdrop == 0; + _2126 = tile_1.backdrop == 0; } else { - _2146 = _2140; + _2126 = _2120; } - if (_2146) + if (_2126) { clip_zero_depth = clip_depth + 1u; } else { - Alloc param_72 = cmd_alloc; - CmdRef param_73 = cmd_ref; - uint param_74 = cmd_limit; - bool _2158 = alloc_cmd(param_72, param_73, param_74, v_266, v_266BufferSize); - cmd_alloc = param_72; - cmd_ref = param_73; - cmd_limit = param_74; - if (!_2158) + Alloc param_73 = cmd_alloc; + CmdRef param_74 = cmd_ref; + uint param_75 = cmd_limit; + alloc_cmd(param_73, param_74, param_75, mem_ok, v_267, v_891); + cmd_alloc = param_73; + cmd_ref = param_74; + cmd_limit = param_75; + if (mem_ok) { - break; + Alloc param_76 = cmd_alloc; + CmdRef param_77 = cmd_ref; + Cmd_BeginClip_write(param_76, param_77, v_267); } - Alloc param_75 = cmd_alloc; - CmdRef param_76 = cmd_ref; - Cmd_BeginClip_write(param_75, param_76, v_266, v_266BufferSize); cmd_ref.offset += 4u; render_blend_depth++; max_blend_depth = max(max_blend_depth, render_blend_depth); @@ -1179,28 +1180,20 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M case 37u: { clip_depth--; - Alloc param_77 = cmd_alloc; - CmdRef param_78 = cmd_ref; - uint param_79 = cmd_limit; - bool _2191 = alloc_cmd(param_77, param_78, param_79, v_266, v_266BufferSize); - cmd_alloc = param_77; - cmd_ref = param_78; - cmd_limit = param_79; - if (!_2191) + Alloc param_78 = cmd_alloc; + CmdRef param_79 = cmd_ref; + Tile param_80 = tile_1; + float param_81 = -1.0; + write_fill(param_78, param_79, param_80, param_81, mem_ok, v_267); + cmd_ref = param_79; + uint blend_1 = _1390.scene[dd_1]; + if (mem_ok) { - break; + Alloc param_82 = cmd_alloc; + CmdRef param_83 = cmd_ref; + CmdEndClip param_84 = CmdEndClip{ blend_1 }; + Cmd_EndClip_write(param_82, param_83, param_84, v_267); } - Alloc param_80 = cmd_alloc; - CmdRef param_81 = cmd_ref; - Tile param_82 = tile_1; - float param_83 = -1.0; - write_fill(param_80, param_81, param_82, param_83, v_266, v_266BufferSize); - cmd_ref = param_81; - uint blend_1 = _1399.scene[dd_1]; - Alloc param_84 = cmd_alloc; - CmdRef param_85 = cmd_ref; - CmdEndClip param_86 = CmdEndClip{ blend_1 }; - Cmd_EndClip_write(param_84, param_85, param_86, v_266, v_266BufferSize); cmd_ref.offset += 8u; render_blend_depth--; break; @@ -1235,31 +1228,33 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M break; } } - bool _2263 = (bin_tile_x + tile_x) < _1020.conf.width_in_tiles; - bool _2272; - if (_2263) + bool _2231 = (bin_tile_x + tile_x) < v_891.conf.width_in_tiles; + bool _2240; + if (_2231) { - _2272 = (bin_tile_y + tile_y) < _1020.conf.height_in_tiles; + _2240 = (bin_tile_y + tile_y) < v_891.conf.height_in_tiles; } else { - _2272 = _2263; + _2240 = _2231; } - if (_2272) + if (_2240) { - Alloc param_87 = cmd_alloc; - CmdRef param_88 = cmd_ref; - Cmd_End_write(param_87, param_88, v_266, v_266BufferSize); + if (mem_ok) + { + Alloc param_85 = cmd_alloc; + CmdRef param_86 = cmd_ref; + Cmd_End_write(param_85, param_86, v_267); + } if (max_blend_depth > 4u) { uint scratch_size = (((max_blend_depth * 16u) * 16u) * 1u) * 4u; - uint param_89 = scratch_size; - MallocResult _2293 = malloc(param_89, v_266, v_266BufferSize); - MallocResult scratch = _2293; - Alloc param_90 = scratch_alloc; - uint param_91 = scratch_alloc.offset; - Alloc param_92 = scratch.alloc; - alloc_write(param_90, param_91, param_92, v_266, v_266BufferSize); + uint _2264 = atomic_fetch_add_explicit((device atomic_uint*)&v_267.blend_offset, scratch_size, memory_order_relaxed); + uint scratch = _2264; + Alloc param_87 = scratch_alloc; + uint param_88 = scratch_alloc.offset >> uint(2); + uint param_89 = scratch; + write_mem(param_87, param_88, param_89, v_267); } } } diff --git a/piet-gpu/shader/gen/coarse.spv b/piet-gpu/shader/gen/coarse.spv index fe5eeee188be90b85271b37aad93d5f1f23c237f..2417cf8ebf1f3d27b35aa71d031235e1cd67490f 100644 GIT binary patch literal 60088 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 literal 60516 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 Vxfi~Gr=MfW^($*=Epu=5{{g6=_aguR diff --git a/piet-gpu/shader/gen/draw_leaf.dxil b/piet-gpu/shader/gen/draw_leaf.dxil index 200f16962e12a1076fc8d560bcb58523676956d1..97b006a53b013923478e71d0b0a34418735ab44f 100644 GIT binary patch delta 2192 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 diff --git a/piet-gpu/shader/gen/draw_leaf.hlsl b/piet-gpu/shader/gen/draw_leaf.hlsl index 734d21e..789c9b3 100644 --- a/piet-gpu/shader/gen/draw_leaf.hlsl +++ b/piet-gpu/shader/gen/draw_leaf.hlsl @@ -13,6 +13,7 @@ struct Alloc struct Config { + uint mem_size; uint n_elements; uint n_pathseg; uint width_in_tiles; @@ -88,7 +89,7 @@ DrawMonoid draw_monoid_identity() void comp_main() { uint ix = gl_GlobalInvocationID.x * 8u; - uint drawtag_base = _93.Load(100) >> uint(2); + uint drawtag_base = _93.Load(104) >> uint(2); uint tag_word = _103.Load((drawtag_base + ix) * 4 + 0); uint param = tag_word; DrawMonoid agg = map_tag(param); @@ -137,11 +138,11 @@ void comp_main() DrawMonoid param_7 = sh_scratch[gl_LocalInvocationID.x - 1u]; row = combine_draw_monoid(param_6, param_7); } - uint drawdata_base = _93.Load(104) >> uint(2); - uint drawinfo_base = _93.Load(68) >> uint(2); + uint drawdata_base = _93.Load(108) >> uint(2); + uint drawinfo_base = _93.Load(72) >> uint(2); uint out_ix = gl_GlobalInvocationID.x * 8u; - uint out_base = (_93.Load(44) >> uint(2)) + (out_ix * 4u); - uint clip_out_base = _93.Load(48) >> uint(2); + uint out_base = (_93.Load(48) >> uint(2)) + (out_ix * 4u); + uint clip_out_base = _93.Load(52) >> uint(2); float4 mat; float2 translate; float2 p0; @@ -155,31 +156,31 @@ void comp_main() DrawMonoid param_9 = local[i_2 - 1u]; m = combine_draw_monoid(param_8, param_9); } - _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); + _285.Store((out_base + (i_2 * 4u)) * 4 + 12, m.path_ix); + _285.Store(((out_base + (i_2 * 4u)) + 1u) * 4 + 12, m.clip_ix); + _285.Store(((out_base + (i_2 * 4u)) + 2u) * 4 + 12, m.scene_offset); + _285.Store(((out_base + (i_2 * 4u)) + 3u) * 4 + 12, m.info_offset); uint dd = drawdata_base + (m.scene_offset >> uint(2)); uint di = drawinfo_base + (m.info_offset >> uint(2)); 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 = (_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; + uint bbox_offset = (_93.Load(44) >> uint(2)) + (6u * m.path_ix); + float bbox_l = float(_285.Load(bbox_offset * 4 + 12)) - 32768.0f; + float bbox_t = float(_285.Load((bbox_offset + 1u) * 4 + 12)) - 32768.0f; + float bbox_r = float(_285.Load((bbox_offset + 2u) * 4 + 12)) - 32768.0f; + float bbox_b = float(_285.Load((bbox_offset + 3u) * 4 + 12)) - 32768.0f; float4 bbox = float4(bbox_l, bbox_t, bbox_r, bbox_b); - float linewidth = asfloat(_285.Load((bbox_offset + 4u) * 4 + 8)); + float linewidth = asfloat(_285.Load((bbox_offset + 4u) * 4 + 12)); uint fill_mode = uint(linewidth >= 0.0f); if (((linewidth >= 0.0f) || (tag_word == 276u)) || (tag_word == 732u)) { - 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))); + uint trans_ix = _285.Load((bbox_offset + 5u) * 4 + 12); + uint t = (_93.Load(40) >> uint(2)) + (6u * trans_ix); + mat = asfloat(uint4(_285.Load(t * 4 + 12), _285.Load((t + 1u) * 4 + 12), _285.Load((t + 2u) * 4 + 12), _285.Load((t + 3u) * 4 + 12))); if ((tag_word == 276u) || (tag_word == 732u)) { - translate = asfloat(uint2(_285.Load((t + 4u) * 4 + 8), _285.Load((t + 5u) * 4 + 8))); + translate = asfloat(uint2(_285.Load((t + 4u) * 4 + 12), _285.Load((t + 5u) * 4 + 12))); } } if (linewidth >= 0.0f) @@ -191,12 +192,12 @@ void comp_main() case 68u: case 72u: { - _285.Store(di * 4 + 8, asuint(linewidth)); + _285.Store(di * 4 + 12, asuint(linewidth)); break; } case 276u: { - _285.Store(di * 4 + 8, asuint(linewidth)); + _285.Store(di * 4 + 12, 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; @@ -206,9 +207,9 @@ 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)); - _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)); + _285.Store((di + 1u) * 4 + 12, asuint(line_x)); + _285.Store((di + 2u) * 4 + 12, asuint(line_y)); + _285.Store((di + 3u) * 4 + 12, asuint(line_c)); break; } case 732u: @@ -227,17 +228,17 @@ void comp_main() 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)); + _285.Store(di * 4 + 12, asuint(linewidth)); + _285.Store((di + 1u) * 4 + 12, asuint(inv_mat.x)); + _285.Store((di + 2u) * 4 + 12, asuint(inv_mat.y)); + _285.Store((di + 3u) * 4 + 12, asuint(inv_mat.z)); + _285.Store((di + 4u) * 4 + 12, asuint(inv_mat.w)); + _285.Store((di + 5u) * 4 + 12, asuint(inv_tr.x)); + _285.Store((di + 6u) * 4 + 12, asuint(inv_tr.y)); + _285.Store((di + 7u) * 4 + 12, asuint(c1.x)); + _285.Store((di + 8u) * 4 + 12, asuint(c1.y)); + _285.Store((di + 9u) * 4 + 12, asuint(ra)); + _285.Store((di + 10u) * 4 + 12, asuint(roff)); break; } case 5u: @@ -253,7 +254,7 @@ void comp_main() { path_ix = m.path_ix; } - _285.Store((clip_out_base + m.clip_ix) * 4 + 8, path_ix); + _285.Store((clip_out_base + m.clip_ix) * 4 + 12, path_ix); } } } diff --git a/piet-gpu/shader/gen/draw_leaf.msl b/piet-gpu/shader/gen/draw_leaf.msl index c11e21b..2ec1911 100644 --- a/piet-gpu/shader/gen/draw_leaf.msl +++ b/piet-gpu/shader/gen/draw_leaf.msl @@ -59,6 +59,7 @@ struct Alloc struct Config { + uint mem_size; uint n_elements; uint n_pathseg; uint width_in_tiles; @@ -115,6 +116,7 @@ struct Memory { uint mem_offset; uint mem_error; + uint blend_offset; uint memory[1]; }; diff --git a/piet-gpu/shader/gen/draw_leaf.spv b/piet-gpu/shader/gen/draw_leaf.spv index 58dde4387fddb65154909ba8a846f351b6115758..f9feedc8d52df64553a1f01ed883cbfdb46b9d37 100644 GIT binary patch delta 737 zcmY+BJ!lhQ7{~9u_b!QT(&p1MIj=!Vlp3Q3btuI_w6-YXB-nx+NxUY3yGt<{)Z!p6 zIyi(!2Zat&1O*4>aCGP(;^ZI>9UOwI3QnRR_%3 zUyfdA8EYpZVXoa-S?M}GNMsBL8#K_0ViyVB6nV110?mSEa6vyNr=yCA&!?iG?mGVE z{~G9FOa}efIc;({&qU%hjvH*n--*;B*5G=%?T!bJC%y$PsM<;@ zaj)7A!q&E7w*oopCiD*v2Mj_%ud=58ft@3>Fzts{6qsiSyA9mX(lb^Z*w zj(1XS)@to)(sKuR%hh<(&6vcUlWA9I+M#3iGONl=Wj}yXgWmx1_-kkcGu|@@OvkIk z#5hG3g%X<1pY-wgC;AWZ0i5&;qr8N?kYb!Nd9i0{Yz=tVe*yh?q{X*r9QXNQqo_kOD>il)WLyJrE#Lf1+N9;&%e~*_^U;kccbmwJu@vM75S8Xyoa&b>dz)cC6%ao< Q$g>CtOa=itvsDgH0wEO`g#Z8m diff --git a/piet-gpu/shader/gen/draw_reduce.hlsl b/piet-gpu/shader/gen/draw_reduce.hlsl index 8311155..1a8f2b1 100644 --- a/piet-gpu/shader/gen/draw_reduce.hlsl +++ b/piet-gpu/shader/gen/draw_reduce.hlsl @@ -13,6 +13,7 @@ struct Alloc struct Config { + uint mem_size; uint n_elements; uint n_pathseg; uint width_in_tiles; @@ -81,7 +82,7 @@ DrawMonoid combine_draw_monoid(DrawMonoid a, DrawMonoid b) void comp_main() { uint ix = gl_GlobalInvocationID.x * 8u; - uint drawtag_base = _87.Load(100) >> uint(2); + uint drawtag_base = _87.Load(104) >> uint(2); uint tag_word = _97.Load((drawtag_base + ix) * 4 + 0); uint param = tag_word; DrawMonoid agg = map_tag(param); diff --git a/piet-gpu/shader/gen/draw_reduce.msl b/piet-gpu/shader/gen/draw_reduce.msl index 759267c..b2510e3 100644 --- a/piet-gpu/shader/gen/draw_reduce.msl +++ b/piet-gpu/shader/gen/draw_reduce.msl @@ -20,6 +20,7 @@ struct Alloc struct Config { + uint mem_size; uint n_elements; uint n_pathseg; uint width_in_tiles; @@ -76,6 +77,7 @@ struct Memory { uint mem_offset; uint mem_error; + uint blend_offset; uint memory[1]; }; diff --git a/piet-gpu/shader/gen/draw_reduce.spv b/piet-gpu/shader/gen/draw_reduce.spv index d6c6fb75fa1dc5d7d65bfa5c1ab890d474b0ee68..29926778b3a46f9aebfc58c387f095ac8deeec99 100644 GIT binary patch delta 460 zcmY+8J5Iwu5Qe?Gek9}tBw(B+L{TaVN<_E;6m)5*EIVw7rS&?(mOz{#4H_=bM@T^XRqrFrf#b2;Dfi6&fxRcOP$pp?cpNfsc# zBr_*9J~1aJKN+Nk4XlQBvLds%BpXn+pd>j5Aqz2qeR3ePG$Y64T%a0GkO@VJdBspg zFk84L&jqUCp1hM;UXll>COIdw0Notk$sd7g_$KqR$TRX!)@6}q6qxMEA}uQjRG(6m zSe}`emXFZG3U-;$J^jbmbGWjF&=%(VF`dnD6lC$3$Ln+13dF*3_C dgiKcC6Q2BrcM7BA=0-kGMrNSO%@_I0c>pFLQ%?W@ diff --git a/piet-gpu/shader/gen/kernel4.dxil b/piet-gpu/shader/gen/kernel4.dxil index c48d59da9624714bca7fe6b0ffc02834646dbed5..33873b30466aba7d27de99416f5d9b383d1336fd 100644 GIT binary patch literal 14524 zcmeHtdsI``w)f6!Cy)>lUheQpc#0Y&0YwB&6F?qc<`B@nIoV(zg1OXn{X*a0rUY5t4rcep5j>c@GJ;e*SA z!UuD=;pXbY`{{TCE?m|>U;o@sgqQfo(~tARFPuOA!QbJRryrLC|NL`53HtDlryr;F zT=VlK`DPGA29*6ETt-1o9xf;g0CmuxmTtKp!9b9Q&_~zuTs-{Y9aR&xN76>lL0JjY z_7W->F%%jnoV=@0jm;#c?WL#LSP22iG%VLUp|C337{E)74Y@2qTU$bmuE20D{Ofzla(g+LcDuv789dcz!H+AG=+eX zvQy5`%dy&8E5=yTOJl8i#+kIeDLid3-NXqZQsyjHcXRYs0pmnO-|6nbvHcOz+hb1d zuY2*}(p)*F7Y57>J_dI=Rx-Xyh~Lo#>&X(~v3ibvm-(>%#=GW9
qg@uEA{+4-7 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 LMUDTTvFG}~f`f)V literal 14484 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 K@q1&}^}hjWLyOn| diff --git a/piet-gpu/shader/gen/kernel4.hlsl b/piet-gpu/shader/gen/kernel4.hlsl index 0a6c022..2e1f937 100644 --- a/piet-gpu/shader/gen/kernel4.hlsl +++ b/piet-gpu/shader/gen/kernel4.hlsl @@ -130,6 +130,7 @@ struct TileSeg struct Config { + uint mem_size; uint n_elements; uint n_pathseg; uint width_in_tiles; @@ -163,9 +164,10 @@ static const uint3 gl_WorkGroupSize = uint3(8u, 4u, 1u); RWByteAddressBuffer _297 : register(u0, space0); ByteAddressBuffer _1681 : register(t1, space0); -RWTexture2D image_atlas : register(u3, space0); -RWTexture2D gradients : register(u4, space0); -RWTexture2D image : register(u2, space0); +RWByteAddressBuffer _2506 : register(u2, space0); +RWTexture2D image_atlas : register(u4, space0); +RWTexture2D gradients : register(u5, space0); +RWTexture2D image : register(u3, space0); static uint3 gl_WorkGroupID; static uint3 gl_LocalInvocationID; @@ -206,7 +208,7 @@ uint read_mem(Alloc alloc, uint offset) { return 0u; } - uint v = _297.Load(offset * 4 + 8); + uint v = _297.Load(offset * 4 + 12); return v; } @@ -989,9 +991,9 @@ CmdJump Cmd_Jump_read(Alloc a, CmdRef ref) void comp_main() { - uint tile_ix = (gl_WorkGroupID.y * _1681.Load(8)) + gl_WorkGroupID.x; + uint tile_ix = (gl_WorkGroupID.y * _1681.Load(12)) + gl_WorkGroupID.x; Alloc _1696; - _1696.offset = _1681.Load(24); + _1696.offset = _1681.Load(28); Alloc param; param.offset = _1696.offset; uint param_1 = tile_ix * 1024u; @@ -999,7 +1001,7 @@ void comp_main() Alloc cmd_alloc = slice_mem(param, param_1, param_2); CmdRef _1705 = { cmd_alloc.offset }; CmdRef cmd_ref = _1705; - uint blend_offset = _297.Load((cmd_ref.offset >> uint(2)) * 4 + 8); + uint blend_offset = _297.Load((cmd_ref.offset >> uint(2)) * 4 + 12); cmd_ref.offset += 4u; uint2 xy_uint = uint2(gl_LocalInvocationID.x + (16u * gl_WorkGroupID.x), gl_LocalInvocationID.y + (16u * gl_WorkGroupID.y)); float2 xy = float2(xy_uint); @@ -1009,14 +1011,13 @@ void comp_main() rgba[i] = 0.0f.xxxx; } uint clip_depth = 0u; - bool mem_ok = _297.Load(4) == 0u; float df[8]; TileSegRef tile_seg_ref; float area[8]; uint blend_stack[4][8]; uint base_ix_1; uint bg_rgba; - while (mem_ok) + while (true) { Alloc param_3 = cmd_alloc; CmdRef param_4 = cmd_ref; @@ -1036,13 +1037,13 @@ void comp_main() { df[k] = 1000000000.0f; } - TileSegRef _1810 = { stroke.tile_ref }; - tile_seg_ref = _1810; + TileSegRef _1805 = { stroke.tile_ref }; + tile_seg_ref = _1805; do { uint param_7 = tile_seg_ref.offset; uint param_8 = 24u; - bool param_9 = mem_ok; + bool param_9 = true; 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); @@ -1073,13 +1074,13 @@ void comp_main() { area[k_3] = float(fill.backdrop); } - TileSegRef _1930 = { fill.tile_ref }; - tile_seg_ref = _1930; + TileSegRef _1924 = { fill.tile_ref }; + tile_seg_ref = _1924; do { uint param_15 = tile_seg_ref.offset; uint param_16 = 24u; - bool param_17 = mem_ok; + bool param_17 = true; 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); @@ -1163,10 +1164,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 _2264 = fromsRGB(param_29); - fg_rgba.x = _2264.x; - fg_rgba.y = _2264.y; - fg_rgba.z = _2264.z; + float3 _2257 = fromsRGB(param_29); + fg_rgba.x = _2257.x; + fg_rgba.y = _2257.y; + fg_rgba.z = _2257.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; } @@ -1189,10 +1190,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 _2374 = fromsRGB(param_33); - fg_rgba_1.x = _2374.x; - fg_rgba_1.y = _2374.y; - fg_rgba_1.z = _2374.z; + float3 _2367 = fromsRGB(param_33); + fg_rgba_1.x = _2367.x; + fg_rgba_1.y = _2367.y; + fg_rgba_1.z = _2367.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; } @@ -1206,9 +1207,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 _2417[8]; - fillImage(_2417, param_36, param_37); - float4 img[8] = _2417; + float4 _2410[8]; + fillImage(_2410, param_36, param_37); + float4 img[8] = _2410; for (uint k_11 = 0u; k_11 < 8u; k_11++) { float4 fg_k_3 = img[k_11] * area[k_11]; @@ -1224,8 +1225,8 @@ void comp_main() for (uint k_12 = 0u; k_12 < 8u; k_12++) { float4 param_38 = float4(rgba[k_12]); - uint _2479 = packsRGB(param_38); - blend_stack[clip_depth][k_12] = _2479; + uint _2472 = packsRGB(param_38); + blend_stack[clip_depth][k_12] = _2472; rgba[k_12] = 0.0f.xxxx; } } @@ -1235,8 +1236,8 @@ void comp_main() for (uint k_13 = 0u; k_13 < 8u; k_13++) { float4 param_39 = float4(rgba[k_13]); - uint _2522 = packsRGB(param_39); - _297.Store((base_ix + k_13) * 4 + 8, _2522); + uint _2519 = packsRGB(param_39); + _2506.Store((base_ix + k_13) * 4 + 0, _2519); rgba[k_13] = 0.0f.xxxx; } } @@ -1262,7 +1263,7 @@ void comp_main() } else { - bg_rgba = _297.Load((base_ix_1 + k_14) * 4 + 8); + bg_rgba = _2506.Load((base_ix_1 + k_14) * 4 + 0); } uint param_42 = bg_rgba; float4 bg = unpacksRGB(param_42); @@ -1279,8 +1280,8 @@ void comp_main() { Alloc param_46 = cmd_alloc; CmdRef param_47 = cmd_ref; - CmdRef _2621 = { Cmd_Jump_read(param_46, param_47).new_ref }; - cmd_ref = _2621; + CmdRef _2618 = { Cmd_Jump_read(param_46, param_47).new_ref }; + cmd_ref = _2618; cmd_alloc.offset = cmd_ref.offset; break; } diff --git a/piet-gpu/shader/gen/kernel4.msl b/piet-gpu/shader/gen/kernel4.msl index f60ea81..1cf8cb3 100644 --- a/piet-gpu/shader/gen/kernel4.msl +++ b/piet-gpu/shader/gen/kernel4.msl @@ -178,6 +178,7 @@ struct Memory { uint mem_offset; uint mem_error; + uint blend_offset; uint memory[1]; }; @@ -188,6 +189,7 @@ struct Alloc_1 struct Config { + uint mem_size; uint n_elements; uint n_pathseg; uint width_in_tiles; @@ -222,6 +224,11 @@ struct ConfigBuf Config conf; }; +struct BlendBuf +{ + uint blend_mem[1]; +}; + constant uint3 gl_WorkGroupSize [[maybe_unused]] = uint3(8u, 4u, 1u); static inline __attribute__((always_inline)) @@ -1047,7 +1054,7 @@ 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& _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]]) +kernel void main0(device Memory& v_297 [[buffer(0)]], const device ConfigBuf& _1681 [[buffer(1)]], device BlendBuf& _2506 [[buffer(2)]], texture2d image [[texture(3)]], texture2d image_atlas [[texture(4)]], texture2d gradients [[texture(5)]], uint3 gl_WorkGroupID [[threadgroup_position_in_grid]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]]) { uint tile_ix = (gl_WorkGroupID.y * _1681.conf.width_in_tiles) + gl_WorkGroupID.x; Alloc param; @@ -1066,14 +1073,13 @@ kernel void main0(device Memory& v_297 [[buffer(0)]], const device ConfigBuf& _1 rgba[i] = float4(0.0); } uint clip_depth = 0u; - bool mem_ok = v_297.mem_error == 0u; spvUnsafeArray df; TileSegRef tile_seg_ref; spvUnsafeArray area; spvUnsafeArray, 4> blend_stack; uint base_ix_1; uint bg_rgba; - while (mem_ok) + while (true) { Alloc param_3 = cmd_alloc; CmdRef param_4 = cmd_ref; @@ -1098,7 +1104,7 @@ kernel void main0(device Memory& v_297 [[buffer(0)]], const device ConfigBuf& _1 { uint param_7 = tile_seg_ref.offset; uint param_8 = 24u; - bool param_9 = mem_ok; + bool param_9 = true; 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_297); @@ -1134,7 +1140,7 @@ kernel void main0(device Memory& v_297 [[buffer(0)]], const device ConfigBuf& _1 { uint param_15 = tile_seg_ref.offset; uint param_16 = 24u; - bool param_17 = mem_ok; + bool param_17 = true; 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_297); @@ -1218,10 +1224,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 _2264 = fromsRGB(param_29); - fg_rgba.x = _2264.x; - fg_rgba.y = _2264.y; - fg_rgba.z = _2264.z; + float3 _2257 = fromsRGB(param_29); + fg_rgba.x = _2257.x; + fg_rgba.y = _2257.y; + fg_rgba.z = _2257.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; } @@ -1244,10 +1250,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 _2374 = fromsRGB(param_33); - fg_rgba_1.x = _2374.x; - fg_rgba_1.y = _2374.y; - fg_rgba_1.z = _2374.z; + float3 _2367 = fromsRGB(param_33); + fg_rgba_1.x = _2367.x; + fg_rgba_1.y = _2367.y; + fg_rgba_1.z = _2367.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; } @@ -1278,8 +1284,8 @@ kernel void main0(device Memory& v_297 [[buffer(0)]], const device ConfigBuf& _1 for (uint k_12 = 0u; k_12 < 8u; k_12++) { float4 param_38 = float4(rgba[k_12]); - uint _2479 = packsRGB(param_38); - blend_stack[clip_depth][k_12] = _2479; + uint _2472 = packsRGB(param_38); + blend_stack[clip_depth][k_12] = _2472; rgba[k_12] = float4(0.0); } } @@ -1289,8 +1295,8 @@ kernel void main0(device Memory& v_297 [[buffer(0)]], const device ConfigBuf& _1 for (uint k_13 = 0u; k_13 < 8u; k_13++) { float4 param_39 = float4(rgba[k_13]); - uint _2522 = packsRGB(param_39); - v_297.memory[base_ix + k_13] = _2522; + uint _2519 = packsRGB(param_39); + _2506.blend_mem[base_ix + k_13] = _2519; rgba[k_13] = float4(0.0); } } @@ -1316,7 +1322,7 @@ kernel void main0(device Memory& v_297 [[buffer(0)]], const device ConfigBuf& _1 } else { - bg_rgba = v_297.memory[base_ix_1 + k_14]; + bg_rgba = _2506.blend_mem[base_ix_1 + k_14]; } uint param_42 = bg_rgba; float4 bg = unpacksRGB(param_42); diff --git a/piet-gpu/shader/gen/kernel4.spv b/piet-gpu/shader/gen/kernel4.spv index c38894159a01685a4f3a553e68d4dac6c41b07f1..f9198c3a4fbf266f6ea52255db6b8a9f9d3efa2b 100644 GIT binary patch literal 66368 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 P^X(Y0`8*fJo{Rqns)KQL literal 66224 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 vgZcY#@CP`!=S>`JnT~_^`2kqA00&d9VKqK3uE+ literal 14564 zcmeHtd010d*YC-6l0Xs?CKINFQ3S*jKt@Ruz<`2^a~x_DqKJw#ic*KvX21|MN>HF6 z4#BDTs+Cl$Vr@-Gl&Gj^sc+iywvnQxmbO5x1#8>8Pe^R<_kQ<2&v)-X-ydHdlAOKv zZ>_!dI&0d8#$8!MhZ^lfWd2 z3_%g#JzqEjApsiX{D7bt^K-ebODAd0e;60eUxb(d96@>hlh>c%Mfe*Xm4ydyR3DVi zbdAB6lZMhg(E)g&y8iv;ro%2G4t%3;tZVG1qw>-Bf25;h_ZwwFG49v=1%d@#U_mj^ z>Sv%tj%Y>!st_FjE&zH~w&|--3Isg`G*1=BDaQxQ5tZS!0vmn?OixJLhpD7Q5=g8N z{O%$Jb2>I_pJ$epp5U8GV&;1!6lwGHzMO2K_5{RA$m-9d=^5eHLcv_6?veWOE<9HV z&jrRn?GvbTpk^cTv8`0i5PFH@U_OJ3M$t=*9-0Ag=)Qea;w(-9$+_)n4g@U(w1hA% znX_^y-Y5KcCHVNJvPJLfU7*u>R$2?_t!5IR40${unG6&QLg(TNNm7K8zDq*UNSJkX zW+r86SwQ?d9U)mGi?fzi-<(nw=m%yjL71$&nU=?M?AducNJ*9~gJaUnM7{+9LJAl7 zixnCPxRjN|Xt_)PhZmOP1zdxfrPB@n>G0`3&UOzkF4`iMf3TdN!uU|M`k2%ESCgSr#+BbZ!pEzD}F>P>&_K5FQ z3c;HkM6rVy%{g_D97wDnRc&n~rs#JrGwj@GB5rFXZjC0UaR@wwSh1x_W+1-CR|>uj z!bGEX_T6Zz+9a+@E~(mDf&7Su^#U-|#hcKv5qc4+wA{NU>ufR(YdJm5`IWNIS_F)f_ z!adMTW71y*6J={M=ap>c$R<7nqQd#o6F_izgUf`FMkb38l* zz!m6)Sf8A!OsQvi2F@6}zd3(ehTFQM?f z-$+PH@u@uhWgFcqhmP}^&OihR4sq;z=wGquxu3ApKRHFfG>|*!v*_>|HGg?vgXE}o zZQIf4j>dyGch;V$Z@+(M7G1N(QZy^TNL}PR-HyjlI~3EGF0(KBTyx^-w2pu?(YxBH zm314whC47gsF6c5!D0(vXJ(d?Y+?(d6|nRrp84g?oa0KcRx33-pwt4Z`082IWZxng z%x9j#97EFD+pbQzc*%%doMN1I<%4!|M+rB?mI``ct z!W5v!W$L`Z%jQ6nAjoD8>J|js&A|>q$bdOSB=06JwA%;2SpL9vt9RfeUf`E7ZNf(h z?d=y*E=|JRucX|&9;yM z@3sULBLpW*9oU7-v}I@NaG70Obem+v?IhyXyegTDxJ`yba{{M|)y1F<>d~xIhIoB5 zL>nrkCDN_IUxfzQLxVdcA;m~_##MDjcXrwZ+_bCeX_dH)t|8wFF>!kdF{PwxBluKQ z$@En+F|i_=STRZfV&76!y+Nwlz^vNX2r`l~?#Ch8j}F=|CfXo^E3&l&^|u6dIX`

MT>hqAyh$J-CcE3&k2rl*@42qN^$t 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

;ai=tAQgR2#hk;XO zXPn7Kf?6hS4+CNcWnRiX`IoJo*yW%BF(0vYs`7Zn@sGXPo?AeTCmaLMaM1AUwaBck z+Fc+BE?YA3C*ubJpaTW8hOs@9#_S)N^1<=76KK%3Yut}zUKYmL4`Obm+~#-j0&*ui+zCNKq=zbzx1`wJd5g^*#-1f#$H18eFpSZ zc3rb}spHbq}k-DLw5IZCjw0n6<*K9N3$|P zY(&QxaB0VJyF9)(cnuo7epDRI$}qIjy`lkjm&Y^3(T-{K=YWV}V*vKG<7$BAcn%tl zsxn%E+?RB(7=RUm&n__a+yJnyfQf9zybk}+5&wPBe!(m_iRB_sZ5F%^;;46}7$yH_ zapYG9Z(~uiO#98V;dH>}jH5@*m^H8BsPj$u1nX5CIavDQS8-Iiy6}KAj<_rkM>t;p ze=&}1X#ALn$(R4_`w?kP92!U6|63f{m;6`aNQ@q5{_zK8N1~~z+1S)g;U|vX7F(U< zm_I3|#G$6ck68C9S&7gcQzeJzub|2cpukZ(lsv@ZiqMB0Yje~i6gV{Xjwwm~fa0!J z_Z^vPfh!cVr{hK`yIhZz_xe%4N{rUJ9{!7x6!#pU^MXI2Xy0s5vR{O@SwWG^mB$JC zq}gHYK;JQYo2`=>$rIwAakC6H4BXqL3eYIw*?|$Da6hx~cS?qEfrJ0{EvxK5paj7+ zYRSV3mk)EXyK5LrEP8`@(q*oMB^VZ4Gsoyj0XL)p?^Cg&Er2sa5il`9sD~RSne}B+9HJ zLkGfFQU8$q$M4jvTle^*#jKp72yFQKqf8~pwsE|NN0cBJW5<}GAbthBlUs*D^{ruG z-_|h)q-v(AQ-fM)B?Q{&T4pqjvROr_-9|XFk>InAp#K!N|2D3{g1i3_?u+xdcP9}q zh7#MmiFO-t#SroB0b+K9jT6yzj^>!<>zM58Snn%Z?{^-pZ%zKK4@BXOS#@Ah<}Dj9#KwsDPX@a)5!@W^3SJnP?Ya6X|>x>MO_Dx4^ypIR)Nv=}iig3>aP_G#j@Y4ndX44E0Srj6pjje5_w6?^0k z!aLnnJCGa|C9C7*Q-y{wS1$?mm9O_*DH0I^{1=$-ip=nD)iu=TKJ383iM(WoUS4Vo z1s!nqh*9|t=z#w;b;5rr=O`Z>fzx~GjM@_13%6%p+HEgAc2 zZqh?;cIv>{0~A-OqUJ1vZFc`(u$KB@YU8I0S6Hi8;xf|!8M3iOCn9&LUM)wJTO%!Tm2})z67aO zCRh&b+^1NLiLyE(ZKlY)gc9;w{-P}EB7myr+~h>sp~&7PspKvG1s&M5eKpkM5p16x zJ}5S#kURK=73U`C`_cDtj@=;Yg?tL7E>=$ z5*TO94az9hRC|Iwrwv{P_c*};D7ZKrfN^Cg*tQ1+e}aM^rJ!JaE&yvroZt`?{Ll%O zqhM_f3V!Yc^HA`R6Z{7X=7gc(6%jykwhje1)}r94-l$|D3hvKCB?prMxH}vLFN#EU zZb!lVcTw=D6Z{4W))t`PS`;i!K*6)4Q1C4jENVi*@jj^JRVdiz1UEUsi72?t3BHSh z?M^Tc1q(`1uznV5jq@m2k&J?SP%!RG6fA2-CCgB7=$j~b2nB1dp#!kAhp|D7bAdD*1>90P9zv;4k82z#2CRWo@gXKN3^X8|QlcFI$?XY5)KL diff --git a/piet-gpu/shader/gen/kernel4_gray.hlsl b/piet-gpu/shader/gen/kernel4_gray.hlsl index ffada37..392d1f3 100644 --- a/piet-gpu/shader/gen/kernel4_gray.hlsl +++ b/piet-gpu/shader/gen/kernel4_gray.hlsl @@ -130,6 +130,7 @@ struct TileSeg struct Config { + uint mem_size; uint n_elements; uint n_pathseg; uint width_in_tiles; @@ -163,9 +164,10 @@ static const uint3 gl_WorkGroupSize = uint3(8u, 4u, 1u); RWByteAddressBuffer _297 : register(u0, space0); ByteAddressBuffer _1681 : register(t1, space0); -RWTexture2D image_atlas : register(u3, space0); -RWTexture2D gradients : register(u4, space0); -RWTexture2D image : register(u2, space0); +RWByteAddressBuffer _2506 : register(u2, space0); +RWTexture2D image_atlas : register(u4, space0); +RWTexture2D gradients : register(u5, space0); +RWTexture2D image : register(u3, space0); static uint3 gl_WorkGroupID; static uint3 gl_LocalInvocationID; @@ -206,7 +208,7 @@ uint read_mem(Alloc alloc, uint offset) { return 0u; } - uint v = _297.Load(offset * 4 + 8); + uint v = _297.Load(offset * 4 + 12); return v; } @@ -989,9 +991,9 @@ CmdJump Cmd_Jump_read(Alloc a, CmdRef ref) void comp_main() { - uint tile_ix = (gl_WorkGroupID.y * _1681.Load(8)) + gl_WorkGroupID.x; + uint tile_ix = (gl_WorkGroupID.y * _1681.Load(12)) + gl_WorkGroupID.x; Alloc _1696; - _1696.offset = _1681.Load(24); + _1696.offset = _1681.Load(28); Alloc param; param.offset = _1696.offset; uint param_1 = tile_ix * 1024u; @@ -999,7 +1001,7 @@ void comp_main() Alloc cmd_alloc = slice_mem(param, param_1, param_2); CmdRef _1705 = { cmd_alloc.offset }; CmdRef cmd_ref = _1705; - uint blend_offset = _297.Load((cmd_ref.offset >> uint(2)) * 4 + 8); + uint blend_offset = _297.Load((cmd_ref.offset >> uint(2)) * 4 + 12); cmd_ref.offset += 4u; uint2 xy_uint = uint2(gl_LocalInvocationID.x + (16u * gl_WorkGroupID.x), gl_LocalInvocationID.y + (16u * gl_WorkGroupID.y)); float2 xy = float2(xy_uint); @@ -1009,14 +1011,13 @@ void comp_main() rgba[i] = 0.0f.xxxx; } uint clip_depth = 0u; - bool mem_ok = _297.Load(4) == 0u; float df[8]; TileSegRef tile_seg_ref; float area[8]; uint blend_stack[4][8]; uint base_ix_1; uint bg_rgba; - while (mem_ok) + while (true) { Alloc param_3 = cmd_alloc; CmdRef param_4 = cmd_ref; @@ -1036,13 +1037,13 @@ void comp_main() { df[k] = 1000000000.0f; } - TileSegRef _1810 = { stroke.tile_ref }; - tile_seg_ref = _1810; + TileSegRef _1805 = { stroke.tile_ref }; + tile_seg_ref = _1805; do { uint param_7 = tile_seg_ref.offset; uint param_8 = 24u; - bool param_9 = mem_ok; + bool param_9 = true; 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); @@ -1073,13 +1074,13 @@ void comp_main() { area[k_3] = float(fill.backdrop); } - TileSegRef _1930 = { fill.tile_ref }; - tile_seg_ref = _1930; + TileSegRef _1924 = { fill.tile_ref }; + tile_seg_ref = _1924; do { uint param_15 = tile_seg_ref.offset; uint param_16 = 24u; - bool param_17 = mem_ok; + bool param_17 = true; 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); @@ -1163,10 +1164,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 _2264 = fromsRGB(param_29); - fg_rgba.x = _2264.x; - fg_rgba.y = _2264.y; - fg_rgba.z = _2264.z; + float3 _2257 = fromsRGB(param_29); + fg_rgba.x = _2257.x; + fg_rgba.y = _2257.y; + fg_rgba.z = _2257.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; } @@ -1189,10 +1190,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 _2374 = fromsRGB(param_33); - fg_rgba_1.x = _2374.x; - fg_rgba_1.y = _2374.y; - fg_rgba_1.z = _2374.z; + float3 _2367 = fromsRGB(param_33); + fg_rgba_1.x = _2367.x; + fg_rgba_1.y = _2367.y; + fg_rgba_1.z = _2367.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; } @@ -1206,9 +1207,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 _2417[8]; - fillImage(_2417, param_36, param_37); - float4 img[8] = _2417; + float4 _2410[8]; + fillImage(_2410, param_36, param_37); + float4 img[8] = _2410; for (uint k_11 = 0u; k_11 < 8u; k_11++) { float4 fg_k_3 = img[k_11] * area[k_11]; @@ -1224,8 +1225,8 @@ void comp_main() for (uint k_12 = 0u; k_12 < 8u; k_12++) { float4 param_38 = float4(rgba[k_12]); - uint _2479 = packsRGB(param_38); - blend_stack[clip_depth][k_12] = _2479; + uint _2472 = packsRGB(param_38); + blend_stack[clip_depth][k_12] = _2472; rgba[k_12] = 0.0f.xxxx; } } @@ -1235,8 +1236,8 @@ void comp_main() for (uint k_13 = 0u; k_13 < 8u; k_13++) { float4 param_39 = float4(rgba[k_13]); - uint _2522 = packsRGB(param_39); - _297.Store((base_ix + k_13) * 4 + 8, _2522); + uint _2519 = packsRGB(param_39); + _2506.Store((base_ix + k_13) * 4 + 0, _2519); rgba[k_13] = 0.0f.xxxx; } } @@ -1262,7 +1263,7 @@ void comp_main() } else { - bg_rgba = _297.Load((base_ix_1 + k_14) * 4 + 8); + bg_rgba = _2506.Load((base_ix_1 + k_14) * 4 + 0); } uint param_42 = bg_rgba; float4 bg = unpacksRGB(param_42); @@ -1279,8 +1280,8 @@ void comp_main() { Alloc param_46 = cmd_alloc; CmdRef param_47 = cmd_ref; - CmdRef _2621 = { Cmd_Jump_read(param_46, param_47).new_ref }; - cmd_ref = _2621; + CmdRef _2618 = { Cmd_Jump_read(param_46, param_47).new_ref }; + cmd_ref = _2618; 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 e174713..45e7a0e 100644 --- a/piet-gpu/shader/gen/kernel4_gray.msl +++ b/piet-gpu/shader/gen/kernel4_gray.msl @@ -178,6 +178,7 @@ struct Memory { uint mem_offset; uint mem_error; + uint blend_offset; uint memory[1]; }; @@ -188,6 +189,7 @@ struct Alloc_1 struct Config { + uint mem_size; uint n_elements; uint n_pathseg; uint width_in_tiles; @@ -222,6 +224,11 @@ struct ConfigBuf Config conf; }; +struct BlendBuf +{ + uint blend_mem[1]; +}; + constant uint3 gl_WorkGroupSize [[maybe_unused]] = uint3(8u, 4u, 1u); static inline __attribute__((always_inline)) @@ -1047,7 +1054,7 @@ 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& _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]]) +kernel void main0(device Memory& v_297 [[buffer(0)]], const device ConfigBuf& _1681 [[buffer(1)]], device BlendBuf& _2506 [[buffer(2)]], texture2d image [[texture(3)]], texture2d image_atlas [[texture(4)]], texture2d gradients [[texture(5)]], uint3 gl_WorkGroupID [[threadgroup_position_in_grid]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]]) { uint tile_ix = (gl_WorkGroupID.y * _1681.conf.width_in_tiles) + gl_WorkGroupID.x; Alloc param; @@ -1066,14 +1073,13 @@ kernel void main0(device Memory& v_297 [[buffer(0)]], const device ConfigBuf& _1 rgba[i] = float4(0.0); } uint clip_depth = 0u; - bool mem_ok = v_297.mem_error == 0u; spvUnsafeArray df; TileSegRef tile_seg_ref; spvUnsafeArray area; spvUnsafeArray, 4> blend_stack; uint base_ix_1; uint bg_rgba; - while (mem_ok) + while (true) { Alloc param_3 = cmd_alloc; CmdRef param_4 = cmd_ref; @@ -1098,7 +1104,7 @@ kernel void main0(device Memory& v_297 [[buffer(0)]], const device ConfigBuf& _1 { uint param_7 = tile_seg_ref.offset; uint param_8 = 24u; - bool param_9 = mem_ok; + bool param_9 = true; 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_297); @@ -1134,7 +1140,7 @@ kernel void main0(device Memory& v_297 [[buffer(0)]], const device ConfigBuf& _1 { uint param_15 = tile_seg_ref.offset; uint param_16 = 24u; - bool param_17 = mem_ok; + bool param_17 = true; 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_297); @@ -1218,10 +1224,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 _2264 = fromsRGB(param_29); - fg_rgba.x = _2264.x; - fg_rgba.y = _2264.y; - fg_rgba.z = _2264.z; + float3 _2257 = fromsRGB(param_29); + fg_rgba.x = _2257.x; + fg_rgba.y = _2257.y; + fg_rgba.z = _2257.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; } @@ -1244,10 +1250,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 _2374 = fromsRGB(param_33); - fg_rgba_1.x = _2374.x; - fg_rgba_1.y = _2374.y; - fg_rgba_1.z = _2374.z; + float3 _2367 = fromsRGB(param_33); + fg_rgba_1.x = _2367.x; + fg_rgba_1.y = _2367.y; + fg_rgba_1.z = _2367.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; } @@ -1278,8 +1284,8 @@ kernel void main0(device Memory& v_297 [[buffer(0)]], const device ConfigBuf& _1 for (uint k_12 = 0u; k_12 < 8u; k_12++) { float4 param_38 = float4(rgba[k_12]); - uint _2479 = packsRGB(param_38); - blend_stack[clip_depth][k_12] = _2479; + uint _2472 = packsRGB(param_38); + blend_stack[clip_depth][k_12] = _2472; rgba[k_12] = float4(0.0); } } @@ -1289,8 +1295,8 @@ kernel void main0(device Memory& v_297 [[buffer(0)]], const device ConfigBuf& _1 for (uint k_13 = 0u; k_13 < 8u; k_13++) { float4 param_39 = float4(rgba[k_13]); - uint _2522 = packsRGB(param_39); - v_297.memory[base_ix + k_13] = _2522; + uint _2519 = packsRGB(param_39); + _2506.blend_mem[base_ix + k_13] = _2519; rgba[k_13] = float4(0.0); } } @@ -1316,7 +1322,7 @@ kernel void main0(device Memory& v_297 [[buffer(0)]], const device ConfigBuf& _1 } else { - bg_rgba = v_297.memory[base_ix_1 + k_14]; + bg_rgba = _2506.blend_mem[base_ix_1 + k_14]; } uint param_42 = bg_rgba; float4 bg = unpacksRGB(param_42); diff --git a/piet-gpu/shader/gen/kernel4_gray.spv b/piet-gpu/shader/gen/kernel4_gray.spv index 17c75317fdc52c79bd1ffd7073f75e80d3b670aa..df86875a0475861f6bf6130f7e9f230df7e9ea43 100644 GIT binary patch literal 66124 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 literal 65980 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 N12&)MqS$ls{{yE|O<@24 diff --git a/piet-gpu/shader/gen/path_coarse.dxil b/piet-gpu/shader/gen/path_coarse.dxil index 9fd593ca43dc26f919b022903612dc81fad0890b..2842f0d9e87824de3f74a086d48daa1e2df16112 100644 GIT binary patch delta 4780 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 V^q;|>6%sGqC6@ER|F_`pzX7LH;K%>~ delta 4842 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 diff --git a/piet-gpu/shader/gen/path_coarse.hlsl b/piet-gpu/shader/gen/path_coarse.hlsl index 93ee8f0..106fdfc 100644 --- a/piet-gpu/shader/gen/path_coarse.hlsl +++ b/piet-gpu/shader/gen/path_coarse.hlsl @@ -3,12 +3,6 @@ struct Alloc uint offset; }; -struct MallocResult -{ - Alloc alloc; - bool failed; -}; - struct PathCubicRef { uint offset; @@ -74,6 +68,7 @@ struct SubdivResult struct Config { + uint mem_size; uint n_elements; uint n_pathseg; uint width_in_tiles; @@ -105,10 +100,10 @@ struct Config static const uint3 gl_WorkGroupSize = uint3(32u, 1u, 1u); -static const PathSegTag _721 = { 0u, 0u }; +static const PathSegTag _722 = { 0u, 0u }; -RWByteAddressBuffer _136 : register(u0, space0); -ByteAddressBuffer _710 : register(t1, space0); +RWByteAddressBuffer _143 : register(u0, space0); +ByteAddressBuffer _711 : register(t1, space0); static uint3 gl_GlobalInvocationID; struct SPIRV_Cross_Input @@ -116,6 +111,15 @@ struct SPIRV_Cross_Input uint3 gl_GlobalInvocationID : SV_DispatchThreadID; }; +static bool mem_ok; + +bool check_deps(uint dep_stage) +{ + uint _149; + _143.InterlockedOr(4, 0u, _149); + return (_149 & dep_stage) == 0u; +} + bool touch_mem(Alloc alloc, uint offset) { return true; @@ -129,7 +133,7 @@ uint read_mem(Alloc alloc, uint offset) { return 0u; } - uint v = _136.Load(offset * 4 + 8); + uint v = _143.Load(offset * 4 + 12); return v; } @@ -138,8 +142,8 @@ PathSegTag PathSeg_tag(Alloc a, PathSegRef ref) Alloc param = a; uint param_1 = ref.offset >> uint(2); uint tag_and_flags = read_mem(param, param_1); - PathSegTag _367 = { tag_and_flags & 65535u, tag_and_flags >> uint(16) }; - return _367; + PathSegTag _362 = { tag_and_flags & 65535u, tag_and_flags >> uint(16) }; + return _362; } PathCubic PathCubic_read(Alloc a, PathCubicRef ref) @@ -194,9 +198,9 @@ PathCubic PathCubic_read(Alloc a, PathCubicRef ref) PathCubic PathSeg_Cubic_read(Alloc a, PathSegRef ref) { - PathCubicRef _373 = { ref.offset + 4u }; + PathCubicRef _368 = { ref.offset + 4u }; Alloc param = a; - PathCubicRef param_1 = _373; + PathCubicRef param_1 = _368; return PathCubic_read(param, param_1); } @@ -240,8 +244,8 @@ SubdivResult estimate_subdiv(float2 p0, float2 p1, float2 p2, float sqrt_tol) val = (sqrt_tol * da) / approx_parabola_integral(param_2); } } - SubdivResult _695 = { val, a0, a2 }; - return _695; + SubdivResult _690 = { val, a0, a2 }; + return _690; } uint fill_mode_from_flags(uint flags) @@ -263,12 +267,12 @@ 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 _427 = { raw2 }; - s.tiles = _427; + TileRef _422 = { raw2 }; + s.tiles = _422; return s; } -Alloc new_alloc(uint offset, uint size, bool mem_ok) +Alloc new_alloc(uint offset, uint size, bool mem_ok_1) { Alloc a; a.offset = offset; @@ -286,33 +290,24 @@ float2 eval_quad(float2 p0, float2 p1, float2 p2, float t) return (p0 * (mt * mt)) + (((p1 * (mt * 2.0f)) + (p2 * t)) * t); } -MallocResult malloc(uint size) +uint malloc_stage(uint size, uint mem_size, uint stage) { - uint _142; - _136.InterlockedAdd(0, size, _142); - uint offset = _142; - uint _149; - _136.GetDimensions(_149); - _149 = (_149 - 8) / 4; - MallocResult r; - r.failed = (offset + size) > uint(int(_149) * 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 _158; + _143.InterlockedAdd(0, size, _158); + uint offset = _158; + if ((offset + size) > mem_size) { - uint _171; - _136.InterlockedMax(4, 1u, _171); - return r; + uint _168; + _143.InterlockedOr(4, stage, _168); + offset = 0u; } - return r; + return offset; } TileRef Tile_index(TileRef ref, uint index) { - TileRef _385 = { ref.offset + (index * 8u) }; - return _385; + TileRef _380 = { ref.offset + (index * 8u) }; + return _380; } void write_mem(Alloc alloc, uint offset, uint val) @@ -323,7 +318,7 @@ void write_mem(Alloc alloc, uint offset, uint val) { return; } - _136.Store(offset * 4 + 8, val); + _143.Store(offset * 4 + 12, val); } void TileSeg_write(Alloc a, TileSegRef ref, TileSeg s) @@ -357,30 +352,36 @@ void TileSeg_write(Alloc a, TileSegRef ref, TileSeg s) void comp_main() { - uint element_ix = gl_GlobalInvocationID.x; - PathSegRef _718 = { _710.Load(28) + (element_ix * 52u) }; - PathSegRef ref = _718; - PathSegTag tag = _721; - if (element_ix < _710.Load(4)) + mem_ok = true; + uint param = 7u; + bool _694 = check_deps(param); + if (!_694) { - Alloc _731; - _731.offset = _710.Load(28); - Alloc param; - param.offset = _731.offset; - PathSegRef param_1 = ref; - tag = PathSeg_tag(param, param_1); + return; + } + uint element_ix = gl_GlobalInvocationID.x; + PathSegRef _719 = { _711.Load(32) + (element_ix * 52u) }; + PathSegRef ref = _719; + PathSegTag tag = _722; + if (element_ix < _711.Load(8)) + { + Alloc _732; + _732.offset = _711.Load(32); + Alloc param_1; + param_1.offset = _732.offset; + PathSegRef param_2 = ref; + tag = PathSeg_tag(param_1, param_2); } - bool mem_ok = _136.Load(4) == 0u; switch (tag.tag) { case 1u: { - Alloc _748; - _748.offset = _710.Load(28); - Alloc param_2; - param_2.offset = _748.offset; - PathSegRef param_3 = ref; - PathCubic cubic = PathSeg_Cubic_read(param_2, param_3); + Alloc _745; + _745.offset = _711.Load(32); + Alloc param_3; + param_3.offset = _745.offset; + PathSegRef param_4 = ref; + PathCubic cubic = PathSeg_Cubic_read(param_3, param_4); float2 err_v = (((cubic.p2 - cubic.p1) * 3.0f) + cubic.p0) - cubic.p3; float err = (err_v.x * err_v.x) + (err_v.y * err_v.y); uint n_quads = max(uint(ceil(pow(err * 3.7037036418914794921875f, 0.16666667163372039794921875f))), 1u); @@ -392,43 +393,43 @@ void comp_main() for (uint i = 0u; i < n_quads; i++) { float t = float(i + 1u) * _step; - float2 param_4 = cubic.p0; - float2 param_5 = cubic.p1; - float2 param_6 = cubic.p2; - float2 param_7 = cubic.p3; - float param_8 = t; - float2 qp2 = eval_cubic(param_4, param_5, param_6, param_7, param_8); - float2 param_9 = cubic.p0; - float2 param_10 = cubic.p1; - float2 param_11 = cubic.p2; - float2 param_12 = cubic.p3; - float param_13 = t - (0.5f * _step); - float2 qp1 = eval_cubic(param_9, param_10, param_11, param_12, param_13); + float2 param_5 = cubic.p0; + float2 param_6 = cubic.p1; + float2 param_7 = cubic.p2; + float2 param_8 = cubic.p3; + float param_9 = t; + float2 qp2 = eval_cubic(param_5, param_6, param_7, param_8, param_9); + float2 param_10 = cubic.p0; + float2 param_11 = cubic.p1; + float2 param_12 = cubic.p2; + float2 param_13 = cubic.p3; + float param_14 = t - (0.5f * _step); + float2 qp1 = eval_cubic(param_10, param_11, param_12, param_13, param_14); qp1 = (qp1 * 2.0f) - ((qp0 + qp2) * 0.5f); - float2 param_14 = qp0; - float2 param_15 = qp1; - float2 param_16 = qp2; - float param_17 = 0.4743416607379913330078125f; - SubdivResult params = estimate_subdiv(param_14, param_15, param_16, param_17); + float2 param_15 = qp0; + float2 param_16 = qp1; + float2 param_17 = qp2; + float param_18 = 0.4743416607379913330078125f; + SubdivResult params = estimate_subdiv(param_15, param_16, param_17, param_18); keep_params[i] = params; val += params.val; qp0 = qp2; } uint n = max(uint(ceil((val * 0.5f) / 0.4743416607379913330078125f)), 1u); - uint param_18 = tag.flags; - bool is_stroke = fill_mode_from_flags(param_18) == 1u; + uint param_19 = tag.flags; + bool is_stroke = fill_mode_from_flags(param_19) == 1u; uint path_ix = cubic.path_ix; - PathRef _904 = { _710.Load(16) + (path_ix * 12u) }; - Alloc _907; - _907.offset = _710.Load(16); - Alloc param_19; - param_19.offset = _907.offset; - PathRef param_20 = _904; - Path path = Path_read(param_19, param_20); - uint param_21 = path.tiles.offset; - uint param_22 = ((path.bbox.z - path.bbox.x) * (path.bbox.w - path.bbox.y)) * 8u; - bool param_23 = mem_ok; - Alloc path_alloc = new_alloc(param_21, param_22, param_23); + PathRef _901 = { _711.Load(20) + (path_ix * 12u) }; + Alloc _904; + _904.offset = _711.Load(20); + Alloc param_20; + param_20.offset = _904.offset; + PathRef param_21 = _901; + Path path = Path_read(param_20, param_21); + uint param_22 = path.tiles.offset; + uint param_23 = ((path.bbox.z - path.bbox.x) * (path.bbox.w - path.bbox.y)) * 8u; + bool param_24 = true; + Alloc path_alloc = new_alloc(param_22, param_23, param_24); int4 bbox = int4(path.bbox); float2 p0 = cubic.p0; qp0 = cubic.p0; @@ -436,44 +437,44 @@ void comp_main() int n_out = 1; float val_sum = 0.0f; float2 p1; - float _1147; + float _1143; TileSeg tile_seg; for (uint i_1 = 0u; i_1 < n_quads; i_1++) { float t_1 = float(i_1 + 1u) * _step; - float2 param_24 = cubic.p0; - float2 param_25 = cubic.p1; - float2 param_26 = cubic.p2; - float2 param_27 = cubic.p3; - float param_28 = t_1; - float2 qp2_1 = eval_cubic(param_24, param_25, param_26, param_27, param_28); - float2 param_29 = cubic.p0; - float2 param_30 = cubic.p1; - float2 param_31 = cubic.p2; - float2 param_32 = cubic.p3; - float param_33 = t_1 - (0.5f * _step); - float2 qp1_1 = eval_cubic(param_29, param_30, param_31, param_32, param_33); + float2 param_25 = cubic.p0; + float2 param_26 = cubic.p1; + float2 param_27 = cubic.p2; + float2 param_28 = cubic.p3; + float param_29 = t_1; + float2 qp2_1 = eval_cubic(param_25, param_26, param_27, param_28, param_29); + float2 param_30 = cubic.p0; + float2 param_31 = cubic.p1; + float2 param_32 = cubic.p2; + float2 param_33 = cubic.p3; + float param_34 = t_1 - (0.5f * _step); + float2 qp1_1 = eval_cubic(param_30, param_31, param_32, param_33, param_34); qp1_1 = (qp1_1 * 2.0f) - ((qp0 + qp2_1) * 0.5f); SubdivResult params_1 = keep_params[i_1]; - float param_34 = params_1.a0; - float u0 = approx_parabola_inv_integral(param_34); - float param_35 = params_1.a2; - float u2 = approx_parabola_inv_integral(param_35); + float param_35 = params_1.a0; + float u0 = approx_parabola_inv_integral(param_35); + float param_36 = params_1.a2; + float u2 = approx_parabola_inv_integral(param_36); float uscale = 1.0f / (u2 - u0); float target = float(n_out) * v_step; for (;;) { - bool _1040 = uint(n_out) == n; - bool _1050; - if (!_1040) + bool _1036 = uint(n_out) == n; + bool _1046; + if (!_1036) { - _1050 = target < (val_sum + params_1.val); + _1046 = target < (val_sum + params_1.val); } else { - _1050 = _1040; + _1046 = _1036; } - if (_1050) + if (_1046) { if (uint(n_out) == n) { @@ -483,14 +484,14 @@ void comp_main() { float u = (target - val_sum) / params_1.val; float a = lerp(params_1.a0, params_1.a2, u); - float param_36 = a; - float au = approx_parabola_inv_integral(param_36); + float param_37 = a; + float au = approx_parabola_inv_integral(param_37); float t_2 = (au - u0) * uscale; - float2 param_37 = qp0; - float2 param_38 = qp1_1; - float2 param_39 = qp2_1; - float param_40 = t_2; - p1 = eval_quad(param_37, param_38, param_39, param_40); + float2 param_38 = qp0; + float2 param_39 = qp1_1; + float2 param_40 = qp2_1; + float param_41 = t_2; + p1 = eval_quad(param_38, param_39, param_40, param_41); } float xmin = min(p0.x, p1.x) - cubic.stroke.x; float xmax = max(p0.x, p1.x) + cubic.stroke.x; @@ -500,13 +501,13 @@ void comp_main() float dy = p1.y - p0.y; if (abs(dy) < 9.999999717180685365747194737196e-10f) { - _1147 = 1000000000.0f; + _1143 = 1000000000.0f; } else { - _1147 = dx / dy; + _1143 = dx / dy; } - float invslope = _1147; + float invslope = _1143; float c = (cubic.stroke.x + (abs(invslope) * (8.0f + cubic.stroke.y))) * 0.0625f; float b = invslope; float a_1 = (p0.x - ((p0.y - 8.0f) * b)) * 0.0625f; @@ -522,14 +523,20 @@ void comp_main() int stride = bbox.z - bbox.x; int base = ((y0 - bbox.y) * stride) - bbox.x; uint n_tile_alloc = uint((x1 - x0) * (y1 - y0)); - uint param_41 = n_tile_alloc * 24u; - MallocResult _1263 = malloc(param_41); - MallocResult tile_alloc = _1263; - if (tile_alloc.failed || (!mem_ok)) + uint malloc_size = n_tile_alloc * 24u; + uint param_42 = malloc_size; + uint param_43 = _711.Load(0); + uint param_44 = 4u; + uint _1265 = malloc_stage(param_42, param_43, param_44); + uint tile_offset = _1265; + if (tile_offset == 0u) { - return; + mem_ok = false; } - uint tile_offset = tile_alloc.alloc.offset; + uint param_45 = tile_offset; + uint param_46 = malloc_size; + bool param_47 = true; + Alloc tile_alloc = new_alloc(param_45, param_46, param_47); int xray = int(floor(p0.x * 0.0625f)); int last_xray = int(floor(p1.x * 0.0625f)); if (p0.y > p1.y) @@ -542,39 +549,34 @@ void comp_main() { float tile_y0 = float(y * 16); int xbackdrop = max((xray + 1), bbox.x); - bool _1319 = !is_stroke; - bool _1329; - if (_1319) + bool _1322 = !is_stroke; + bool _1332; + if (_1322) { - _1329 = min(p0.y, p1.y) < tile_y0; + _1332 = min(p0.y, p1.y) < tile_y0; } else { - _1329 = _1319; + _1332 = _1322; } - bool _1336; - if (_1329) + bool _1339; + if (_1332) { - _1336 = xbackdrop < bbox.z; + _1339 = xbackdrop < bbox.z; } else { - _1336 = _1329; + _1339 = _1332; } - if (_1336) + if (_1339) { int backdrop = (p1.y < p0.y) ? 1 : (-1); - TileRef param_42 = path.tiles; - uint param_43 = uint(base + xbackdrop); - TileRef tile_ref = Tile_index(param_42, param_43); + TileRef param_48 = path.tiles; + uint param_49 = uint(base + xbackdrop); + TileRef tile_ref = Tile_index(param_48, param_49); uint tile_el = tile_ref.offset >> uint(2); - Alloc param_44 = path_alloc; - uint param_45 = tile_el + 1u; - if (touch_mem(param_44, param_45)) - { - uint _1374; - _136.InterlockedAdd((tile_el + 1u) * 4 + 8, uint(backdrop), _1374); - } + uint _1369; + _143.InterlockedAdd((tile_el + 1u) * 4 + 12, uint(backdrop), _1369); } int next_xray = last_xray; if (y < (y1 - 1)) @@ -592,20 +594,15 @@ void comp_main() for (int x = xx0; x < xx1; x++) { float tile_x0 = float(x * 16); - TileRef _1454 = { path.tiles.offset }; - TileRef param_46 = _1454; - uint param_47 = uint(base + x); - TileRef tile_ref_1 = Tile_index(param_46, param_47); + TileRef _1449 = { path.tiles.offset }; + TileRef param_50 = _1449; + uint param_51 = uint(base + x); + TileRef tile_ref_1 = Tile_index(param_50, param_51); uint tile_el_1 = tile_ref_1.offset >> uint(2); uint old = 0u; - Alloc param_48 = path_alloc; - uint param_49 = tile_el_1; - if (touch_mem(param_48, param_49)) - { - uint _1477; - _136.InterlockedExchange(tile_el_1 * 4 + 8, tile_offset, _1477); - old = _1477; - } + uint _1465; + _143.InterlockedExchange(tile_el_1 * 4 + 12, tile_offset, _1465); + old = _1465; tile_seg.origin = p0; tile_seg._vector = p1 - p0; float y_edge = 0.0f; @@ -636,11 +633,14 @@ void comp_main() } tile_seg.y_edge = y_edge; tile_seg.next.offset = old; - TileSegRef _1559 = { tile_offset }; - Alloc param_50 = tile_alloc.alloc; - TileSegRef param_51 = _1559; - TileSeg param_52 = tile_seg; - TileSeg_write(param_50, param_51, param_52); + if (mem_ok) + { + TileSegRef _1550 = { tile_offset }; + Alloc param_52 = tile_alloc; + TileSegRef param_53 = _1550; + TileSeg param_54 = tile_seg; + TileSeg_write(param_52, param_53, param_54); + } tile_offset += 24u; } xc += b; diff --git a/piet-gpu/shader/gen/path_coarse.msl b/piet-gpu/shader/gen/path_coarse.msl index 26aa33a..4f59b3f 100644 --- a/piet-gpu/shader/gen/path_coarse.msl +++ b/piet-gpu/shader/gen/path_coarse.msl @@ -51,12 +51,6 @@ struct Alloc uint offset; }; -struct MallocResult -{ - Alloc alloc; - bool failed; -}; - struct PathCubicRef { uint offset; @@ -124,6 +118,7 @@ struct Memory { uint mem_offset; uint mem_error; + uint blend_offset; uint memory[1]; }; @@ -134,6 +129,7 @@ struct Alloc_1 struct Config { + uint mem_size; uint n_elements; uint n_pathseg; uint width_in_tiles; @@ -170,6 +166,13 @@ struct ConfigBuf constant uint3 gl_WorkGroupSize [[maybe_unused]] = uint3(32u, 1u, 1u); +static inline __attribute__((always_inline)) +bool check_deps(thread const uint& dep_stage, device Memory& v_143) +{ + uint _149 = atomic_fetch_or_explicit((device atomic_uint*)&v_143.mem_error, 0u, memory_order_relaxed); + return (_149 & dep_stage) == 0u; +} + static inline __attribute__((always_inline)) bool touch_mem(thread const Alloc& alloc, thread const uint& offset) { @@ -177,7 +180,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_136, constant uint& v_136BufferSize) +uint read_mem(thread const Alloc& alloc, thread const uint& offset, device Memory& v_143) { Alloc param = alloc; uint param_1 = offset; @@ -185,59 +188,59 @@ uint read_mem(thread const Alloc& alloc, thread const uint& offset, device Memor { return 0u; } - uint v = v_136.memory[offset]; + uint v = v_143.memory[offset]; return v; } static inline __attribute__((always_inline)) -PathSegTag PathSeg_tag(thread const Alloc& a, thread const PathSegRef& ref, device Memory& v_136, constant uint& v_136BufferSize) +PathSegTag PathSeg_tag(thread const Alloc& a, thread const PathSegRef& ref, device Memory& v_143) { Alloc param = a; uint param_1 = ref.offset >> uint(2); - uint tag_and_flags = read_mem(param, param_1, v_136, v_136BufferSize); + uint tag_and_flags = read_mem(param, param_1, v_143); return PathSegTag{ tag_and_flags & 65535u, tag_and_flags >> uint(16) }; } static inline __attribute__((always_inline)) -PathCubic PathCubic_read(thread const Alloc& a, thread const PathCubicRef& ref, device Memory& v_136, constant uint& v_136BufferSize) +PathCubic PathCubic_read(thread const Alloc& a, thread const PathCubicRef& ref, device Memory& v_143) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; - uint raw0 = read_mem(param, param_1, v_136, v_136BufferSize); + uint raw0 = read_mem(param, param_1, v_143); Alloc param_2 = a; uint param_3 = ix + 1u; - uint raw1 = read_mem(param_2, param_3, v_136, v_136BufferSize); + uint raw1 = read_mem(param_2, param_3, v_143); Alloc param_4 = a; uint param_5 = ix + 2u; - uint raw2 = read_mem(param_4, param_5, v_136, v_136BufferSize); + uint raw2 = read_mem(param_4, param_5, v_143); Alloc param_6 = a; uint param_7 = ix + 3u; - uint raw3 = read_mem(param_6, param_7, v_136, v_136BufferSize); + uint raw3 = read_mem(param_6, param_7, v_143); Alloc param_8 = a; uint param_9 = ix + 4u; - uint raw4 = read_mem(param_8, param_9, v_136, v_136BufferSize); + uint raw4 = read_mem(param_8, param_9, v_143); Alloc param_10 = a; uint param_11 = ix + 5u; - uint raw5 = read_mem(param_10, param_11, v_136, v_136BufferSize); + uint raw5 = read_mem(param_10, param_11, v_143); Alloc param_12 = a; uint param_13 = ix + 6u; - uint raw6 = read_mem(param_12, param_13, v_136, v_136BufferSize); + uint raw6 = read_mem(param_12, param_13, v_143); Alloc param_14 = a; uint param_15 = ix + 7u; - uint raw7 = read_mem(param_14, param_15, v_136, v_136BufferSize); + uint raw7 = read_mem(param_14, param_15, v_143); Alloc param_16 = a; uint param_17 = ix + 8u; - uint raw8 = read_mem(param_16, param_17, v_136, v_136BufferSize); + uint raw8 = read_mem(param_16, param_17, v_143); Alloc param_18 = a; uint param_19 = ix + 9u; - uint raw9 = read_mem(param_18, param_19, v_136, v_136BufferSize); + uint raw9 = read_mem(param_18, param_19, v_143); Alloc param_20 = a; uint param_21 = ix + 10u; - uint raw10 = read_mem(param_20, param_21, v_136, v_136BufferSize); + uint raw10 = read_mem(param_20, param_21, v_143); Alloc param_22 = a; uint param_23 = ix + 11u; - uint raw11 = read_mem(param_22, param_23, v_136, v_136BufferSize); + uint raw11 = read_mem(param_22, param_23, v_143); PathCubic s; s.p0 = float2(as_type(raw0), as_type(raw1)); s.p1 = float2(as_type(raw2), as_type(raw3)); @@ -250,11 +253,11 @@ PathCubic PathCubic_read(thread const Alloc& a, thread const PathCubicRef& ref, } static inline __attribute__((always_inline)) -PathCubic PathSeg_Cubic_read(thread const Alloc& a, thread const PathSegRef& ref, device Memory& v_136, constant uint& v_136BufferSize) +PathCubic PathSeg_Cubic_read(thread const Alloc& a, thread const PathSegRef& ref, device Memory& v_143) { Alloc param = a; PathCubicRef param_1 = PathCubicRef{ ref.offset + 4u }; - return PathCubic_read(param, param_1, v_136, v_136BufferSize); + return PathCubic_read(param, param_1, v_143); } static inline __attribute__((always_inline)) @@ -310,18 +313,18 @@ uint fill_mode_from_flags(thread const uint& flags) } static inline __attribute__((always_inline)) -Path Path_read(thread const Alloc& a, thread const PathRef& ref, device Memory& v_136, constant uint& v_136BufferSize) +Path Path_read(thread const Alloc& a, thread const PathRef& ref, device Memory& v_143) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; - uint raw0 = read_mem(param, param_1, v_136, v_136BufferSize); + uint raw0 = read_mem(param, param_1, v_143); Alloc param_2 = a; uint param_3 = ix + 1u; - uint raw1 = read_mem(param_2, param_3, v_136, v_136BufferSize); + uint raw1 = read_mem(param_2, param_3, v_143); Alloc param_4 = a; uint param_5 = ix + 2u; - uint raw2 = read_mem(param_4, param_5, v_136, v_136BufferSize); + uint raw2 = read_mem(param_4, param_5, v_143); Path s; s.bbox = uint4(raw0 & 65535u, raw0 >> uint(16), raw1 & 65535u, raw1 >> uint(16)); s.tiles = TileRef{ raw2 }; @@ -350,22 +353,16 @@ float2 eval_quad(thread const float2& p0, thread const float2& p1, thread const } static inline __attribute__((always_inline)) -MallocResult malloc(thread const uint& size, device Memory& v_136, constant uint& v_136BufferSize) +uint malloc_stage(thread const uint& size, thread const uint& mem_size, thread const uint& stage, device Memory& v_143) { - uint _142 = atomic_fetch_add_explicit((device atomic_uint*)&v_136.mem_offset, size, memory_order_relaxed); - uint offset = _142; - MallocResult r; - r.failed = (offset + size) > uint(int((v_136BufferSize - 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 _158 = atomic_fetch_add_explicit((device atomic_uint*)&v_143.mem_offset, size, memory_order_relaxed); + uint offset = _158; + if ((offset + size) > mem_size) { - uint _171 = atomic_fetch_max_explicit((device atomic_uint*)&v_136.mem_error, 1u, memory_order_relaxed); - return r; + uint _168 = atomic_fetch_or_explicit((device atomic_uint*)&v_143.mem_error, stage, memory_order_relaxed); + offset = 0u; } - return r; + return offset; } static inline __attribute__((always_inline)) @@ -375,7 +372,7 @@ TileRef Tile_index(thread const TileRef& ref, thread const uint& index) } static inline __attribute__((always_inline)) -void write_mem(thread const Alloc& alloc, thread const uint& offset, thread const uint& val, device Memory& v_136, constant uint& v_136BufferSize) +void write_mem(thread const Alloc& alloc, thread const uint& offset, thread const uint& val, device Memory& v_143) { Alloc param = alloc; uint param_1 = offset; @@ -383,61 +380,66 @@ void write_mem(thread const Alloc& alloc, thread const uint& offset, thread cons { return; } - v_136.memory[offset] = val; + v_143.memory[offset] = val; } static inline __attribute__((always_inline)) -void TileSeg_write(thread const Alloc& a, thread const TileSegRef& ref, thread const TileSeg& s, device Memory& v_136, constant uint& v_136BufferSize) +void TileSeg_write(thread const Alloc& a, thread const TileSegRef& ref, thread const TileSeg& s, device Memory& v_143) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; uint param_2 = as_type(s.origin.x); - write_mem(param, param_1, param_2, v_136, v_136BufferSize); + write_mem(param, param_1, param_2, v_143); Alloc param_3 = a; uint param_4 = ix + 1u; uint param_5 = as_type(s.origin.y); - write_mem(param_3, param_4, param_5, v_136, v_136BufferSize); + write_mem(param_3, param_4, param_5, v_143); Alloc param_6 = a; uint param_7 = ix + 2u; uint param_8 = as_type(s.vector.x); - write_mem(param_6, param_7, param_8, v_136, v_136BufferSize); + write_mem(param_6, param_7, param_8, v_143); Alloc param_9 = a; uint param_10 = ix + 3u; uint param_11 = as_type(s.vector.y); - write_mem(param_9, param_10, param_11, v_136, v_136BufferSize); + write_mem(param_9, param_10, param_11, v_143); Alloc param_12 = a; uint param_13 = ix + 4u; uint param_14 = as_type(s.y_edge); - write_mem(param_12, param_13, param_14, v_136, v_136BufferSize); + write_mem(param_12, param_13, param_14, v_143); Alloc param_15 = a; uint param_16 = ix + 5u; uint param_17 = s.next.offset; - write_mem(param_15, param_16, param_17, v_136, v_136BufferSize); + write_mem(param_15, param_16, param_17, v_143); } -kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device Memory& v_136 [[buffer(0)]], const device ConfigBuf& _710 [[buffer(1)]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]]) +kernel void main0(device Memory& v_143 [[buffer(0)]], const device ConfigBuf& _711 [[buffer(1)]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]]) { - constant uint& v_136BufferSize = spvBufferSizeConstants[0]; - uint element_ix = gl_GlobalInvocationID.x; - PathSegRef ref = PathSegRef{ _710.conf.pathseg_alloc.offset + (element_ix * 52u) }; - PathSegTag tag = PathSegTag{ 0u, 0u }; - if (element_ix < _710.conf.n_pathseg) + bool mem_ok = true; + uint param = 7u; + bool _694 = check_deps(param, v_143); + if (!_694) { - Alloc param; - param.offset = _710.conf.pathseg_alloc.offset; - PathSegRef param_1 = ref; - tag = PathSeg_tag(param, param_1, v_136, v_136BufferSize); + return; + } + uint element_ix = gl_GlobalInvocationID.x; + PathSegRef ref = PathSegRef{ _711.conf.pathseg_alloc.offset + (element_ix * 52u) }; + PathSegTag tag = PathSegTag{ 0u, 0u }; + if (element_ix < _711.conf.n_pathseg) + { + Alloc param_1; + param_1.offset = _711.conf.pathseg_alloc.offset; + PathSegRef param_2 = ref; + tag = PathSeg_tag(param_1, param_2, v_143); } - bool mem_ok = v_136.mem_error == 0u; switch (tag.tag) { case 1u: { - Alloc param_2; - param_2.offset = _710.conf.pathseg_alloc.offset; - PathSegRef param_3 = ref; - PathCubic cubic = PathSeg_Cubic_read(param_2, param_3, v_136, v_136BufferSize); + Alloc param_3; + param_3.offset = _711.conf.pathseg_alloc.offset; + PathSegRef param_4 = ref; + PathCubic cubic = PathSeg_Cubic_read(param_3, param_4, v_143); float2 err_v = (((cubic.p2 - cubic.p1) * 3.0) + cubic.p0) - cubic.p3; float err = (err_v.x * err_v.x) + (err_v.y * err_v.y); uint n_quads = max(uint(ceil(pow(err * 3.7037036418914794921875, 0.16666667163372039794921875))), 1u); @@ -449,40 +451,40 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M for (uint i = 0u; i < n_quads; i++) { float t = float(i + 1u) * _step; - float2 param_4 = cubic.p0; - float2 param_5 = cubic.p1; - float2 param_6 = cubic.p2; - float2 param_7 = cubic.p3; - float param_8 = t; - float2 qp2 = eval_cubic(param_4, param_5, param_6, param_7, param_8); - float2 param_9 = cubic.p0; - float2 param_10 = cubic.p1; - float2 param_11 = cubic.p2; - float2 param_12 = cubic.p3; - float param_13 = t - (0.5 * _step); - float2 qp1 = eval_cubic(param_9, param_10, param_11, param_12, param_13); + float2 param_5 = cubic.p0; + float2 param_6 = cubic.p1; + float2 param_7 = cubic.p2; + float2 param_8 = cubic.p3; + float param_9 = t; + float2 qp2 = eval_cubic(param_5, param_6, param_7, param_8, param_9); + float2 param_10 = cubic.p0; + float2 param_11 = cubic.p1; + float2 param_12 = cubic.p2; + float2 param_13 = cubic.p3; + float param_14 = t - (0.5 * _step); + float2 qp1 = eval_cubic(param_10, param_11, param_12, param_13, param_14); qp1 = (qp1 * 2.0) - ((qp0 + qp2) * 0.5); - float2 param_14 = qp0; - float2 param_15 = qp1; - float2 param_16 = qp2; - float param_17 = 0.4743416607379913330078125; - SubdivResult params = estimate_subdiv(param_14, param_15, param_16, param_17); + float2 param_15 = qp0; + float2 param_16 = qp1; + float2 param_17 = qp2; + float param_18 = 0.4743416607379913330078125; + SubdivResult params = estimate_subdiv(param_15, param_16, param_17, param_18); keep_params[i] = params; val += params.val; qp0 = qp2; } uint n = max(uint(ceil((val * 0.5) / 0.4743416607379913330078125)), 1u); - uint param_18 = tag.flags; - bool is_stroke = fill_mode_from_flags(param_18) == 1u; + uint param_19 = tag.flags; + bool is_stroke = fill_mode_from_flags(param_19) == 1u; uint path_ix = cubic.path_ix; - Alloc param_19; - param_19.offset = _710.conf.tile_alloc.offset; - PathRef param_20 = PathRef{ _710.conf.tile_alloc.offset + (path_ix * 12u) }; - Path path = Path_read(param_19, param_20, v_136, v_136BufferSize); - uint param_21 = path.tiles.offset; - uint param_22 = ((path.bbox.z - path.bbox.x) * (path.bbox.w - path.bbox.y)) * 8u; - bool param_23 = mem_ok; - Alloc path_alloc = new_alloc(param_21, param_22, param_23); + Alloc param_20; + param_20.offset = _711.conf.tile_alloc.offset; + PathRef param_21 = PathRef{ _711.conf.tile_alloc.offset + (path_ix * 12u) }; + Path path = Path_read(param_20, param_21, v_143); + uint param_22 = path.tiles.offset; + uint param_23 = ((path.bbox.z - path.bbox.x) * (path.bbox.w - path.bbox.y)) * 8u; + bool param_24 = true; + Alloc path_alloc = new_alloc(param_22, param_23, param_24); int4 bbox = int4(path.bbox); float2 p0 = cubic.p0; qp0 = cubic.p0; @@ -490,44 +492,44 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M int n_out = 1; float val_sum = 0.0; float2 p1; - float _1147; + float _1143; TileSeg tile_seg; for (uint i_1 = 0u; i_1 < n_quads; i_1++) { float t_1 = float(i_1 + 1u) * _step; - float2 param_24 = cubic.p0; - float2 param_25 = cubic.p1; - float2 param_26 = cubic.p2; - float2 param_27 = cubic.p3; - float param_28 = t_1; - float2 qp2_1 = eval_cubic(param_24, param_25, param_26, param_27, param_28); - float2 param_29 = cubic.p0; - float2 param_30 = cubic.p1; - float2 param_31 = cubic.p2; - float2 param_32 = cubic.p3; - float param_33 = t_1 - (0.5 * _step); - float2 qp1_1 = eval_cubic(param_29, param_30, param_31, param_32, param_33); + float2 param_25 = cubic.p0; + float2 param_26 = cubic.p1; + float2 param_27 = cubic.p2; + float2 param_28 = cubic.p3; + float param_29 = t_1; + float2 qp2_1 = eval_cubic(param_25, param_26, param_27, param_28, param_29); + float2 param_30 = cubic.p0; + float2 param_31 = cubic.p1; + float2 param_32 = cubic.p2; + float2 param_33 = cubic.p3; + float param_34 = t_1 - (0.5 * _step); + float2 qp1_1 = eval_cubic(param_30, param_31, param_32, param_33, param_34); qp1_1 = (qp1_1 * 2.0) - ((qp0 + qp2_1) * 0.5); SubdivResult params_1 = keep_params[i_1]; - float param_34 = params_1.a0; - float u0 = approx_parabola_inv_integral(param_34); - float param_35 = params_1.a2; - float u2 = approx_parabola_inv_integral(param_35); + float param_35 = params_1.a0; + float u0 = approx_parabola_inv_integral(param_35); + float param_36 = params_1.a2; + float u2 = approx_parabola_inv_integral(param_36); float uscale = 1.0 / (u2 - u0); float target = float(n_out) * v_step; for (;;) { - bool _1040 = uint(n_out) == n; - bool _1050; - if (!_1040) + bool _1036 = uint(n_out) == n; + bool _1046; + if (!_1036) { - _1050 = target < (val_sum + params_1.val); + _1046 = target < (val_sum + params_1.val); } else { - _1050 = _1040; + _1046 = _1036; } - if (_1050) + if (_1046) { if (uint(n_out) == n) { @@ -537,14 +539,14 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M { float u = (target - val_sum) / params_1.val; float a = mix(params_1.a0, params_1.a2, u); - float param_36 = a; - float au = approx_parabola_inv_integral(param_36); + float param_37 = a; + float au = approx_parabola_inv_integral(param_37); float t_2 = (au - u0) * uscale; - float2 param_37 = qp0; - float2 param_38 = qp1_1; - float2 param_39 = qp2_1; - float param_40 = t_2; - p1 = eval_quad(param_37, param_38, param_39, param_40); + float2 param_38 = qp0; + float2 param_39 = qp1_1; + float2 param_40 = qp2_1; + float param_41 = t_2; + p1 = eval_quad(param_38, param_39, param_40, param_41); } float xmin = fast::min(p0.x, p1.x) - cubic.stroke.x; float xmax = fast::max(p0.x, p1.x) + cubic.stroke.x; @@ -554,13 +556,13 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M float dy = p1.y - p0.y; if (abs(dy) < 9.999999717180685365747194737196e-10) { - _1147 = 1000000000.0; + _1143 = 1000000000.0; } else { - _1147 = dx / dy; + _1143 = dx / dy; } - float invslope = _1147; + float invslope = _1143; float c = (cubic.stroke.x + (abs(invslope) * (8.0 + cubic.stroke.y))) * 0.0625; float b = invslope; float a_1 = (p0.x - ((p0.y - 8.0) * b)) * 0.0625; @@ -576,14 +578,20 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M int stride = bbox.z - bbox.x; int base = ((y0 - bbox.y) * stride) - bbox.x; uint n_tile_alloc = uint((x1 - x0) * (y1 - y0)); - uint param_41 = n_tile_alloc * 24u; - MallocResult _1263 = malloc(param_41, v_136, v_136BufferSize); - MallocResult tile_alloc = _1263; - if (tile_alloc.failed || (!mem_ok)) + uint malloc_size = n_tile_alloc * 24u; + uint param_42 = malloc_size; + uint param_43 = _711.conf.mem_size; + uint param_44 = 4u; + uint _1265 = malloc_stage(param_42, param_43, param_44, v_143); + uint tile_offset = _1265; + if (tile_offset == 0u) { - return; + mem_ok = false; } - uint tile_offset = tile_alloc.alloc.offset; + uint param_45 = tile_offset; + uint param_46 = malloc_size; + bool param_47 = true; + Alloc tile_alloc = new_alloc(param_45, param_46, param_47); int xray = int(floor(p0.x * 0.0625)); int last_xray = int(floor(p1.x * 0.0625)); if (p0.y > p1.y) @@ -596,38 +604,33 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M { float tile_y0 = float(y * 16); int xbackdrop = max((xray + 1), bbox.x); - bool _1319 = !is_stroke; - bool _1329; - if (_1319) + bool _1322 = !is_stroke; + bool _1332; + if (_1322) { - _1329 = fast::min(p0.y, p1.y) < tile_y0; + _1332 = fast::min(p0.y, p1.y) < tile_y0; } else { - _1329 = _1319; + _1332 = _1322; } - bool _1336; - if (_1329) + bool _1339; + if (_1332) { - _1336 = xbackdrop < bbox.z; + _1339 = xbackdrop < bbox.z; } else { - _1336 = _1329; + _1339 = _1332; } - if (_1336) + if (_1339) { int backdrop = (p1.y < p0.y) ? 1 : (-1); - TileRef param_42 = path.tiles; - uint param_43 = uint(base + xbackdrop); - TileRef tile_ref = Tile_index(param_42, param_43); + TileRef param_48 = path.tiles; + uint param_49 = uint(base + xbackdrop); + TileRef tile_ref = Tile_index(param_48, param_49); uint tile_el = tile_ref.offset >> uint(2); - Alloc param_44 = path_alloc; - uint param_45 = tile_el + 1u; - if (touch_mem(param_44, param_45)) - { - uint _1374 = atomic_fetch_add_explicit((device atomic_uint*)&v_136.memory[tile_el + 1u], uint(backdrop), memory_order_relaxed); - } + uint _1369 = atomic_fetch_add_explicit((device atomic_uint*)&v_143.memory[tile_el + 1u], uint(backdrop), memory_order_relaxed); } int next_xray = last_xray; if (y < (y1 - 1)) @@ -645,18 +648,13 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M for (int x = xx0; x < xx1; x++) { float tile_x0 = float(x * 16); - TileRef param_46 = TileRef{ path.tiles.offset }; - uint param_47 = uint(base + x); - TileRef tile_ref_1 = Tile_index(param_46, param_47); + TileRef param_50 = TileRef{ path.tiles.offset }; + uint param_51 = uint(base + x); + TileRef tile_ref_1 = Tile_index(param_50, param_51); uint tile_el_1 = tile_ref_1.offset >> uint(2); uint old = 0u; - Alloc param_48 = path_alloc; - uint param_49 = tile_el_1; - if (touch_mem(param_48, param_49)) - { - uint _1477 = atomic_exchange_explicit((device atomic_uint*)&v_136.memory[tile_el_1], tile_offset, memory_order_relaxed); - old = _1477; - } + uint _1465 = atomic_exchange_explicit((device atomic_uint*)&v_143.memory[tile_el_1], tile_offset, memory_order_relaxed); + old = _1465; tile_seg.origin = p0; tile_seg.vector = p1 - p0; float y_edge = 0.0; @@ -687,10 +685,13 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M } tile_seg.y_edge = y_edge; tile_seg.next.offset = old; - Alloc param_50 = tile_alloc.alloc; - TileSegRef param_51 = TileSegRef{ tile_offset }; - TileSeg param_52 = tile_seg; - TileSeg_write(param_50, param_51, param_52, v_136, v_136BufferSize); + if (mem_ok) + { + Alloc param_52 = tile_alloc; + TileSegRef param_53 = TileSegRef{ tile_offset }; + TileSeg param_54 = tile_seg; + TileSeg_write(param_52, param_53, param_54, v_143); + } tile_offset += 24u; } xc += b; diff --git a/piet-gpu/shader/gen/path_coarse.spv b/piet-gpu/shader/gen/path_coarse.spv index 5e6beda2d5384eb658b12761ac78a7207338d8af..bd32fc2d2e26c9f046ac6e5b97e8cb7ee3d81463 100644 GIT binary patch literal 39708 zcmbWA2b^9-`L+-2CiLEW=%GsJi1ZSA?*hvv*(3{_-LTmdia;mkkk=zg0{8=A1`mRoJ6!{Sv(%TJ#r@EJkfNtx2! z+ppoS`KxM4bhV`@qbT}XI`|*v>Rw1Ey^h_lYwUpsj@@sMuJKc+c1;^PrLU)}ueZOa zYeMf}&-kI<89n+fSorn!kMEm4p>!C5N7=u8VfxsmuWw*HwHeC&3{0Fjt!Jo0S%BQD zs=sGuSGRtnr;pj5|BoB9J+{tj(P6%w)nf2zy{D3mZ9AC*#@jQcYv3gL$Z8q*_{lxv zPwJY`Gj*E5)JIfHqoXjg?nyQt!B|$ZZL8C^Tz6f!>8zH=KCiD4)e8F4*F3GWT2Y_5 zF&D1ZfDa8!A3wPZ&(YI{2B(i7+N3oBn@k_m8d*E<)$nU|P3<^Vr=B+_i&X2vXAbrb z_581KT4}c0uGNUO_OMtT)jIGQ-F^5jTx|#*?CGBHzlOzbKBKA2{5F8k%Wt7-Q~1Q* zzP_$01FV6Gg9B5#CiZnts%N|%V-tN8sl7HX+Jm}>ChsgMyfcgWN&+WqM7`kYD*UA?o2F|rk71lrJG zcmFg+KCV-Jy$!j711GUyMsNph3!j^Rm$UdkFK~Uu=ejY>)`h1jF*>TPsk>{u4fPKrxv@K|vEajc`+A%V=R)ph-drqF z?FZMVtG9nb&#VloZZ+?AYxT1azU{m_t9`+(Ce*I=1E`&w^daXC>I2~PVck7->fpevuBqLF-Qx!Ox>?dgJ(C8z`$o4@Z^d$) zF18W85zKtwHZ$J0-Hf^IMpmbQ51l@4Lhp=2dZtb9Yh6$GQguH*C&FDD-Su9p-F4C3 z8q31fnc$vjL%mbFc|=WX1spaxrtLUS!!PrFy11T~kBD2bMpS2jr=2`F)HO8V)X}c9 zI-7dlbG@TF7v8@9oz*4a{d=Yi43d<4xZF?6zkaWX?ikd21_xc@crVcMcP!)jdip1H z<*sS3bz`~KY14}D7(NE~V_u)7P7C?Xa4(wIS$<1{f3LxRFpPIpKZ1LG?B_vhpFqZW z7(CcLli6?cN2tqw{@CD;!SQEy+x|~B>`yiLU*Pz21={}4HSEtf_zQ6Sx1eg}_m77C znd-1grl{);#4 zOE&n@ZU1fKzkI{KVuP>T_TMi4t2gYU8hov`{}?Z@*L%H&eRP9wSo?c{_20B%-)tD~ zsJ4K&_r;Obv0$G0UEQqqdG7?B)d|DebXMaU{Nx6oHjH;vXTq~y&jE8i=C0Q{!+bld z3mW{ww*TDqdP&3nu?D}a?LT+DUeT~$IgEEypN6-`-%;HJPM)_9^Xsg>)!=tF_+1Tt zcZ1*4;6H8fpEvje4gOGrKiuHIYw*V#{K*FYQ-eR<;LkSrbHjK?^#XhfPX+g*`Pd|b zcLYz^Y)nhvRXk?%7T#0LL)A684|x3Gz_iT!vG7@}2xFZn=IZG;3p{Oncc0H+ZD+%M z&S*OaJnug5sOD&^+nwLAT?lV~uj!~R15fBS#)#@laO-(ecVgV@(Pm9)e=nBb1fSPW zXLZLgKBD>_yr-{cN>Be#>sx`}7yUjxsjq8n-@v%;zPK*9cd-r-A_hN6q zmvmP5fm^Ra*nEeQ`zfCtKSJAWpnqa->pgyCCHLd=D&H}Ej;V85s{XDzBPKYyP5OCl z7@9n-$M+VWZ~FTTo7p?TFFO5QL+uyR*gCOI?&+O0nW4p)cq6ds-u^N^uOGh)jl(7tsVSlN?{|V>4 zuq*Fh@3eWVuLZe*`deQlrnPcf7M{IkIq=E6)SA1R%Z}20-*>jA4 zba-oAoz;gM{I~}18pcOdqxs#)H8LICJB{4^;oX)5@AzJ=(8vYjz<0Gm|(!Rd4jq#abKAqLo4gUECzZRbF{;ty-wAatDo4_*| zf~&&Vx5E3o2Bx>yLT7cGcD|-gn?415NA*p3*39?8Su^*7Pv%RKG42DGYv%q2|5=0o zqQM^=#yhHq;8`<|46}7sk2d%d4gOSvKi%Ljg}2sBNA)s%dObI<#MZi29o6gF>gW3# z!)%?^+uDj}_&=e;5#(6bx#}Wszv8!DYT&}Q?Yhb z%Yk(^-!;^ICt~7kyEc5*I9?4V3=VLMx3nG63aO>-nRdPu*0J_QE6097gCCSOJ)YN( zsE&bq?lvz^zNf{9i)Vh5;Ir!UI@`>Iv((b073Vay?pcM#_cz>W1)QOgE#IWBNve-Y3CdjZ9iXW-^V6@HU*7v|Yku~j=9tu$EHtLH zr7c@%&Xaz=6Q-^2_iD-6c+Q8~C`$Z%r&n92(0rd)8(nCQUv1+;GgmdXrMdBZZ&%y0 z(0pfC+qTerS6BN`p*c>qoeRzPa<$zH&G&J&y$a3uaJBsk%{fv#sL*^5S39iGd=FPU zs?dD@Ry(%PoL{vQ3e9(IwF!mhJGR>7Li62Pt*@nZ&V7H*HOu?7K7L%IY8@@y*?PBL zt7U1gQQx&)qpmO4?B*;2uaWsI!wSQU-Jce>*V}UVxK2h<{EULTMl9;f(!%wj?wU}S zuTBKlgFb8WU;B`!t-fp0#_OcNx_-{HZQ^HbZ0A92j5S&3u20)Vx9ys6^N-e!Iigx0 z&6v^c*Y%iw%+<9hw=W)%t-jQj$Hwaldd1I!JF6|I<@U2WBX+&2mBly~HFMpHT0i?Y zw*C3DzVx>}*j&|Crw`Y5V%UBMxSH+tRoj(1G1ZJYmO3%_0vl6J|GjG*UH=2n;(s7m ze>KPH+Sle@VonEBt0mqcU^R2Ht?`bePCV}kKk z#?Y=`H?@AokdLdmvDU;gzP9O?qR*PFk`v#@rcc}6Sq*}XBVV1lI;G}niGM0sJ+af? zTxO#?Zr9`XH9x!7Heg=V&!KoPoku;2G9P85n$H3ISq{t`U?+Fzr%b`t*` zu+O0IPC6^|SrqQ|jeS|T^A^4;+&v?F9k_cz_{MPe7{|Lg*jU~l+MV4CrZ-n{mc;Y;FY{Hwsmcm2z+tGV}w{kdjdM60T^b_##J#jBmemvAzxo#*nk z;rG3M&HRsdo`%_4{o_+y$ec1ljV6Ufp?8dAL>xa<1M=bh03g`c=G36R9%mkjc z(3H8?a8dY8U)`{E4a|FKxN9cH0wUhCV0NbZ~O6*6W{q6BrcU%>FH&~l7^dDFI ztLtz4v%!l}drhwaJ5JZQ{$H&9)#bO;T%Yte9p|p8AKfhcTpM$Y9e!bppS45!dmiq4 z$A-+mbNL2bn=yAE;r;U7d+{AZf}_wkCR5jy?-^?DGnTEHXXmrsWqU2Yg+iFt8gyV=Uim@BtbH#Au zd#+gWT^ii8#nSHCV#z&Q3^%@Ki{Y+!&lbb&&$Gpnd$w3|&lbat=h@<14jx}{b6v1< z^Wm9dxa0L)G2HvtbH#A&w-sF7bH&o`*hEV*ZmC4ZyAJ#Q@So;QX&p4Hf# z!tKv9$C7*QSaQ!EOYZq&$vuAzH@;_(CHD-n+iW_ z$vu-Sx#y83_e`?no=b+?pJ$Wdj>ogfl6x*0Ztb~b$vu}Wx#yDMe$Vu5GTi<=mkjrQ z^;|OC>+jiQxZhPhn+!LeXOr?Bd0#r4`kWg3UgP(j?ReYqJ?dNVWvJC}J{4wO@g4r|ls6{~&%3g4ONccQ?7%_cq_R z6aTkhi;IklC0^3$S?fwn6o#!RV z;cd8ja`+F}w(5@6?-6Ro7)QJRg4HgsV|ae>E?hl6@4b%?p(^$Bh+~`i;I>mwyZOP! z_B)sP>DPg#9-q$l@fm@pp4cP7wo{*7_qPDpKD9Zn*7qTB`dJ99mKck`)%@PPD0h#! zECzOcu1wMHcj!e~C)yUTZ9Y5on?n90!ApR(8AHBg?YBW~bFAj$_c3kequ)|swX|CX zY~SnEHot49oi?%G;Vxnf&XwzOd3bZ3tbnGjzu)oX>2oEpeNL_Cer2%Q1@#=R0`{y( z-S&PbR1^Ds&^6&+uo~F=*ZK`&twBAC;z#?MwcR>>uLU+n_}XA|$$q&GSRZxwNcrj% zW80TFZPx=EEBpKUU^VADV;c=uw~g0t1F+-C_1_SzkGkXY`>k5$b`x-OZZ}0!*Wd5E z^7wBC*1x>}$Dpa}@AqMO{I>w>{}8#EqxblhXzKd=eOVs=t-<=2_x3hu>iYYATAuN4 z2X;)_{BAAZj#Eqf`5<^IwPP?Z`?9@$`fo(7Phx!tY^?Ad!R1`;q>ZBPKI44v47Q!N zjA2)Bb53_dQ@7t;sO9nB1Kga`J<-(l-|GmJ?Io%sgU4PFA<>(A4$! z3_&j5pL%CX=I{Wpb7;=yVQl^N(|>zveR6FN1gmA=KM1VmS!{d`hI`M39|HDT%w|r# zZij;PQBR!1!0OI__V~lW#@Ciy)Drg?u>EK|npz&)v0(Gm_F-yyY{!GmN854Ka&Z^+ zQIzd?TlAdp1h9Wb!`Q~qS0883p z+y{)UO|9HF*MKLt0kHjNUz!S5^Ll1qJ{hd;9Orp72=;m5^GJK1N7KOC@?06J{d^v2 z%k!uotj&4!-Ek(^ce(6eUYl8H>W*UuwcPIs+D-v)O0E7?G`}aD3RX`a)4^)#<8-k1 zn?L`^{CxyX-9ApEmgjrGnc%z=`ZJPTWBWe~oA$(+4Yqy02b=>|JDZYgbFP@8&F=yJ zeDOT6dfr3N2bX;s|2}fQ09{+&Lq7^u^ONyi2%lp?b3AhW#1~Q9m+zhatmb0y;nezT z)8`Cob#w8WTnbh*-ZPYp^i%pkeS8*fF0R4yT7M2rn{)ITYPtAo zYU7AMPkj#Uwqxe}S=<-kOHk{tpLYE&q1NU#^Jit(fir%`bP#Q>M^ir?ehu}PC~CI9 zw&u3)#`nu`*L3oApS}@IUH==XrPcttP&eI{VUXVBaOxzX^8TxJTU%c8|06-R@h|cT)Ul|8{M+&Kmd* z*cjp81usa+yWRJ|`l$PEC%=PYZ2JYI(-{Yp`R|_8_%9?twv6Eq;O3nE5l!8GAEB1V|1ofLP9H~8*Z)y!dHkOQH|O+E zXzKbuK`oE}pTW&J{R^79{!dZM#ZOZ^rp)0pVCT@B&BNIG>!<%i)cWMwJ_}aMJK1w! zwesEWukht4Y4beTYcZRB#P#tvus-UE^8#4i`OmxEi(unxOD<~0b$|Ff*!#zMID+~g zl<^dGeSF9IXRX`*C9quoaoAo3t7Wab2mK4KuKz34a^C~Ay#}61t*-rLYPH0B6KuTP z3$}R+uCD(Z)bhmpH`sXU+Fz$uGk4qm2dozU4%j}kHvbFOM?HJuyI{Z9YBT2B)M~~! zkC;@gy>X!KV?MZA`j{Vl6aLv>I^g=K8}B`AYVMDn)b454?w=#67ohmjzF=*)PX7ym zZzYD$8?WKQa5e4nMZo>o^PaURTp#tE(Jls7_uOp>YCrC^>Wfp<%uAecEeSUF@TK6l z!E^1FhI{Si5Gy{*psCNUum7@O+o^vW&G*3Nz{b|*nA5lQ>pY+JSsrY@&V&BuWxnbo zD9)StitXF$v;w%CrxoF9+MTDBz~wxx4A)29d0Ca(kNs#{g))j_KVrx2GktY%bMIIK zP2KCg8nxW98PoR0$sDZ(F6VV^xbvDdx(-|)_009U;O1Pfho+u&ygt~r>gM6k0M!y> z190=+-4IPZJ{#3O<^8xZntJlz1Z?a@xl-P9n}WH0TJQVD(_bHR7)`A`ZO4GswD~hf zdG77a!QR{I+CM<8mbP1h)xx&|m-qJ8aDCL{vkln$IrrwaaQ)Qn!=H1i>F+-KL9qL< zHh<j=H(;O0AYW_5(L_-5*UoJ_mrCxgLn7o?H(Co9k$b?X@S@gTe2Y>mlgc zX4iYtpgIYFwOaBx9^A~e3r#&fCxDx|cB82$*Ky#?tL?QX*YV)@%XI>}w%PT( z_JEC}Zm!2st0j*~;O6z6jHVu+UT|}roQS5LIXMYzJ9Yb+NUfF_Q^3vf_M@rCX8_!s zx2b6A>E~py?bPk3k6JDF+BC3Q&RmAT&LLH$Ezi3dU~SVWK4(s$_TzI#+bqhd6rU4f z` zz-)AFiE%dAwwaG}z?lziiFY12@yfM72VL9jdOe*FK9|zcYwZHKaka(oqhgA-?DH3a z)i0ztrZcJ4lIta4bJcb+wLEL%W8mf*{5YC=d@ief%KSfprk?e4Iatjxq~9yR_Ln?A z3D!?N?XCpdpSJjY3ap;-Tnbi8+)smdrNsX;U^V@7Jw6NediZ{&y`S~xd(-E@+MJ84 zsO5?KdGNlJ#Qg$Tt&DpOJaM(>x_l9=&3EhcbuC=ozOJU0r?2b5hf&hkm%wUeUpK(h zm-fW{GFY2&ucMYH?pMIaQ4;s7V6`&tP4L9ko-uq4tgRfw*Wv2+btARhzMRXO!Oo%U zo*> zbI4jX-nY=y<8x>2lQTYjzKy1y9KHii4)$RTeKP0Tlf!qxUf;z39=JIV-$zrA&kt&! zXXra|?m|;f4nG7Z2m3IFKIUM5+SB%Ku-7N??*TXG;a)WL_}o|fl=JW-H1*{0V{me? z4`b+)^`PAxd~f&(*n2hnr(o~@_=O^O<5EA4F4+&#!Br?B`zZ-=L{`Rx5u9Y&&)P`6abla(@_HuCw34oAdj7H1))M z1Z+F?#Q6i**q;5`?;pYXsVCn@!Oiva7@B%wKMuC7y7~T=S}pxN33iQy{|S5*CGDRA z>!Ti@KZ9LE;eP=;=CpYltdDx~e+FzUZTZgrELh#Vo}iW+)9i=PCL> zN39nBm%wV;UZj@$Z1wk#{sGR*go`qOTWVQ zA8_X2ZLnOwcc{-HZqE7t3-_Gg_WEhp?@elLt}nmmya#SR^D(vb+>7(U)h@(0&(!(h z?gc(mwdZ-%0oG<;@8T~{Un9V)q2=ClpBRazp1u|UtCf8%2v1+y)7L^^ZT8hkEl*zy zgPZTUi=e5;XHl^Emulwk%lxj7jb~NgvknT^{T`sjt6xD%W=fYV)!7tZgOgl_`F-uTtBs z6KhqlF~U~^d;i~B&%^3)ebgPhd_{_}?Ms}tqrk?>zOW`(%|D-&{eCUDy1Dy1vhuWF z2khMWvySt~d0n`gXRls6-!ImKH}}Q$(bWBJcOJf@!LFMP>loVY&)>n-W`ADe4Zzch znKQ!;;c8y*jj8=OX7!CIYK~c)wX_Mix!yKKQ;*LFz|Hlx8Jc>&kB$MG^STt~?7CSt}m|+fLoQ64yF;Z4b6zbJgEI&1(nh<&Rp&UZqDV-XzKCV1>C$Q zyK1Lo4tE3FPW>x93C^SQJ;3U&x812-Gya~odgf&;*yn8cUU26rYj$t2KI(ZE?gLgg zzrBdPANUN`U4Eu87Hxktb^F|xS}s0-+V=jOT)zXs`%&woO`kof)s64Z$qxprmCwUN z;Oh6{<8$v&u-ZdlV;lrlb6naF1FJbM`QczS_sl$dkAVAUTm3nm_RPtVVCOC4KMJh& zLjBA=8f;r*`ApF6ddc;+POJ}uJ1ORP47EJAW5LT6{5Y_CSKd{QhpRcyS)*NW+i7#% zbyNHCe$aLTMa^|5PG94}_Lb{A0jy^1>~}qI^>V+P2v;}%an$mx)5+lGGq@K`Jw7Lb zo6pXZ(A3S%{h<$R?6jEzZm$1+H1&Mv9st`;J#nV0F@HHzIT@~>y59xtYY^-{SG#d%Qfo`Q)4^q&kHE_~XTXi)b46e6#yO2zTgH7B*zYLev*BmLGxul1 z^-<4z)j8nIgZ9kBxnOO{@jS43XKZu88JoV^&FM^PZOP#RaGBFb;pQ~EYX98wLbyKa z$>}1nvHhJY?aAq4u(srM3D`Nvy>Tg6&3hwxehi+uv%Nm%c|Nta#QHec+`}&e`<*5H z6Y#6y`EGhS+_;_-*j9giG6&kz_6o55g?|!U#=a6>#{LvMv2ClrKFM2qVtpEH-rBCB zmb+d*L+xH-?K|1$sIR8@(f;|`ZkWQ}|c ztdDx06JH0bo5#)6#uR^pT3eohw}5>H>Z47c8>rRY1I_z3uv(e(H{t4e2Hp-<%QNs+ zu$uAipw9OdpMT$iYtOUqPH>)m+8noj-v;{~?%DcT_Z_&tdDdx9d~LSdf_C2nyJwq! zH~jnX?^4WPf4M&K{{h(NLik;9+q=gY?}u=G)D!b=ura+ajVaepd=It1|71M(;(Ouc zyYYQ+HJ_P3ruO67Q~wb~&9x`CKfhz%4{kn(euAbRpPzyqNBLdsXK3o?;xp&xVAo~Z zJODOsu8%&yKvT~i`%AFx)D!1d;ED8==i7sD{nYb(`!(2m-shXSnu~s!BkjrKH{fO- z522~Y=eJWli=o9|AeLRSU0=AvH`9DLQ z{Ixwz`5VRj#pdgJeim#_;m?81C+q#MaDCLx$9w2`aJk;)`nm7guYK58V!i;jkFi(a{32YAN9oiC%DW>u3wpxxw+4H54~LYmuu)1bZxgYR`1tW z!D`;a&g*MnKduXH|DvclW^u0B>)_@!djm~9K5v4X*ZwUu_1tg&2HQ?O?+FeAicWZgpxV6{gJlgyhd{x2U1<#~>v!0{(!1}1C zjme!>@cH1z$g_5Slc%WPP{-*28%vvWJ%ZYgbFHnDqUKzSvv=g@o3U9tmh7F@=H-4i z5}WsDuE7Fu=O@o9xjy<+RSWW;J6itj=k`Ky{rzq>hhh$D`q{=cvoQE%EkWqTYdFA8oy=0=BLd+i!1jG zljU123-;eMvAylIJ5R~SI{7RIHXq+BfYtK+M=fW`+SF`+HT^jrYulfP{|eZ=-gz%s z5w4bJq&79%e+F#(&r#dn>$DQKi|HeLWw`Izv&l#MDsVOZ9IH09^uH?Dp9O@k2KT)w z`K%6C)6e$W)Z)Je_!#oh=64slxvpI2Y8~HE*p`DQ_L^|Dj8&VO?N_MVuT->O3!A@h zmiBAI)zV&@n*BNUb-@0fVEDRle-A8kvmRVcKl9h7roVgs`e64aZSFsEb6Wt->tHSK ztocal+%Kc?ZT|k)259QZXG5^Rhn9Rcf~)CgpW4)t&&J?;(X{zHQ*!&i6Kp=#`XX1G z@E?Eg)VY#x%74@{SK8EUe|z2jThwy@T(I%1{qy77Qv5r4yuUo#_v7EEwGDaruDfV~ z7pt+~*%qf5XGv=Ro*w^P{J9j{B+v7~ws+ptFQDi%hvGQp`si=}AEju2m$>5O=6e@A5S3I+D>Q8H)$+-v@RqtAk!pN!#iV8`G*WiGD<8#Cuz zp9kxgF==;BjioK^z5rGWzXoiater1{^|^);pKHP9{59spxxbF0pZc5h@g-_M?&sRB zr>HqDamH~2IM*Vvzl`P_P>mR-WAN0^5f+l%+~)$KmE17|%y2rjSJ!v*(Vd!*p{{jtFx zE4cno7F_?Q8vHK>*Z;YK>;HU%zff@f|50%LUvBVM3$Fhg1=s(r27kNY`oCLn{rzHM zo%x!-;QEg&xPA*Z_`(I(-+#lZjOV{$Rq~|^uD}0=RcZI%uqwI#hE=%!{u@@|)}tDH zt%B>nUcvPr-QXJ*Tz~%!t1`a-hE=$KAD{n*l|1hWzXoqZnM29C{tZ|?=WD+Ot35>V zUUE&U#s7C;wLIs34_5Qu)yIAK4;0tB?On5SvFlZT_YLp8M=9=W`e@U~HLsrj9tW5G zJpotqzDs|90;fOMyxdq%QR|=n{tUK1eV(G|^BA>y`g7V{y0o$KG+VpvW zT0Q;!3taa1I$Z6w+Q7z{__YC#)*8wj38v$4AtbOcn0dV?j?HO=mxnJm?{uTn; zpFZ03anDgte~W<2{uYC)`S(%jV}DD4)1P~e+*s~6`lr98!1kw)HhtW))YIQG;IhBv z;A;LEawZUb7>%!I6sePQ!^}*@SJyUKh_e=fL-v(g&(?^>=?z!se zZzFKo-zIRijcXtK`v5rox#!A_<$kMw`WpkbKYg_65V&5CAmOl3Z+eSTo?hCfhJL_@E^-IkC!QM0aFM!VhVEz63A-ooH zed2!**fk&jgTeYANYP)ePy7!BuSH4Dhk?~%KOF2Di~R_&TE=uF*f#1J(@|jiJcMGO za{Y|CC1W@mtljroao%e`gl%VvpB*T9uidf6+f(mE@!feB>b$2NOAO~G-%Cy?xca!7 zXHJfT8^`sWaUPGRp7)e4u$pT@AMev{xVbnc`)G51hXbsC?$hyL?^AuW>2Hqe>2Cs9 zE${mi!D>B}_)G%plbm|NYLh9>zw>n>*tXi7PkH9kx!!}~XIDz*bGI5hpSx3>&poL# zewG$f zA@H`;`e<{UZLNI`QT+`%`BeGl`{7IgVLq>bVA|fNkr~ z%12V43Rhc}lCho!ww<>8?E7@Ey19yTO%5i;;S@iIP;yNUt?_}>hf&P+2Ekt2Pk)~QJLc>;p9QOxd(P)-pIoD>;cD(ViSv1|V@aGZfYr)4*VI0V z^F_FtaSmc7A4IO#g3ZA`jG>R~=Q`@^DXuBkk7JSRpB%mfc6_Y zL9UPOy$5fs?cSf_+@JGf>!SGiFeUfru{A!5`nVb&Lw!8Od-VkB+^aVc&wC{M>Fotq z|5k(FS#a;Qy9%!V-3@+E!S(-X!S(-ngFjGk{U0j0{tq|!?+UK};|16M$p-&Z!S#Q- z;QBw?;Lp`Od&Sq_&S|+u_a>*r>$TJ{R(SS{<}8(_8U6}N!Z+$-|)Ya*L%U{s=t2Plk0up zGS?r$)!d_!>yP2)>b+LZ>;353lIu^vYRUCy;NU>ir`(Kkps;5qsa*F1h|5Y_9t2 zr#-no0xom?16=L3R<7;emHH#xTwU|F^ZGxErk*?>1FI#^C&0zs6p#0gBh~Wa?bQ`FMzz*KmHgez}Gn zaIc}d*HC}8%uy%UJTlf1aDBo@);x2+09+sS_$=7)SqQG5dggjzuzhJu-;019cj7Dx zFZ*7s=IMKJxIXI9mISN&_hqNArNGA4mcEt-JFn?$8Mu8V&az;&GR|^v+i6Rj<-uN) z#90CEe5daf;rgg&ZL9<~mbSE88Cvee*z`$0n}W?*yW^IZ_@D>zp(Y6C`PSKX}eGr^+Yfr!1gUwC5Ke54Q zHTc;LeolkWY4GzK{K5vmtii8r@ar4=rkZ;_-LH3oJ73{D!<|d_RqeaL^-*_Ub-vW% zzZ=*&4&NPaytLl~u8+FyonN*1k5w=DUSNIFes8co>bCcKsO>_2D_N=iq&} zADVi6_6Iwr(&qp)^*lcg1lvwM?G6IlU-?dXFkC%r^$@Ua)zj`!usN0O4ntFq&*5Nm zDt(SXQ%_Duf^Dasc1MBDsT|AEaP{PL4A{2niS=QyxoUGBUB_yPdz?C@jC(v>Jw9FF zX5S~Esi*I5u0tZRma)$Omt&s^*H7KCpGd71|5L#F=YBjDY%bZOPXoJ0?@G~@ zcBg}l75)*h^P2T`23Q~UjNweM@wDaIoCP)qZRvA1*giWc+RfX2R6YHj3${OP=TOV@ z_wAhr9-^(f_Oq$g()I$dxobP0TAsEa1>06#`y6UD@rBeEQ4;53uzBUrY+MRfyM*#4 z{vW6I8rfY;z^GdfI#%?7XJUXTY}c3`JY~J_~jZ<7FLw8LW@G@vf&< zi~o(_vi(=!=9hfF3f4zGZN3IJj`41ymS>%P9qc+&PYySOjiW7NQY**g*yLG9*6HsX jVAp8)EnwGC_^n{q*+E=Q-=l5=+eSZazH6!ZuJwNabFgND literal 39788 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 diff --git a/piet-gpu/shader/gen/pathseg.hlsl b/piet-gpu/shader/gen/pathseg.hlsl index 578417f..4e9a0ae 100644 --- a/piet-gpu/shader/gen/pathseg.hlsl +++ b/piet-gpu/shader/gen/pathseg.hlsl @@ -52,6 +52,7 @@ struct Monoid struct Config { + uint mem_size; uint n_elements; uint n_pathseg; uint width_in_tiles; @@ -164,7 +165,7 @@ uint read_mem(Alloc alloc, uint offset) { return 0u; } - uint v = _111.Load(offset * 4 + 8); + uint v = _111.Load(offset * 4 + 12); return v; } @@ -203,7 +204,7 @@ void write_mem(Alloc alloc, uint offset, uint val) { return; } - _111.Store(offset * 4 + 8, val); + _111.Store(offset * 4 + 12, val); } void PathCubic_write(Alloc a, PathCubicRef ref, PathCubic s) @@ -365,7 +366,7 @@ uint round_up(float x) void comp_main() { uint ix = gl_GlobalInvocationID.x * 4u; - uint tag_word = _574.Load(((_639.Load(92) >> uint(2)) + (ix >> uint(2))) * 4 + 0); + uint tag_word = _574.Load(((_639.Load(96) >> uint(2)) + (ix >> uint(2))) * 4 + 0); uint param = tag_word; TagMonoid local_tm = reduce_tag(param); sh_tag[gl_LocalInvocationID.x] = local_tm; @@ -404,14 +405,14 @@ void comp_main() TagMonoid param_4 = sh_tag[gl_LocalInvocationID.x - 1u]; tm = combine_tag_monoid(param_3, param_4); } - uint ps_ix = (_639.Load(96) >> uint(2)) + tm.pathseg_offset; - uint lw_ix = (_639.Load(88) >> uint(2)) + tm.linewidth_ix; + uint ps_ix = (_639.Load(100) >> uint(2)) + tm.pathseg_offset; + uint lw_ix = (_639.Load(92) >> uint(2)) + tm.linewidth_ix; uint save_path_ix = tm.path_ix; uint trans_ix = tm.trans_ix; - TransformSegRef _771 = { _639.Load(36) + (trans_ix * 24u) }; + TransformSegRef _771 = { _639.Load(40) + (trans_ix * 24u) }; TransformSegRef trans_ref = _771; - PathSegRef _781 = { _639.Load(28) + (tm.pathseg_ix * 52u) }; - PathSegRef ps_ref = _781; + PathSegRef _780 = { _639.Load(32) + (tm.pathseg_ix * 52u) }; + PathSegRef ps_ref = _780; float linewidth[4]; uint save_trans_ix[4]; float2 p0; @@ -464,9 +465,9 @@ void comp_main() } } } - Alloc _877; - _877.offset = _639.Load(36); - param_13.offset = _877.offset; + Alloc _876; + _876.offset = _639.Load(40); + param_13.offset = _876.offset; TransformSegRef param_14 = trans_ref; TransformSeg transform = TransformSeg_read(param_13, param_14); p0 = ((transform.mat.xy * p0.x) + (transform.mat.zw * p0.y)) + transform.translate; @@ -475,25 +476,25 @@ void comp_main() if (seg_type >= 2u) { p2 = ((transform.mat.xy * p2.x) + (transform.mat.zw * p2.y)) + transform.translate; - float4 _947 = bbox; - float2 _950 = min(_947.xy, p2); - bbox.x = _950.x; - bbox.y = _950.y; - float4 _955 = bbox; - float2 _958 = max(_955.zw, p2); - bbox.z = _958.x; - bbox.w = _958.y; + float4 _946 = bbox; + float2 _949 = min(_946.xy, p2); + bbox.x = _949.x; + bbox.y = _949.y; + float4 _954 = bbox; + float2 _957 = max(_954.zw, p2); + bbox.z = _957.x; + bbox.w = _957.y; if (seg_type == 3u) { p3 = ((transform.mat.xy * p3.x) + (transform.mat.zw * p3.y)) + transform.translate; - float4 _983 = bbox; - float2 _986 = min(_983.xy, p3); - bbox.x = _986.x; - bbox.y = _986.y; - float4 _991 = bbox; - float2 _994 = max(_991.zw, p3); - bbox.z = _994.x; - bbox.w = _994.y; + float4 _982 = bbox; + float2 _985 = min(_982.xy, p3); + bbox.x = _985.x; + bbox.y = _985.y; + float4 _990 = bbox; + float2 _993 = max(_990.zw, p3); + bbox.z = _993.x; + bbox.w = _993.y; } else { @@ -524,9 +525,9 @@ void comp_main() cubic.trans_ix = (gl_GlobalInvocationID.x * 4u) + i_1; cubic.stroke = stroke; uint fill_mode = uint(linewidth[i_1] >= 0.0f); - Alloc _1089; - _1089.offset = _639.Load(28); - param_15.offset = _1089.offset; + Alloc _1088; + _1088.offset = _639.Load(32); + param_15.offset = _1088.offset; PathSegRef param_16 = ps_ref; uint param_17 = fill_mode; PathCubic param_18 = cubic; @@ -571,7 +572,7 @@ void comp_main() } GroupMemoryBarrierWithGroupSync(); uint path_ix = save_path_ix; - uint bbox_out_ix = (_639.Load(40) >> uint(2)) + (path_ix * 6u); + uint bbox_out_ix = (_639.Load(44) >> uint(2)) + (path_ix * 6u); Monoid row = monoid_identity(); if (gl_LocalInvocationID.x > 0u) { @@ -583,24 +584,24 @@ void comp_main() Monoid param_24 = local[i_4]; Monoid m = combine_monoid(param_23, param_24); bool do_atomic = false; - bool _1264 = i_4 == 3u; - bool _1270; - if (_1264) + bool _1263 = i_4 == 3u; + bool _1269; + if (_1263) { - _1270 = gl_LocalInvocationID.x == 255u; + _1269 = gl_LocalInvocationID.x == 255u; } else { - _1270 = _1264; + _1269 = _1263; } - if (_1270) + if (_1269) { do_atomic = true; } if ((m.flags & 1u) != 0u) { - _111.Store((bbox_out_ix + 4u) * 4 + 8, asuint(linewidth[i_4])); - _111.Store((bbox_out_ix + 5u) * 4 + 8, save_trans_ix[i_4]); + _111.Store((bbox_out_ix + 4u) * 4 + 12, asuint(linewidth[i_4])); + _111.Store((bbox_out_ix + 5u) * 4 + 12, save_trans_ix[i_4]); if ((m.flags & 2u) == 0u) { do_atomic = true; @@ -608,43 +609,43 @@ void comp_main() else { float param_25 = m.bbox.x; - _111.Store(bbox_out_ix * 4 + 8, round_down(param_25)); + _111.Store(bbox_out_ix * 4 + 12, round_down(param_25)); float param_26 = m.bbox.y; - _111.Store((bbox_out_ix + 1u) * 4 + 8, round_down(param_26)); + _111.Store((bbox_out_ix + 1u) * 4 + 12, round_down(param_26)); float param_27 = m.bbox.z; - _111.Store((bbox_out_ix + 2u) * 4 + 8, round_up(param_27)); + _111.Store((bbox_out_ix + 2u) * 4 + 12, round_up(param_27)); float param_28 = m.bbox.w; - _111.Store((bbox_out_ix + 3u) * 4 + 8, round_up(param_28)); + _111.Store((bbox_out_ix + 3u) * 4 + 12, round_up(param_28)); bbox_out_ix += 6u; do_atomic = false; } } if (do_atomic) { - bool _1335 = m.bbox.z > m.bbox.x; - bool _1344; - if (!_1335) + bool _1334 = m.bbox.z > m.bbox.x; + bool _1343; + if (!_1334) { - _1344 = m.bbox.w > m.bbox.y; + _1343 = m.bbox.w > m.bbox.y; } else { - _1344 = _1335; + _1343 = _1334; } - if (_1344) + if (_1343) { float param_29 = m.bbox.x; - uint _1353; - _111.InterlockedMin(bbox_out_ix * 4 + 8, round_down(param_29), _1353); + uint _1352; + _111.InterlockedMin(bbox_out_ix * 4 + 12, round_down(param_29), _1352); float param_30 = m.bbox.y; - uint _1361; - _111.InterlockedMin((bbox_out_ix + 1u) * 4 + 8, round_down(param_30), _1361); + uint _1360; + _111.InterlockedMin((bbox_out_ix + 1u) * 4 + 12, round_down(param_30), _1360); float param_31 = m.bbox.z; - uint _1369; - _111.InterlockedMax((bbox_out_ix + 2u) * 4 + 8, round_up(param_31), _1369); + uint _1368; + _111.InterlockedMax((bbox_out_ix + 2u) * 4 + 12, round_up(param_31), _1368); float param_32 = m.bbox.w; - uint _1377; - _111.InterlockedMax((bbox_out_ix + 3u) * 4 + 8, round_up(param_32), _1377); + uint _1376; + _111.InterlockedMax((bbox_out_ix + 3u) * 4 + 12, round_up(param_32), _1376); } bbox_out_ix += 6u; } diff --git a/piet-gpu/shader/gen/pathseg.msl b/piet-gpu/shader/gen/pathseg.msl index 9f6328e..5aea66d 100644 --- a/piet-gpu/shader/gen/pathseg.msl +++ b/piet-gpu/shader/gen/pathseg.msl @@ -102,6 +102,7 @@ struct Memory { uint mem_offset; uint mem_error; + uint blend_offset; uint memory[1]; }; @@ -117,6 +118,7 @@ struct Alloc_1 struct Config { + uint mem_size; uint n_elements; uint n_pathseg; uint width_in_tiles; @@ -545,25 +547,25 @@ kernel void main0(device Memory& v_111 [[buffer(0)]], const device ConfigBuf& _6 if (seg_type >= 2u) { p2 = ((transform.mat.xy * p2.x) + (transform.mat.zw * p2.y)) + transform.translate; - float4 _947 = bbox; - float2 _950 = fast::min(_947.xy, p2); - bbox.x = _950.x; - bbox.y = _950.y; - float4 _955 = bbox; - float2 _958 = fast::max(_955.zw, p2); - bbox.z = _958.x; - bbox.w = _958.y; + float4 _946 = bbox; + float2 _949 = fast::min(_946.xy, p2); + bbox.x = _949.x; + bbox.y = _949.y; + float4 _954 = bbox; + float2 _957 = fast::max(_954.zw, p2); + bbox.z = _957.x; + bbox.w = _957.y; if (seg_type == 3u) { p3 = ((transform.mat.xy * p3.x) + (transform.mat.zw * p3.y)) + transform.translate; - float4 _983 = bbox; - float2 _986 = fast::min(_983.xy, p3); - bbox.x = _986.x; - bbox.y = _986.y; - float4 _991 = bbox; - float2 _994 = fast::max(_991.zw, p3); - bbox.z = _994.x; - bbox.w = _994.y; + float4 _982 = bbox; + float2 _985 = fast::min(_982.xy, p3); + bbox.x = _985.x; + bbox.y = _985.y; + float4 _990 = bbox; + float2 _993 = fast::max(_990.zw, p3); + bbox.z = _993.x; + bbox.w = _993.y; } else { @@ -651,17 +653,17 @@ kernel void main0(device Memory& v_111 [[buffer(0)]], const device ConfigBuf& _6 Monoid param_24 = local[i_4]; Monoid m = combine_monoid(param_23, param_24); bool do_atomic = false; - bool _1264 = i_4 == 3u; - bool _1270; - if (_1264) + bool _1263 = i_4 == 3u; + bool _1269; + if (_1263) { - _1270 = gl_LocalInvocationID.x == 255u; + _1269 = gl_LocalInvocationID.x == 255u; } else { - _1270 = _1264; + _1269 = _1263; } - if (_1270) + if (_1269) { do_atomic = true; } @@ -689,26 +691,26 @@ kernel void main0(device Memory& v_111 [[buffer(0)]], const device ConfigBuf& _6 } if (do_atomic) { - bool _1335 = m.bbox.z > m.bbox.x; - bool _1344; - if (!_1335) + bool _1334 = m.bbox.z > m.bbox.x; + bool _1343; + if (!_1334) { - _1344 = m.bbox.w > m.bbox.y; + _1343 = m.bbox.w > m.bbox.y; } else { - _1344 = _1335; + _1343 = _1334; } - if (_1344) + if (_1343) { float param_29 = m.bbox.x; - uint _1353 = atomic_fetch_min_explicit((device atomic_uint*)&v_111.memory[bbox_out_ix], round_down(param_29), memory_order_relaxed); + uint _1352 = atomic_fetch_min_explicit((device atomic_uint*)&v_111.memory[bbox_out_ix], round_down(param_29), memory_order_relaxed); float param_30 = m.bbox.y; - uint _1361 = atomic_fetch_min_explicit((device atomic_uint*)&v_111.memory[bbox_out_ix + 1u], round_down(param_30), memory_order_relaxed); + uint _1360 = atomic_fetch_min_explicit((device atomic_uint*)&v_111.memory[bbox_out_ix + 1u], round_down(param_30), memory_order_relaxed); float param_31 = m.bbox.z; - uint _1369 = atomic_fetch_max_explicit((device atomic_uint*)&v_111.memory[bbox_out_ix + 2u], round_up(param_31), memory_order_relaxed); + uint _1368 = atomic_fetch_max_explicit((device atomic_uint*)&v_111.memory[bbox_out_ix + 2u], round_up(param_31), memory_order_relaxed); float param_32 = m.bbox.w; - uint _1377 = atomic_fetch_max_explicit((device atomic_uint*)&v_111.memory[bbox_out_ix + 3u], round_up(param_32), memory_order_relaxed); + uint _1376 = atomic_fetch_max_explicit((device atomic_uint*)&v_111.memory[bbox_out_ix + 3u], round_up(param_32), memory_order_relaxed); } bbox_out_ix += 6u; } diff --git a/piet-gpu/shader/gen/pathseg.spv b/piet-gpu/shader/gen/pathseg.spv index 4e2e9d54995c7e17f3f02f9876384c618e18d991..2fb04e576995b70e4fc255db0bbaab02fca0dafa 100644 GIT binary patch literal 35296 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 x%E4(w|`&$HIvYwdFOd)_mXq+{{*N4Hvw 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 N+=jr~%}s1>{|_qA&e8w? diff --git a/piet-gpu/shader/gen/pathtag_reduce.dxil b/piet-gpu/shader/gen/pathtag_reduce.dxil index 4c2bd233ca3457688916b6937bc1b15e1db950ba..692ac5f74f7683290317eb30834a6e6aab71f0e0 100644 GIT binary patch delta 57 zcmV-90LK5MB%~x1L|8&Y@T}2<9H1Q8(> uint(2)) + ix; + uint scene_ix = (_139.Load(96) >> uint(2)) + ix; uint tag_word = _151.Load(scene_ix * 4 + 0); uint param = tag_word; TagMonoid agg = reduce_tag(param); diff --git a/piet-gpu/shader/gen/pathtag_reduce.msl b/piet-gpu/shader/gen/pathtag_reduce.msl index 91e0cca..c6266ad 100644 --- a/piet-gpu/shader/gen/pathtag_reduce.msl +++ b/piet-gpu/shader/gen/pathtag_reduce.msl @@ -21,6 +21,7 @@ struct Alloc struct Config { + uint mem_size; uint n_elements; uint n_pathseg; uint width_in_tiles; @@ -78,6 +79,7 @@ struct Memory { uint mem_offset; uint mem_error; + uint blend_offset; uint memory[1]; }; diff --git a/piet-gpu/shader/gen/pathtag_reduce.spv b/piet-gpu/shader/gen/pathtag_reduce.spv index f1d8679c961cc8dc0b74b6dafa1cb84cc2a7e80c..829addcf999546baaca926f0efa521d5a4559356 100644 GIT binary patch delta 461 zcmY+Ay-ve05XWOXUoHKl1-F<|p-vqbcmp~hu`n<&FhxmmX(ZQaNrs9Ysm#a9JAg9t z4oIvl>@0l%Bra(SBGK8&|9*G(*L|J54W2*f(L_$XIJ}bvJ~qA!ya|T(q>>Y-PbzW zKpUnAuZ(xLFgx{=u@?lLw=@=$nF6;neK9HLMw`a0&}^AEQaO z;mH*J2Fhsj*4LR$D{s-vwQN9UZl&$Or`hQ2VkT$3Xf%ptg1<!Vl@D5yY>SluUmBh delta 368 zcmccM_{L$w9j3`&m_#HQ85kJy;tLW>GKy2vfowJgc7_fh%`{n&S(=e~vMsZ;BnyyV zl9`hlpO}-ApA1sN23Es5xsX|0k_{+ZP?DU3kcF7QK6xR~1dhpjfoeEGCKM&+6+;!l zY~h;x7N~}MGAE0?Bo9zca!zIex;ea)9a*Fq`6kD*$TRX!t_89MCeLJ%mK6l5Pbo?) z&&*59N9bV%yG&^EMHXRAVW0|#-#~7L$cTW&K=vT~Dms~$Rhm(3vL>rMqxfV`AX{Q` zA-gaq%$1Up8(F0%H?VSSUc#Ei#LmjV01P#z&4wJ2Oq=I%onzeGz+=b6C_8ySpXlTp Wd{Y?3H|O$)GO~cwZ9XNyCIA2%R!y-0 diff --git a/piet-gpu/shader/gen/tile_alloc.dxil b/piet-gpu/shader/gen/tile_alloc.dxil index 7759910ca527b4ff12fbe9ba3ee03fdb6a428ca7..35a1c2b142bd6e9b1d289381090dba20a5a609af 100644 GIT binary patch delta 3056 zcmds&{Zms{8pqE~ZfKo^!tEd7g7VIkvcNRd~iGt#0Z<#KFTIJqhg>Cpw3jtZD=R5EtAS9xftq*lYad z%~&7?fCVBj2z?ow*5m;AOTuY?#{kgk2Ja~e0RHG$gq%iF9Ay$3u{jP&GK*WI@k2_4 z1o_2xQ@6aVTTwUjhr0eC$C1gjc(|6^z;Y;XhSq}^XaTNNfiKBvjau9CLe_>?P*K{W zX+3cbxCqpqUXzz0aac>%^rUKq4hOL$0~hhc>x-*PhDg4oB!dCaxWE?Z6!IsMg3G zr@?hhPp9FiMqgfO21^uHp;Co^yy|{}6)Q1=<%%F}L4%&fx#44@wow$}(qb(4$(w`Z zAl6}0;d<|`*`DLa>HG<6yaL4lT+bze4KI}63!B(Xjibm&i??aoxc~YWpIvS0>&~t|)z(IXJJ^TBwL#(r zkbTL>zGP)%F4@?i>>lvH&-g#!{4Xu-wZxZ~@2N;CD>hWtCGc zO10L9MPXOAZB(Vl#{I)SeQ~s-zOm`*>z_3?_2o+JDaG$4RT-*x?5^5ssLm6d4U(Ts z^(&0rQebbJP!v*yP-D``p4C|&Zg`Nj@R<0U<_B5n>9M3G2`=2aV|QhZp$e{Bb{>)C zA;x5Q?jlz7LG`m^C$}BD{MUEy=86R+UN&VD^6RPeRmMkUd%pWmTH8azQgTT)ChG`K z`l@yxTSaAz*|GimW-dH-$>GQg&=6JEFba6@3sA=4|8AT}6Kx;Z_wb1jUiR)9&b_K~ zVnNUJ(-WTuba&EGd#a*_;7E|MiysP$60|gsrPg}2pp0L0Iy#EeL_qZlTEQzmYQR}i z+=oOT*b4`LKgDmkuLp@5U0gYV;usU|yS%G4d8%cRSDfwjY6ay%acdrLA+sgCC!GKc0By4~gd) z--Wt-lmk#p0kFZ5j4t~gc8JJ%4Mj+|Rx7Y!T7`d=$^HOz*k=?+H3fJHi?bH*^58mk zuL{4_uUB@~(^%Hg7*?mQplK;k;Z|lI>09$id#!q*h8@4q(VOJDzXWpkr1qWaY|Hzn z5~_`-gmRsqV{2;DZS3i{pSSQ*pQHZC9p`$)H;QAF)_?~rVg8^a%zMlhFwxc zTVY#vc)@YST_@em;|19|_WVIwEZqwE8msRcZ@QW*u`Pv!RF~?D4OO{2iVfv?f-VAr zxn+EE^NGn#gdcPigcLD)=LS>0Ho2*Y zxf)u+bcB>LYn-{$&i^uU=ME$D2n(rU+#wk6TcF6t!n;hAjiLZ2rjO>NZi_3`q8+@{dDO#*Xnd9= z($W1S=8*{^>NFD5jTADIS204F@i;G%CEm@?uK&*6L^7fpSLhVti>g_=7hvv4n+hEi zU464d?AyB_VHT02Mt)IP%w|dCe6)SEw3M_B!I-w#%U`d8)x%-+?6=IX^=fuXPf3uS znsc{@P5ZJ40-$cj_(Zf4PXZ&k}XVv8lIs`_8C}AjApE1H1 zMT3!gP}O-5fVw@0ezB6c}TTw1cK%y}j zJgwfx!)r!$Q$gnJfx7H5-EU26w}{Gn4ZWz1O6B=_5FD=$(B$CBfx*d*0lVAh$Dao$ z>MP=^+ZZE8oDxoFTg~fCARY%SUJ|4KXT@X*Y1g+jc z3kDM$yHTWisq`K^=aroBN*cQbiLlVj2-|GxF&7B@ghlXw2Eb<+Y{uTgN7z42`62Rh g`4uH?S>#!c7Q^@saKr^d8EAJmYgB?1e)_BSKax%JZvX%Q literal 5132 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 OWo=+H$A5m@8Gi?G?1dQs diff --git a/piet-gpu/shader/gen/tile_alloc.hlsl b/piet-gpu/shader/gen/tile_alloc.hlsl index 73e0a8e..aed9001 100644 --- a/piet-gpu/shader/gen/tile_alloc.hlsl +++ b/piet-gpu/shader/gen/tile_alloc.hlsl @@ -3,12 +3,6 @@ struct Alloc uint offset; }; -struct MallocResult -{ - Alloc alloc; - bool failed; -}; - struct PathRef { uint offset; @@ -27,6 +21,7 @@ struct Path struct Config { + uint mem_size; uint n_elements; uint n_pathseg; uint width_in_tiles; @@ -58,9 +53,9 @@ struct Config static const uint3 gl_WorkGroupSize = uint3(256u, 1u, 1u); -RWByteAddressBuffer _70 : register(u0, space0); -ByteAddressBuffer _181 : register(t1, space0); -ByteAddressBuffer _257 : register(t2, space0); +RWByteAddressBuffer _53 : register(u0, space0); +ByteAddressBuffer _148 : register(t1, space0); +ByteAddressBuffer _232 : register(t2, space0); static uint3 gl_LocalInvocationID; static uint3 gl_GlobalInvocationID; @@ -71,53 +66,38 @@ struct SPIRV_Cross_Input }; groupshared uint sh_tile_count[256]; -groupshared MallocResult sh_tile_alloc; +groupshared uint sh_tile_offset; + +bool check_deps(uint dep_stage) +{ + uint _60; + _53.InterlockedOr(4, 0u, _60); + return (_60 & dep_stage) == 0u; +} float4 load_draw_bbox(uint draw_ix) { - uint base = (_181.Load(64) >> uint(2)) + (4u * draw_ix); - float x0 = asfloat(_70.Load(base * 4 + 8)); - float y0 = asfloat(_70.Load((base + 1u) * 4 + 8)); - float x1 = asfloat(_70.Load((base + 2u) * 4 + 8)); - float y1 = asfloat(_70.Load((base + 3u) * 4 + 8)); + uint base = (_148.Load(68) >> uint(2)) + (4u * draw_ix); + float x0 = asfloat(_53.Load(base * 4 + 12)); + float y0 = asfloat(_53.Load((base + 1u) * 4 + 12)); + float x1 = asfloat(_53.Load((base + 2u) * 4 + 12)); + float y1 = asfloat(_53.Load((base + 3u) * 4 + 12)); float4 bbox = float4(x0, y0, x1, y1); return bbox; } -Alloc new_alloc(uint offset, uint size, bool mem_ok) +uint malloc_stage(uint size, uint mem_size, uint stage) { - Alloc a; - a.offset = offset; - return a; -} - -MallocResult malloc(uint size) -{ - uint _76; - _70.InterlockedAdd(0, size, _76); - uint offset = _76; - uint _83; - _70.GetDimensions(_83); - _83 = (_83 - 8) / 4; - MallocResult r; - r.failed = (offset + size) > uint(int(_83) * 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 _70; + _53.InterlockedAdd(0, size, _70); + uint offset = _70; + if ((offset + size) > mem_size) { - uint _105; - _70.InterlockedMax(4, 1u, _105); - return r; + uint _80; + _53.InterlockedOr(4, stage, _80); + offset = 0u; } - return r; -} - -Alloc slice_mem(Alloc a, uint offset, uint size) -{ - Alloc _131 = { a.offset + offset }; - return _131; + return offset; } bool touch_mem(Alloc alloc, uint offset) @@ -133,7 +113,7 @@ void write_mem(Alloc alloc, uint offset, uint val) { return; } - _70.Store(offset * 4 + 8, val); + _53.Store(offset * 4 + 12, val); } void Path_write(Alloc a, PathRef ref, Path s) @@ -155,15 +135,21 @@ void Path_write(Alloc a, PathRef ref, Path s) void comp_main() { + uint param = 1u; + bool _192 = check_deps(param); + if (!_192) + { + return; + } uint th_ix = gl_LocalInvocationID.x; uint element_ix = gl_GlobalInvocationID.x; - PathRef _241 = { _181.Load(16) + (element_ix * 12u) }; - PathRef path_ref = _241; - uint drawtag_base = _181.Load(100) >> uint(2); + PathRef _216 = { _148.Load(20) + (element_ix * 12u) }; + PathRef path_ref = _216; + uint drawtag_base = _148.Load(104) >> uint(2); uint drawtag = 0u; - if (element_ix < _181.Load(0)) + if (element_ix < _148.Load(4)) { - drawtag = _257.Load((drawtag_base + element_ix) * 4 + 0); + drawtag = _232.Load((drawtag_base + element_ix) * 4 + 0); } int x0 = 0; int y0 = 0; @@ -171,17 +157,17 @@ void comp_main() int y1 = 0; if ((drawtag != 0u) && (drawtag != 37u)) { - uint param = element_ix; - float4 bbox = load_draw_bbox(param); + uint param_1 = element_ix; + float4 bbox = load_draw_bbox(param_1); x0 = int(floor(bbox.x * 0.0625f)); y0 = int(floor(bbox.y * 0.0625f)); x1 = int(ceil(bbox.z * 0.0625f)); y1 = int(ceil(bbox.w * 0.0625f)); } - x0 = clamp(x0, 0, int(_181.Load(8))); - y0 = clamp(y0, 0, int(_181.Load(12))); - x1 = clamp(x1, 0, int(_181.Load(8))); - y1 = clamp(y1, 0, int(_181.Load(12))); + x0 = clamp(x0, 0, int(_148.Load(12))); + y0 = clamp(y0, 0, int(_148.Load(16))); + x1 = clamp(x1, 0, int(_148.Load(12))); + y1 = clamp(y1, 0, int(_148.Load(16))); Path path; path.bbox = uint4(uint(x0), uint(y0), uint(x1), uint(y1)); uint tile_count = uint((x1 - x0) * (y1 - y0)); @@ -199,59 +185,45 @@ void comp_main() } if (th_ix == 255u) { - uint param_1 = total_tile_count * 8u; - MallocResult _392 = malloc(param_1); - sh_tile_alloc = _392; + uint param_2 = total_tile_count * 8u; + uint param_3 = _148.Load(0); + uint param_4 = 2u; + uint _370 = malloc_stage(param_2, param_3, param_4); + sh_tile_offset = _370; } GroupMemoryBarrierWithGroupSync(); - MallocResult alloc_start = sh_tile_alloc; - bool _403; - if (!alloc_start.failed) - { - _403 = _70.Load(4) != 0u; - } - else - { - _403 = alloc_start.failed; - } - if (_403) + uint offset_start = sh_tile_offset; + if (offset_start == 0u) { return; } - if (element_ix < _181.Load(0)) + if (element_ix < _148.Load(4)) { - uint _416; + uint _387; if (th_ix > 0u) { - _416 = sh_tile_count[th_ix - 1u]; + _387 = sh_tile_count[th_ix - 1u]; } else { - _416 = 0u; + _387 = 0u; } - uint tile_subix = _416; - Alloc param_2 = alloc_start.alloc; - uint param_3 = 8u * tile_subix; - uint param_4 = 8u * tile_count; - Alloc tiles_alloc = slice_mem(param_2, param_3, param_4); - TileRef _438 = { tiles_alloc.offset }; - path.tiles = _438; - Alloc _444; - _444.offset = _181.Load(16); + uint tile_subix = _387; + TileRef _400 = { offset_start + (8u * tile_subix) }; + path.tiles = _400; + Alloc _406; + _406.offset = _148.Load(20); Alloc param_5; - param_5.offset = _444.offset; + param_5.offset = _406.offset; PathRef param_6 = path_ref; Path param_7 = path; Path_write(param_5, param_6, param_7); } uint total_count = sh_tile_count[255] * 2u; - uint start_ix = alloc_start.alloc.offset >> uint(2); + uint start_ix = offset_start >> uint(2); for (uint i_1 = th_ix; i_1 < total_count; i_1 += 256u) { - Alloc param_8 = alloc_start.alloc; - uint param_9 = start_ix + i_1; - uint param_10 = 0u; - write_mem(param_8, param_9, param_10); + _53.Store((start_ix + i_1) * 4 + 12, 0u); } } diff --git a/piet-gpu/shader/gen/tile_alloc.msl b/piet-gpu/shader/gen/tile_alloc.msl index 961be50..e02138a 100644 --- a/piet-gpu/shader/gen/tile_alloc.msl +++ b/piet-gpu/shader/gen/tile_alloc.msl @@ -12,12 +12,6 @@ struct Alloc uint offset; }; -struct MallocResult -{ - Alloc alloc; - bool failed; -}; - struct PathRef { uint offset; @@ -38,6 +32,7 @@ struct Memory { uint mem_offset; uint mem_error; + uint blend_offset; uint memory[1]; }; @@ -48,6 +43,7 @@ struct Alloc_1 struct Config { + uint mem_size; uint n_elements; uint n_pathseg; uint width_in_tiles; @@ -90,48 +86,35 @@ struct SceneBuf constant uint3 gl_WorkGroupSize [[maybe_unused]] = uint3(256u, 1u, 1u); static inline __attribute__((always_inline)) -float4 load_draw_bbox(thread const uint& draw_ix, device Memory& v_70, constant uint& v_70BufferSize, const device ConfigBuf& v_181) +bool check_deps(thread const uint& dep_stage, device Memory& v_53) { - uint base = (v_181.conf.draw_bbox_alloc.offset >> uint(2)) + (4u * draw_ix); - float x0 = as_type(v_70.memory[base]); - float y0 = as_type(v_70.memory[base + 1u]); - float x1 = as_type(v_70.memory[base + 2u]); - float y1 = as_type(v_70.memory[base + 3u]); + uint _60 = atomic_fetch_or_explicit((device atomic_uint*)&v_53.mem_error, 0u, memory_order_relaxed); + return (_60 & dep_stage) == 0u; +} + +static inline __attribute__((always_inline)) +float4 load_draw_bbox(thread const uint& draw_ix, device Memory& v_53, const device ConfigBuf& v_148) +{ + uint base = (v_148.conf.draw_bbox_alloc.offset >> uint(2)) + (4u * draw_ix); + float x0 = as_type(v_53.memory[base]); + float y0 = as_type(v_53.memory[base + 1u]); + float x1 = as_type(v_53.memory[base + 2u]); + float y1 = as_type(v_53.memory[base + 3u]); float4 bbox = float4(x0, y0, x1, y1); return bbox; } static inline __attribute__((always_inline)) -Alloc new_alloc(thread const uint& offset, thread const uint& size, thread const bool& mem_ok) +uint malloc_stage(thread const uint& size, thread const uint& mem_size, thread const uint& stage, device Memory& v_53) { - Alloc a; - a.offset = offset; - return a; -} - -static inline __attribute__((always_inline)) -MallocResult malloc(thread const uint& size, device Memory& v_70, constant uint& v_70BufferSize) -{ - uint _76 = atomic_fetch_add_explicit((device atomic_uint*)&v_70.mem_offset, size, memory_order_relaxed); - uint offset = _76; - MallocResult r; - r.failed = (offset + size) > uint(int((v_70BufferSize - 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 _70 = atomic_fetch_add_explicit((device atomic_uint*)&v_53.mem_offset, size, memory_order_relaxed); + uint offset = _70; + if ((offset + size) > mem_size) { - uint _105 = atomic_fetch_max_explicit((device atomic_uint*)&v_70.mem_error, 1u, memory_order_relaxed); - return r; + uint _80 = atomic_fetch_or_explicit((device atomic_uint*)&v_53.mem_error, stage, memory_order_relaxed); + offset = 0u; } - return r; -} - -static inline __attribute__((always_inline)) -Alloc slice_mem(thread const Alloc& a, thread const uint& offset, thread const uint& size) -{ - return Alloc{ a.offset + offset }; + return offset; } static inline __attribute__((always_inline)) @@ -141,7 +124,7 @@ bool touch_mem(thread const Alloc& alloc, thread const uint& offset) } static inline __attribute__((always_inline)) -void write_mem(thread const Alloc& alloc, thread const uint& offset, thread const uint& val, device Memory& v_70, constant uint& v_70BufferSize) +void write_mem(thread const Alloc& alloc, thread const uint& offset, thread const uint& val, device Memory& v_53) { Alloc param = alloc; uint param_1 = offset; @@ -149,40 +132,45 @@ void write_mem(thread const Alloc& alloc, thread const uint& offset, thread cons { return; } - v_70.memory[offset] = val; + v_53.memory[offset] = val; } static inline __attribute__((always_inline)) -void Path_write(thread const Alloc& a, thread const PathRef& ref, thread const Path& s, device Memory& v_70, constant uint& v_70BufferSize) +void Path_write(thread const Alloc& a, thread const PathRef& ref, thread const Path& s, device Memory& v_53) { uint ix = ref.offset >> uint(2); Alloc param = a; uint param_1 = ix + 0u; uint param_2 = s.bbox.x | (s.bbox.y << uint(16)); - write_mem(param, param_1, param_2, v_70, v_70BufferSize); + write_mem(param, param_1, param_2, v_53); Alloc param_3 = a; uint param_4 = ix + 1u; uint param_5 = s.bbox.z | (s.bbox.w << uint(16)); - write_mem(param_3, param_4, param_5, v_70, v_70BufferSize); + write_mem(param_3, param_4, param_5, v_53); Alloc param_6 = a; uint param_7 = ix + 2u; uint param_8 = s.tiles.offset; - write_mem(param_6, param_7, param_8, v_70, v_70BufferSize); + write_mem(param_6, param_7, param_8, v_53); } -kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device Memory& v_70 [[buffer(0)]], const device ConfigBuf& v_181 [[buffer(1)]], const device SceneBuf& _257 [[buffer(2)]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]]) +kernel void main0(device Memory& v_53 [[buffer(0)]], const device ConfigBuf& v_148 [[buffer(1)]], const device SceneBuf& _232 [[buffer(2)]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]]) { threadgroup uint sh_tile_count[256]; - threadgroup MallocResult sh_tile_alloc; - constant uint& v_70BufferSize = spvBufferSizeConstants[0]; + threadgroup uint sh_tile_offset; + uint param = 1u; + bool _192 = check_deps(param, v_53); + if (!_192) + { + return; + } uint th_ix = gl_LocalInvocationID.x; uint element_ix = gl_GlobalInvocationID.x; - PathRef path_ref = PathRef{ v_181.conf.tile_alloc.offset + (element_ix * 12u) }; - uint drawtag_base = v_181.conf.drawtag_offset >> uint(2); + PathRef path_ref = PathRef{ v_148.conf.tile_alloc.offset + (element_ix * 12u) }; + uint drawtag_base = v_148.conf.drawtag_offset >> uint(2); uint drawtag = 0u; - if (element_ix < v_181.conf.n_elements) + if (element_ix < v_148.conf.n_elements) { - drawtag = _257.scene[drawtag_base + element_ix]; + drawtag = _232.scene[drawtag_base + element_ix]; } int x0 = 0; int y0 = 0; @@ -190,17 +178,17 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M int y1 = 0; if ((drawtag != 0u) && (drawtag != 37u)) { - uint param = element_ix; - float4 bbox = load_draw_bbox(param, v_70, v_70BufferSize, v_181); + uint param_1 = element_ix; + float4 bbox = load_draw_bbox(param_1, v_53, v_148); x0 = int(floor(bbox.x * 0.0625)); y0 = int(floor(bbox.y * 0.0625)); x1 = int(ceil(bbox.z * 0.0625)); y1 = int(ceil(bbox.w * 0.0625)); } - x0 = clamp(x0, 0, int(v_181.conf.width_in_tiles)); - y0 = clamp(y0, 0, int(v_181.conf.height_in_tiles)); - x1 = clamp(x1, 0, int(v_181.conf.width_in_tiles)); - y1 = clamp(y1, 0, int(v_181.conf.height_in_tiles)); + x0 = clamp(x0, 0, int(v_148.conf.width_in_tiles)); + y0 = clamp(y0, 0, int(v_148.conf.height_in_tiles)); + x1 = clamp(x1, 0, int(v_148.conf.width_in_tiles)); + y1 = clamp(y1, 0, int(v_148.conf.height_in_tiles)); Path path; path.bbox = uint4(uint(x0), uint(y0), uint(x1), uint(y1)); uint tile_count = uint((x1 - x0) * (y1 - y0)); @@ -218,56 +206,42 @@ kernel void main0(constant uint* spvBufferSizeConstants [[buffer(25)]], device M } if (th_ix == 255u) { - uint param_1 = total_tile_count * 8u; - MallocResult _392 = malloc(param_1, v_70, v_70BufferSize); - sh_tile_alloc = _392; + uint param_2 = total_tile_count * 8u; + uint param_3 = v_148.conf.mem_size; + uint param_4 = 2u; + uint _370 = malloc_stage(param_2, param_3, param_4, v_53); + sh_tile_offset = _370; } threadgroup_barrier(mem_flags::mem_threadgroup); - MallocResult alloc_start = sh_tile_alloc; - bool _403; - if (!alloc_start.failed) - { - _403 = v_70.mem_error != 0u; - } - else - { - _403 = alloc_start.failed; - } - if (_403) + uint offset_start = sh_tile_offset; + if (offset_start == 0u) { return; } - if (element_ix < v_181.conf.n_elements) + if (element_ix < v_148.conf.n_elements) { - uint _416; + uint _387; if (th_ix > 0u) { - _416 = sh_tile_count[th_ix - 1u]; + _387 = sh_tile_count[th_ix - 1u]; } else { - _416 = 0u; + _387 = 0u; } - uint tile_subix = _416; - Alloc param_2 = alloc_start.alloc; - uint param_3 = 8u * tile_subix; - uint param_4 = 8u * tile_count; - Alloc tiles_alloc = slice_mem(param_2, param_3, param_4); - path.tiles = TileRef{ tiles_alloc.offset }; + uint tile_subix = _387; + path.tiles = TileRef{ offset_start + (8u * tile_subix) }; Alloc param_5; - param_5.offset = v_181.conf.tile_alloc.offset; + param_5.offset = v_148.conf.tile_alloc.offset; PathRef param_6 = path_ref; Path param_7 = path; - Path_write(param_5, param_6, param_7, v_70, v_70BufferSize); + Path_write(param_5, param_6, param_7, v_53); } uint total_count = sh_tile_count[255] * 2u; - uint start_ix = alloc_start.alloc.offset >> uint(2); + uint start_ix = offset_start >> uint(2); for (uint i_1 = th_ix; i_1 < total_count; i_1 += 256u) { - Alloc param_8 = alloc_start.alloc; - uint param_9 = start_ix + i_1; - uint param_10 = 0u; - write_mem(param_8, param_9, param_10, v_70, v_70BufferSize); + v_53.memory[start_ix + i_1] = 0u; } } diff --git a/piet-gpu/shader/gen/tile_alloc.spv b/piet-gpu/shader/gen/tile_alloc.spv index dbc02a8e5b33b11e2aa77b3e30bc20d732eaf669..25a362cff49d23cb4b5a41581f9c372dcda883c5 100644 GIT binary patch literal 12352 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 literal 13360 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 KcbC|A*Z%@7(!8|* diff --git a/piet-gpu/shader/gen/transform_leaf.dxil b/piet-gpu/shader/gen/transform_leaf.dxil index f9f31e6ea1417ccaabda3cd5ad47c1b5642a4e85..942718668d53d2cf46a56480fbbd0f519ae8392a 100644 GIT binary patch delta 1382 zcmX|>eM}Q)9LJw)?~Vg|tfeg!O0dUUORr<7P(Y{l1xPh)F*xTIi6fcfT=vIecBgcI+>`r!fBAl& zC(rMBo`7yhmr2=8X8&7ack@}~oooF8d24n1Gz0+1zmi!FLyy^dSeDwR&-bi|Cuhar ziKf1=LcRcLBOh)tBeX8Ro+02(0RxDWuI0T(3Zvc@>wWR5Np zA^=)OJF!Pd*Hf+}h3j;Dng8Pbzz>KGz^kzOAf&$StW|+DXpmh2sGxoVx}>y*Af&>2 z1G;22${U18V+BG*6%giDy*$Oa0mws>ftwbOyT-qWWe&yqi~>fbppH7*4;j#w62|~g zVd$KazK}H>%j#F;6997?;iR9wLJvpLJQU@;198__;&;|H#r~73?ULpAUGDR-!zN%m zQB!uxiXp~TrP^{2$nOW#jU`zyTkiCPJ=a}&;%rM z5b1;Ej7v9ja|PXS&b!CHNTXv0_Q4yDt|4f|Ohe>Mz^!Le4j8LNVgSdOhTf(H56G}c z1p)LJBN4*DSQ7ZznDMV_!8_LtH0BI?3P1+2NYk<8wPGjsl@dTZhbYz=fEX6GkX`*VS`H8eqFI|QkN<=vj`Q?ZpE z=eguc`=T?obY0SI<&R&owGwsLQ2{!M$7-0E&Lf6bThl$gr56}10u3+ehVJDuWkS(MSJ>y0iY`;JX_M^r{Glae=Q1@{ z<($Nu4d|!{k=WD}a*Sxt;FhAnCom1L$lHl&9=G8)cr557?(%pTpXIUaW8wvmefT_& zRYOF37BsRifX8`k944lDjN}jM`Ygsm!)(QV9QHEHxv!s2i1zQf8^*zd$ zrp-}$5UO+wPTh;7>=mvy;LPaMv99v*0}d3J!4W{nu8R#l_hzFX;#p$wNSNH96Ix~Jl5`@T6hfQ74z8g zE*0eQY2JDseFvzZMPQ#)73z5m9-(ThIiw3WvUM_7;X+Mi@4-%??|uz;T&tc^_C+SQ zbG@$BAlXa|mPckT$Zji}yV<{F?{#$)G~OTDVLQm3xFaHi5S9=4;$j05yr?FcZU&=$ zMj>~z?T-XxN7{@}MTT?9(KczgDwNW%DCKUotFbtIQ4M{AjhV=?2C|xHvV5H|JvNai z(iVI)dDTIF*Cr2pBMH;l;;X-^p>MH>+e${xkQqeNt>J|04>uV|Tk-|S>lexI+a%%X ofrRUB@%3CSbQzntNlwg@`lKfU&%++WZf-|idj#;ScL{+10QkJe%K!iX delta 1356 zcmX|=ZA?>F7{|};ec?h{ynO*$%CNUpf!<1r$V)fJT6&9tsH<4AZlJq%;wE!iyT$2Z z#%-a9wO#5iGX0>d4l;C1D~RG`u9ugHufeQa$YPLyF1i>;jLG)FEW2014<|Xl|C9g! zoSf%5U8a~xL%S>Op{h;KKK>(hOU;4UrLj$Q8z2CH?wqC!fv$4v5mmakbV2fSyL!#I3;+h8zy|{$G7y3YAuBHEmG;CG zDFt9#|6Y6+ZT?#*DUr1%vAjrF$uQ^uWHAV;okX|V={xLHqqX_yh8VPT{Sefxb@o7L zx$_Ft?X+do!a-L#5|*<%eC8ewfB{Pd0fsnd>ptq&#Q1ibgw?6(PncbeW^9|;69qaP zJEU#cnBC>i4y%^{JYak68Fu6w?87)_z%aoZov?K+Y;W4mbI;R_&B@oIe&1pKqe|ck zRHs5NEB3mF6{A#(yZp)?v5>T;m|tqi#c`YJyr^~D!RED&{2?eK@giV&L30(1^BFfq zO*OlqsfID|xI*6z&A@JKo>}88er5Ha-MN z87Q-}jJ26Yho54_QS@E+6od7fx!FaY=95sbo#Bn+u|O%C=CQ4o5&+@Znw0v6BgNK_*9xJicimat=L_<08%6HR1#PoMLBuh|FOm>78Y*_BEsY z(>8B3)#9G=rWY5b+|b_kbL-@J&D$l|h>Wjhc~c94%(sROR@|ir;I$2@E6Hvp)XP{8 z9>d#Y?K&-M+);TwPvYj|nH6%Wmf%Z4@L_Am+ekdXFCW&cOLc)Apy^TSsc&%xwKqf^ z=IvJG9_T2}tlcV4WVc-^Kgdk7_#o6XZt6+0Mh=K*jr=U)(mmvuh)m=c5li-w4@6`m zcSLl2M>b|dy_=6jeigCqdvZX;!N_j{w$(AZ#T<7=u@`v)Y0q+$vcSUTn$=o_30VRX+3$mCZg{>Op+)!dBhzJEM5!T8$>tl^^wz{| zN#GfGL22=jv|zJU2j1I1$EH2EhiKsub%v!1CkPv9+UO9FF%*bcvxcq_F=kjUVv~yw zi8yU25;5eVLsb&@2(he0#M4c*akYTXWfpF|%D*gGZQ0+r7Y+J-IMzp9PRyV1J4t?OzVg<0D!wZce7IFux;=&6%=WPRX=M7s?Z z{~qA^!s?a6hxR)P<0td@Uc7$=)n7@iChMzSnf}yM`xMEL zlNzX{F8DI~f`bdDVBz_hJpM=gqHh&-F+gRJ_19my{_;>U#r;r}y7V>mlTY3^7F}?S Y6%Oi+{2BamA9Z<{DouIB5t*w00WQ48NB{r; diff --git a/piet-gpu/shader/gen/transform_leaf.hlsl b/piet-gpu/shader/gen/transform_leaf.hlsl index 8a3b3d5..d3347a6 100644 --- a/piet-gpu/shader/gen/transform_leaf.hlsl +++ b/piet-gpu/shader/gen/transform_leaf.hlsl @@ -27,6 +27,7 @@ struct TransformSeg struct Config { + uint mem_size; uint n_elements; uint n_pathseg; uint width_in_tiles; @@ -58,12 +59,12 @@ struct Config static const uint3 gl_WorkGroupSize = uint3(256u, 1u, 1u); -static const Transform _224 = { float4(1.0f, 0.0f, 0.0f, 1.0f), 0.0f.xx }; +static const Transform _225 = { float4(1.0f, 0.0f, 0.0f, 1.0f), 0.0f.xx }; RWByteAddressBuffer _71 : register(u0, space0); -ByteAddressBuffer _96 : register(t2, space0); -ByteAddressBuffer _278 : register(t1, space0); -ByteAddressBuffer _376 : register(t3, space0); +ByteAddressBuffer _97 : register(t2, space0); +ByteAddressBuffer _279 : register(t1, space0); +ByteAddressBuffer _377 : register(t3, space0); static uint3 gl_WorkGroupID; static uint3 gl_LocalInvocationID; @@ -80,12 +81,12 @@ groupshared Transform sh_scratch[256]; Transform Transform_read(TransformRef ref) { uint ix = ref.offset >> uint(2); - uint raw0 = _96.Load((ix + 0u) * 4 + 0); - uint raw1 = _96.Load((ix + 1u) * 4 + 0); - uint raw2 = _96.Load((ix + 2u) * 4 + 0); - uint raw3 = _96.Load((ix + 3u) * 4 + 0); - uint raw4 = _96.Load((ix + 4u) * 4 + 0); - uint raw5 = _96.Load((ix + 5u) * 4 + 0); + uint raw0 = _97.Load((ix + 0u) * 4 + 0); + uint raw1 = _97.Load((ix + 1u) * 4 + 0); + uint raw2 = _97.Load((ix + 2u) * 4 + 0); + uint raw3 = _97.Load((ix + 3u) * 4 + 0); + uint raw4 = _97.Load((ix + 4u) * 4 + 0); + uint raw5 = _97.Load((ix + 5u) * 4 + 0); Transform s; s.mat = float4(asfloat(raw0), asfloat(raw1), asfloat(raw2), asfloat(raw3)); s.translate = float2(asfloat(raw4), asfloat(raw5)); @@ -108,7 +109,7 @@ Transform combine_monoid(Transform a, Transform b) Transform monoid_identity() { - return _224; + return _225; } bool touch_mem(Alloc alloc, uint offset) @@ -124,7 +125,7 @@ void write_mem(Alloc alloc, uint offset, uint val) { return; } - _71.Store(offset * 4 + 8, val); + _71.Store(offset * 4 + 12, val); } void TransformSeg_write(Alloc a, TransformSegRef ref, TransformSeg s) @@ -159,8 +160,8 @@ void TransformSeg_write(Alloc a, TransformSegRef ref, TransformSeg s) void comp_main() { uint ix = gl_GlobalInvocationID.x * 8u; - TransformRef _285 = { _278.Load(84) + (ix * 24u) }; - TransformRef ref = _285; + TransformRef _286 = { _279.Load(88) + (ix * 24u) }; + TransformRef ref = _286; TransformRef param = ref; Transform agg = Transform_read(param); Transform local[8]; @@ -193,11 +194,11 @@ void comp_main() Transform row = monoid_identity(); if (gl_WorkGroupID.x > 0u) { - Transform _382; - _382.mat = asfloat(_376.Load4((gl_WorkGroupID.x - 1u) * 32 + 0)); - _382.translate = asfloat(_376.Load2((gl_WorkGroupID.x - 1u) * 32 + 16)); - row.mat = _382.mat; - row.translate = _382.translate; + Transform _383; + _383.mat = asfloat(_377.Load4((gl_WorkGroupID.x - 1u) * 32 + 0)); + _383.translate = asfloat(_377.Load2((gl_WorkGroupID.x - 1u) * 32 + 16)); + row.mat = _383.mat; + row.translate = _383.translate; } if (gl_LocalInvocationID.x > 0u) { @@ -211,13 +212,13 @@ void comp_main() Transform param_10 = row; Transform param_11 = local[i_2]; Transform m = combine_monoid(param_10, param_11); - TransformSeg _422 = { m.mat, m.translate }; - TransformSeg transform = _422; - TransformSegRef _432 = { _278.Load(36) + ((ix + i_2) * 24u) }; - TransformSegRef trans_ref = _432; - Alloc _436; - _436.offset = _278.Load(36); - param_12.offset = _436.offset; + TransformSeg _423 = { m.mat, m.translate }; + TransformSeg transform = _423; + TransformSegRef _433 = { _279.Load(40) + ((ix + i_2) * 24u) }; + TransformSegRef trans_ref = _433; + Alloc _437; + _437.offset = _279.Load(40); + param_12.offset = _437.offset; TransformSegRef param_13 = trans_ref; TransformSeg param_14 = transform; TransformSeg_write(param_12, param_13, param_14); diff --git a/piet-gpu/shader/gen/transform_leaf.msl b/piet-gpu/shader/gen/transform_leaf.msl index fe45438..01fefd1 100644 --- a/piet-gpu/shader/gen/transform_leaf.msl +++ b/piet-gpu/shader/gen/transform_leaf.msl @@ -75,6 +75,7 @@ struct Memory { uint mem_offset; uint mem_error; + uint blend_offset; uint memory[1]; }; @@ -90,6 +91,7 @@ struct Alloc_1 struct Config { + uint mem_size; uint n_elements; uint n_pathseg; uint width_in_tiles; @@ -139,15 +141,15 @@ struct ParentBuf constant uint3 gl_WorkGroupSize [[maybe_unused]] = uint3(256u, 1u, 1u); static inline __attribute__((always_inline)) -Transform Transform_read(thread const TransformRef& ref, const device SceneBuf& v_96) +Transform Transform_read(thread const TransformRef& ref, const device SceneBuf& v_97) { uint ix = ref.offset >> uint(2); - uint raw0 = v_96.scene[ix + 0u]; - uint raw1 = v_96.scene[ix + 1u]; - uint raw2 = v_96.scene[ix + 2u]; - uint raw3 = v_96.scene[ix + 3u]; - uint raw4 = v_96.scene[ix + 4u]; - uint raw5 = v_96.scene[ix + 5u]; + uint raw0 = v_97.scene[ix + 0u]; + uint raw1 = v_97.scene[ix + 1u]; + uint raw2 = v_97.scene[ix + 2u]; + uint raw3 = v_97.scene[ix + 3u]; + uint raw4 = v_97.scene[ix + 4u]; + uint raw5 = v_97.scene[ix + 5u]; Transform s; s.mat = float4(as_type(raw0), as_type(raw1), as_type(raw2), as_type(raw3)); s.translate = float2(as_type(raw4), as_type(raw5)); @@ -223,13 +225,13 @@ void TransformSeg_write(thread const Alloc& a, thread const TransformSegRef& ref write_mem(param_15, param_16, param_17, v_71); } -kernel void main0(device Memory& v_71 [[buffer(0)]], const device ConfigBuf& _278 [[buffer(1)]], const device SceneBuf& v_96 [[buffer(2)]], const device ParentBuf& _376 [[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& v_71 [[buffer(0)]], const device ConfigBuf& _279 [[buffer(1)]], const device SceneBuf& v_97 [[buffer(2)]], const device ParentBuf& _377 [[buffer(3)]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]], uint3 gl_WorkGroupID [[threadgroup_position_in_grid]]) { threadgroup Transform sh_scratch[256]; uint ix = gl_GlobalInvocationID.x * 8u; - TransformRef ref = TransformRef{ _278.conf.trans_offset + (ix * 24u) }; + TransformRef ref = TransformRef{ _279.conf.trans_offset + (ix * 24u) }; TransformRef param = ref; - Transform agg = Transform_read(param, v_96); + Transform agg = Transform_read(param, v_97); spvUnsafeArray local; local[0] = agg; for (uint i = 1u; i < 8u; i++) @@ -238,7 +240,7 @@ kernel void main0(device Memory& v_71 [[buffer(0)]], const device ConfigBuf& _27 uint param_2 = i; TransformRef param_3 = Transform_index(param_1, param_2); Transform param_4 = agg; - Transform param_5 = Transform_read(param_3, v_96); + Transform param_5 = Transform_read(param_3, v_97); agg = combine_monoid(param_4, param_5); local[i] = agg; } @@ -260,9 +262,9 @@ kernel void main0(device Memory& v_71 [[buffer(0)]], const device ConfigBuf& _27 Transform row = monoid_identity(); if (gl_WorkGroupID.x > 0u) { - uint _379 = gl_WorkGroupID.x - 1u; - row.mat = _376.parent[_379].mat; - row.translate = _376.parent[_379].translate; + uint _380 = gl_WorkGroupID.x - 1u; + row.mat = _377.parent[_380].mat; + row.translate = _377.parent[_380].translate; } if (gl_LocalInvocationID.x > 0u) { @@ -277,8 +279,8 @@ kernel void main0(device Memory& v_71 [[buffer(0)]], const device ConfigBuf& _27 Transform param_11 = local[i_2]; Transform m = combine_monoid(param_10, param_11); TransformSeg transform = TransformSeg{ m.mat, m.translate }; - TransformSegRef trans_ref = TransformSegRef{ _278.conf.trans_alloc.offset + ((ix + i_2) * 24u) }; - param_12.offset = _278.conf.trans_alloc.offset; + TransformSegRef trans_ref = TransformSegRef{ _279.conf.trans_alloc.offset + ((ix + i_2) * 24u) }; + param_12.offset = _279.conf.trans_alloc.offset; TransformSegRef param_13 = trans_ref; TransformSeg param_14 = transform; TransformSeg_write(param_12, param_13, param_14, v_71); diff --git a/piet-gpu/shader/gen/transform_leaf.spv b/piet-gpu/shader/gen/transform_leaf.spv index b7390994c2522a13c274a0c50bf0a1c8e2e3139a..a0081bf8bb498be78a7016133a149c7f88edfa5b 100644 GIT binary patch literal 13088 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 diff --git a/piet-gpu/shader/gen/transform_reduce.dxil b/piet-gpu/shader/gen/transform_reduce.dxil index 978dd98aca8a278bde85fc024c77ca5695bdfcda..6986f8f9ea8fecedbed2cabcb3f92049c7751005 100644 GIT binary patch delta 58 zcmV-A0LA~@B-|tvL|8&Yeg09UHA$!$sLQa%EbbuSu@uk;5ZUph0X2~AfRRR5(zVFd Qh_mzuCk6p*vm6dU1SxJBc>n+a delta 58 zcmV-A0LA~@B-|tvL|8&Y#zcUskJ3vR3{+Vg6mY2Ru@uk;5Y2I-spmdi{|h)YR7MrD QhqLqtCk6p(vm6dU1i@q$mH+?% diff --git a/piet-gpu/shader/gen/transform_reduce.hlsl b/piet-gpu/shader/gen/transform_reduce.hlsl index bd14f79..90ea55f 100644 --- a/piet-gpu/shader/gen/transform_reduce.hlsl +++ b/piet-gpu/shader/gen/transform_reduce.hlsl @@ -16,6 +16,7 @@ struct Alloc struct Config { + uint mem_size; uint n_elements; uint n_pathseg; uint width_in_tiles; @@ -96,7 +97,7 @@ Transform combine_monoid(Transform a, Transform b) void comp_main() { uint ix = gl_GlobalInvocationID.x * 8u; - TransformRef _168 = { _161.Load(84) + (ix * 24u) }; + TransformRef _168 = { _161.Load(88) + (ix * 24u) }; TransformRef ref = _168; TransformRef param = ref; Transform agg = Transform_read(param); diff --git a/piet-gpu/shader/gen/transform_reduce.msl b/piet-gpu/shader/gen/transform_reduce.msl index 62da531..6ae57e7 100644 --- a/piet-gpu/shader/gen/transform_reduce.msl +++ b/piet-gpu/shader/gen/transform_reduce.msl @@ -28,6 +28,7 @@ struct Alloc struct Config { + uint mem_size; uint n_elements; uint n_pathseg; uint width_in_tiles; @@ -78,6 +79,7 @@ struct Memory { uint mem_offset; uint mem_error; + uint blend_offset; uint memory[1]; }; diff --git a/piet-gpu/shader/gen/transform_reduce.spv b/piet-gpu/shader/gen/transform_reduce.spv index 6aa6b941f2f2323acd46ccaf083aad3cc57cf7e0..fc8e58adfe90d8e6e7f2fa348f685e72cc7f5a3d 100644 GIT binary patch delta 455 zcmZ9Iy-ve05XbF0cGJ%^^dkfdI&@-SL`ZDi5buDZ(54W{O{*pn0*Q?mK*!Rh;suaE znL6+YJVZAZBp8qo6PLJBC2Uzf-~Z?ToqgAT?>`S&dmN0tIJ^l64uNxlI|ZLPZULjn zoBGLR99-mTF;^MfGf542V$$W9PeK)VzEYFH#zDXe9g3(h135&b$CI>f;Xc}8}Na#4J9sjw~!ys{Hrh;O*VIU z-hC7Lyt&^(LccBRSu5>4m(|H~x{D6na!DPS^DfiIkQez)33_B!1l-j YR&@s+>kqV(9$GdvMa~J5o;Hpfe=(I^g#Z8m delta 389 zcmY+8Jx;?w5QTTVySDQKPDp|=mSrd?(o!N(MB)Hk09j6Oh$Ul3#04!97f1#u)6*cL ztvCWDN1#BWp`>T*U?jBCYUjQ0&A!jU?cn*G_tGFrqRS}FXN>7|mW(mLIk!Q>NA7x@ z=1CM^O!6R3gFH^6*&iqHo!gEiVn|+?B-x1G)fOGw!UhBT!gWm2!!*q*sA6h(CTy=x z?ljCN!El&e{~|gw%PtL^3m=-eqFo#KDqPsa58-k%)DdZCptoYqj#v!QF=7YvPw#0$eSy*?_Q}