mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-01-31 01:15:24 +01:00
Compare commits
1280 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
660a165533 | ||
|
|
bfe2d5abb2 | ||
|
|
d5b36da6b0 | ||
|
|
328cebd5fc | ||
|
|
579cb7bd27 | ||
|
|
aab889535f | ||
|
|
e0362f7879 | ||
|
|
009ae1fb02 | ||
|
|
d40289e977 | ||
|
|
c2fd4af163 | ||
|
|
5bdee3a611 | ||
|
|
cb026a6946 | ||
|
|
cb5124da4b | ||
|
|
7c88af9c73 | ||
|
|
465a31bbd5 | ||
|
|
6deb43bde2 | ||
|
|
8e7dcb83a8 | ||
|
|
51ead1e00f | ||
|
|
27bcb7c29a | ||
|
|
aaed4a4983 | ||
|
|
748f232976 | ||
|
|
a33612cf7d | ||
|
|
5c123f3183 | ||
|
|
d30a7fb991 | ||
|
|
d4f661c27c | ||
|
|
6d05d0220d | ||
|
|
7fab935c2d | ||
|
|
cd120c3cfd | ||
|
|
0180ec060b | ||
|
|
cf4412ecbe | ||
|
|
743b0b11d8 | ||
|
|
e8c2cfa843 | ||
|
|
764875ddbf | ||
|
|
92c7eaa383 | ||
|
|
4d2c1a82c9 | ||
|
|
eb50aaea35 | ||
|
|
d69c71e058 | ||
|
|
7cc8c7eee6 | ||
|
|
dd96f2c296 | ||
|
|
3cb2f3d2d9 | ||
|
|
1f9a9940e9 | ||
|
|
8164f2b2db | ||
|
|
d0c54de330 | ||
|
|
af5cd8d48e | ||
|
|
a43f051852 | ||
|
|
0f8c5066e3 | ||
|
|
1bf1f458d0 | ||
|
|
5ef1993496 | ||
|
|
80baa73578 | ||
|
|
b46c85ee7f | ||
|
|
7f233ca620 | ||
|
|
47fe2344a5 | ||
|
|
4e763d6ff7 | ||
|
|
e1cc994cca | ||
|
|
5b7f85e571 | ||
|
|
7475cfb325 | ||
|
|
cee01a22e1 | ||
|
|
c6437bccad | ||
|
|
7419311296 | ||
|
|
2807a06d76 | ||
|
|
14f76c5627 | ||
|
|
260eaa6c6c | ||
|
|
461f01718c | ||
|
|
65e209b0f0 | ||
|
|
36ffe3a521 | ||
|
|
359d552245 | ||
|
|
180377181d | ||
|
|
2805bf376a | ||
|
|
eaa834d238 | ||
|
|
8cc28c25d8 | ||
|
|
0cd14c9919 | ||
|
|
3a33400ca6 | ||
|
|
2f5afc40b6 | ||
|
|
fe9915cbd0 | ||
|
|
70ce7e024f | ||
|
|
cab81ac23a | ||
|
|
dbb6d2769f | ||
|
|
cce1b82e11 | ||
|
|
e906717146 | ||
|
|
a841151446 | ||
|
|
426261ebbe | ||
|
|
aedaf5a9a7 | ||
|
|
d83417ba0d | ||
|
|
23cd5a9da7 | ||
|
|
1fd017f410 | ||
|
|
0afc9d6d10 | ||
|
|
2f4583f2e4 | ||
|
|
86af608bfc | ||
|
|
3a7489b2cc | ||
|
|
51947f8f93 | ||
|
|
e07f02d9bc | ||
|
|
6c07160503 | ||
|
|
a02e1b3487 | ||
|
|
86a7e97025 | ||
|
|
5d641e4a9d | ||
|
|
a5f7b4e8c6 | ||
|
|
9bb30dcb44 | ||
|
|
4eb0b097d6 | ||
|
|
38f61b9658 | ||
|
|
80ffb82a4a | ||
|
|
3cecd894a3 | ||
|
|
02f0921b2d | ||
|
|
94bd268a51 | ||
|
|
746174d73d | ||
|
|
98c74b939a | ||
|
|
775f381685 | ||
|
|
3d2ecafb01 | ||
|
|
ee6b080fa2 | ||
|
|
cf0bf4db5a | ||
|
|
7f211d7fbf | ||
|
|
35efe8fcb6 | ||
|
|
eb0b23a284 | ||
|
|
a4b7b6e9d7 | ||
|
|
4ac3adcdd8 | ||
|
|
7f4c4b0e3e | ||
|
|
37c8d988eb | ||
|
|
dafb9042e4 | ||
|
|
e1ba9bacda | ||
|
|
169022923c | ||
|
|
4acf27234e | ||
|
|
e9977f2a2c | ||
|
|
df8d809506 | ||
|
|
4d89fec9ff | ||
|
|
27b641d048 | ||
|
|
e475c0df06 | ||
|
|
9877129815 | ||
|
|
3376001d45 | ||
|
|
0cbd884234 | ||
|
|
3e8327e934 | ||
|
|
ca9d88f47b | ||
|
|
bf92ffffa3 | ||
|
|
eccec21ada | ||
|
|
03aaf7db6a | ||
|
|
6d9e0482b4 | ||
|
|
34f2328a79 | ||
|
|
2569193b05 | ||
|
|
b935ec3d19 | ||
|
|
e0e6b0d9a5 | ||
|
|
580218d495 | ||
|
|
519f280fa5 | ||
|
|
a33ee13bb4 | ||
|
|
0c70cc7e5a | ||
|
|
2cba346ff5 | ||
|
|
db2509edb3 | ||
|
|
e3063d6cd6 | ||
|
|
8d30e8cee8 | ||
|
|
ff2f1998ad | ||
|
|
7942ee438a | ||
|
|
f322dfb1d4 | ||
|
|
a7f5ddfe0d | ||
|
|
0cdfb75fd0 | ||
|
|
35624a12d9 | ||
|
|
9b147cc57c | ||
|
|
10e13cfece | ||
|
|
7b2eb7bc47 | ||
|
|
ab1cb802d8 | ||
|
|
366cdd8df0 | ||
|
|
bc3cfb1373 | ||
|
|
db6792af2e | ||
|
|
a1485fb7cd | ||
|
|
c72c309218 | ||
|
|
58899a9ed3 | ||
|
|
0823c70460 | ||
|
|
e5c29a3975 | ||
|
|
1174ae99c9 | ||
|
|
e2d3680038 | ||
|
|
8630893cb1 | ||
|
|
53598b970d | ||
|
|
89de00ac36 | ||
|
|
d5ddf07958 | ||
|
|
30dcf4a14a | ||
|
|
a87710e4bc | ||
|
|
a12f87fec2 | ||
|
|
8ba9bba094 | ||
|
|
1363571c14 | ||
|
|
80de666fcc | ||
|
|
ff0a2f84fa | ||
|
|
0676f145bc | ||
|
|
e19ae2bf60 | ||
|
|
7782d930d5 | ||
|
|
d1a53fe29b | ||
|
|
c484cf286c | ||
|
|
f8882c4da6 | ||
|
|
52c17e67a5 | ||
|
|
615cd00147 | ||
|
|
cb0bf953d3 | ||
|
|
26a68ef76a | ||
|
|
e4c1dc2359 | ||
|
|
40425e3bee | ||
|
|
e51e4a35fe | ||
|
|
bd1b9ea718 | ||
|
|
faaa376232 | ||
|
|
e9ca1a6ead | ||
|
|
4d3149eacb | ||
|
|
78822c96fb | ||
|
|
a78617b987 | ||
|
|
3059ab2b12 | ||
|
|
1d0f6cc5b7 | ||
|
|
38a35043a8 | ||
|
|
7385cbe40a | ||
|
|
9955e07470 | ||
|
|
74db386144 | ||
|
|
3f72efeb7a | ||
|
|
d0f8905439 | ||
|
|
5a60259ef5 | ||
|
|
c8dffccaa7 | ||
|
|
87a82b16ff | ||
|
|
5666902638 | ||
|
|
f1dc232f91 | ||
|
|
5476c5a17f | ||
|
|
9aabb197e6 | ||
|
|
c2488c9269 | ||
|
|
7e40ab8e7e | ||
|
|
902b3c5033 | ||
|
|
4d1afb9fdd | ||
|
|
4209900351 | ||
|
|
780c599b49 | ||
|
|
908d35bf77 | ||
|
|
cfea84b934 | ||
|
|
e5d94e255b | ||
|
|
080858b97c | ||
|
|
d883076573 | ||
|
|
b80101fbd6 | ||
|
|
aca775f8b8 | ||
|
|
4f4a26769c | ||
|
|
d19eaa1b8e | ||
|
|
be1af0cd0f | ||
|
|
6ab02e76f1 | ||
|
|
f87bc7d72b | ||
|
|
086f4f11e1 | ||
|
|
6f54da6234 | ||
|
|
44f47f11b8 | ||
|
|
b5a2d04b2e | ||
|
|
8508ebb7d3 | ||
|
|
3234e45f33 | ||
|
|
53d1320d83 | ||
|
|
9b545809be | ||
|
|
79400acf2a | ||
|
|
3107c4103a | ||
|
|
68c88f692e | ||
|
|
df19b37d6d | ||
|
|
1b5c352566 | ||
|
|
bed6a9e4d4 | ||
|
|
d602ad1d3e | ||
|
|
51c31347df | ||
|
|
00876e7076 | ||
|
|
47eb499893 | ||
|
|
b8680c3139 | ||
|
|
9b4e3b8f74 | ||
|
|
3e858167bc | ||
|
|
44d66555cc | ||
|
|
c5438ceca3 | ||
|
|
3e1927ae44 | ||
|
|
b688117002 | ||
|
|
e62e6fb6c3 | ||
|
|
262e94e5d7 | ||
|
|
11a4b4e7ff | ||
|
|
a98cfcf28c | ||
|
|
d02f30ee62 | ||
|
|
c0bf01a646 | ||
|
|
babb985e9e | ||
|
|
e379c8317d | ||
|
|
5098277474 | ||
|
|
4a94cb6cbd | ||
|
|
e245454b91 | ||
|
|
b003eadd2d | ||
|
|
a5984d8213 | ||
|
|
4dbd95b0bb | ||
|
|
68803229da | ||
|
|
b661a2a149 | ||
|
|
63cd355d7a | ||
|
|
0f5ff68679 | ||
|
|
bd74921926 | ||
|
|
78f83514f4 | ||
|
|
2c36259b88 | ||
|
|
32a0bed6af | ||
|
|
d415f8364c | ||
|
|
7c768b6833 | ||
|
|
773f6968a4 | ||
|
|
1021199512 | ||
|
|
08ef9e2bd9 | ||
|
|
6ba3f96f27 | ||
|
|
7d5b7bc3ce | ||
|
|
0d43d30346 | ||
|
|
da824b4e9e | ||
|
|
ed08b5f34e | ||
|
|
0ce312c1c3 | ||
|
|
07bc2fa452 | ||
|
|
bfd2775074 | ||
|
|
94ccafd745 | ||
|
|
5c6049c4ae | ||
|
|
090464c42d | ||
|
|
89a00db3d6 | ||
|
|
fc415dff93 | ||
|
|
f648a9a438 | ||
|
|
cac6669423 | ||
|
|
7db487a49b | ||
|
|
c96607fe37 | ||
|
|
ba0dae5f57 | ||
|
|
5fe5148e86 | ||
|
|
5445cb516a | ||
|
|
84a29ffcca | ||
|
|
e56075976f | ||
|
|
0f709735c0 | ||
|
|
ad3f0fd6cd | ||
|
|
fbfdacd589 | ||
|
|
aedc51e151 | ||
|
|
fe95a697f4 | ||
|
|
f99cf28429 | ||
|
|
bea1eb0cf9 | ||
|
|
3cf21e0ab6 | ||
|
|
521b32c253 | ||
|
|
190b525ca6 | ||
|
|
baa00e4d38 | ||
|
|
51bc6c1465 | ||
|
|
ea8492082a | ||
|
|
9d1fd23d78 | ||
|
|
9ff575377d | ||
|
|
47250293cd | ||
|
|
f9b346521d | ||
|
|
b5a4c71eff | ||
|
|
2604256424 | ||
|
|
906ac6a8ea | ||
|
|
3db21e0579 | ||
|
|
abd03884de | ||
|
|
a159256b07 | ||
|
|
d9a2618b7a | ||
|
|
dca0291cfb | ||
|
|
b261873471 | ||
|
|
bfd01c913a | ||
|
|
818b3fe779 | ||
|
|
66a28e4488 | ||
|
|
28e2ecf920 | ||
|
|
d3dbf53fa7 | ||
|
|
8fb2940f25 | ||
|
|
55498762f9 | ||
|
|
50baaf39d6 | ||
|
|
4743ccac8c | ||
|
|
0dc3fc6228 | ||
|
|
a7a4583c84 | ||
|
|
6b52937262 | ||
|
|
df9caf6fb8 | ||
|
|
be5f8d2e60 | ||
|
|
b0e01ca518 | ||
|
|
4e85272393 | ||
|
|
bffed9a839 | ||
|
|
7ed0c0d031 | ||
|
|
ae6e4c98f6 | ||
|
|
38cfa9912d | ||
|
|
b02318e2b6 | ||
|
|
db45263221 | ||
|
|
3fd9625f1c | ||
|
|
2978b6050d | ||
|
|
274acddcf1 | ||
|
|
8dffc85707 | ||
|
|
f799631a70 | ||
|
|
d744f0dfeb | ||
|
|
bdb8de6d3b | ||
|
|
e751f367ca | ||
|
|
13f2d87ba8 | ||
|
|
3cac2cf7c2 | ||
|
|
a67409bfc6 | ||
|
|
6a556c9968 | ||
|
|
4d93285ca2 | ||
|
|
98c35a308d | ||
|
|
7da97e6d80 | ||
|
|
edf686752a | ||
|
|
b7e17646a3 | ||
|
|
3f437e7496 | ||
|
|
7ab6c62dee | ||
|
|
2a7bf35f20 | ||
|
|
08552a83cc | ||
|
|
ee417ee4c5 | ||
|
|
869837f5f0 | ||
|
|
7ab6bac39a | ||
|
|
e388294004 | ||
|
|
bba5ef67ff | ||
|
|
83dc2de6ca | ||
|
|
f47fbda0e6 | ||
|
|
d34d2af849 | ||
|
|
db92af8ca4 | ||
|
|
47897fc2be | ||
|
|
b451602f69 | ||
|
|
96ac35a4bd | ||
|
|
ddd33a0701 | ||
|
|
d5e4a1c896 | ||
|
|
9674fd773c | ||
|
|
01e916b132 | ||
|
|
1867791653 | ||
|
|
bc11ff0571 | ||
|
|
e550cf9b63 | ||
|
|
bafd87694c | ||
|
|
caf6298ad1 | ||
|
|
7f0d287512 | ||
|
|
2177de2238 | ||
|
|
32973c746e | ||
|
|
3bf94330ef | ||
|
|
34ae3b1eb0 | ||
|
|
b9288d4845 | ||
|
|
a13cb32eb1 | ||
|
|
9d72ad785d | ||
|
|
0afde446c4 | ||
|
|
49111a6fbe | ||
|
|
251140fd52 | ||
|
|
f57c7d216c | ||
|
|
36157402c8 | ||
|
|
51ee8f4015 | ||
|
|
fb85bb9076 | ||
|
|
0a391e2407 | ||
|
|
52f03c900f | ||
|
|
74be344ce6 | ||
|
|
14574ef4eb | ||
|
|
fe565afff0 | ||
|
|
5fcd0f94c2 | ||
|
|
e22609ea29 | ||
|
|
1d068ffde9 | ||
|
|
fe133b3c0c | ||
|
|
eb42ce3343 | ||
|
|
c50c24e3c9 | ||
|
|
ab85d759b0 | ||
|
|
2ef2adf517 | ||
|
|
c13e23ab68 | ||
|
|
ec57e9c178 | ||
|
|
b5a2fe3223 | ||
|
|
88d378d293 | ||
|
|
c79e6ecc2c | ||
|
|
a46ee17537 | ||
|
|
b6dbffa251 | ||
|
|
4af1f7846d | ||
|
|
f5e706f753 | ||
|
|
2dcf602666 | ||
|
|
42be070727 | ||
|
|
98ded09177 | ||
|
|
24cb93d7c5 | ||
|
|
535ebdbc8c | ||
|
|
42a6076967 | ||
|
|
fb27549bed | ||
|
|
6720c9ef83 | ||
|
|
b7c135586e | ||
|
|
f47b55ce42 | ||
|
|
a635796b12 | ||
|
|
fbbd11bc18 | ||
|
|
4134dd015d | ||
|
|
b0dedcc590 | ||
|
|
f5ce81d72c | ||
|
|
9810d2923c | ||
|
|
92ede270ce | ||
|
|
427096dc29 | ||
|
|
a7f948c00f | ||
|
|
4afa5b8409 | ||
|
|
7f285b2164 | ||
|
|
9dac7825d7 | ||
|
|
305d0e81d6 | ||
|
|
56f3d6ea09 | ||
|
|
edc04fb8e3 | ||
|
|
a72f78fd79 | ||
|
|
aadd0fd65e | ||
|
|
e2bc80a96f | ||
|
|
704e531c1f | ||
|
|
203981182d | ||
|
|
14b67e3ac3 | ||
|
|
f83e11892b | ||
|
|
a8c549baee | ||
|
|
13142dd31d | ||
|
|
ed5c364603 | ||
|
|
0ccf7d2e10 | ||
|
|
ebb0dc7cc5 | ||
|
|
52ebebc739 | ||
|
|
c8141261f2 | ||
|
|
9c7750b85d | ||
|
|
bf10b55aa1 | ||
|
|
43d9ea99b0 | ||
|
|
37f28e95b6 | ||
|
|
1870193615 | ||
|
|
189374d19c | ||
|
|
ac04695edd | ||
|
|
93bf9db0b4 | ||
|
|
9219a1a38b | ||
|
|
1a28d6f0d1 | ||
|
|
aca1b4478e | ||
|
|
9a794f7aaa | ||
|
|
6e65558d42 | ||
|
|
74936f49e0 | ||
|
|
9864cd97de | ||
|
|
6d7deb57a0 | ||
|
|
21876ff590 | ||
|
|
c543c05968 | ||
|
|
a5537da4df | ||
|
|
edaddeecc4 | ||
|
|
6b30a199da | ||
|
|
23c637e3e5 | ||
|
|
313b0fe3b5 | ||
|
|
90818c3627 | ||
|
|
89877aba58 | ||
|
|
80cb381b35 | ||
|
|
73a4d258a9 | ||
|
|
26fcbc712e | ||
|
|
7e4bc6ba22 | ||
|
|
a975a472b8 | ||
|
|
29a1304218 | ||
|
|
af5279cf56 | ||
|
|
4a59a80f1d | ||
|
|
501088b859 | ||
|
|
aa0bd38134 | ||
|
|
35d3bf2f2d | ||
|
|
09d0ff2577 | ||
|
|
567b0173ec | ||
|
|
20411aa8d6 | ||
|
|
be94aa97db | ||
|
|
f65c1dd5bc | ||
|
|
a92297ceec | ||
|
|
a8ea4e55ef | ||
|
|
3195befab1 | ||
|
|
2cdc65c06b | ||
|
|
0529715640 | ||
|
|
2534cb2c9d | ||
|
|
49f4c36b0e | ||
|
|
4b08672f99 | ||
|
|
73f7cb1fa7 | ||
|
|
8f64d118c8 | ||
|
|
e31625d2bd | ||
|
|
7907ead7fc | ||
|
|
276193d876 | ||
|
|
9c61053fe0 | ||
|
|
8779bf44d8 | ||
|
|
5ea4c55a6a | ||
|
|
4662d0e5dc | ||
|
|
cc5f594384 | ||
|
|
d9ff9d7aa1 | ||
|
|
08b9037781 | ||
|
|
59125c9b12 | ||
|
|
e5ba376985 | ||
|
|
165595008e | ||
|
|
8dc905e827 | ||
|
|
7cc8e5887f | ||
|
|
3599438e57 | ||
|
|
88515d58ab | ||
|
|
338e1a71a9 | ||
|
|
d9fc763f82 | ||
|
|
7eeb6c7aca | ||
|
|
a045c917e7 | ||
|
|
a052a43b84 | ||
|
|
94d87a35be | ||
|
|
0c8c798051 | ||
|
|
c9ddab444a | ||
|
|
1222270e44 | ||
|
|
86b5de8785 | ||
|
|
e97f03ed8b | ||
|
|
0a76c5a64d | ||
|
|
01a1b017e8 | ||
|
|
ddefb8a393 | ||
|
|
62a5cd98da | ||
|
|
8ad9d7d047 | ||
|
|
10ed797881 | ||
|
|
23918e25c2 | ||
|
|
de022ab68d | ||
|
|
5561884126 | ||
|
|
406d7468dd | ||
|
|
41124994fa | ||
|
|
c4e048eedf | ||
|
|
eff9b4167c | ||
|
|
47931a0689 | ||
|
|
34ca40fa2a | ||
|
|
821f732ff9 | ||
|
|
54c8ef7ee6 | ||
|
|
dc9e531cb1 | ||
|
|
2bd151e6f2 | ||
|
|
ae084643c4 | ||
|
|
bd1b91b862 | ||
|
|
f221c85e17 | ||
|
|
e2fe93e403 | ||
|
|
f98e23f061 | ||
|
|
18f6518d41 | ||
|
|
74598b3055 | ||
|
|
6159cd4114 | ||
|
|
3c70d7f575 | ||
|
|
bd70f1ca4a | ||
|
|
0e67507d3a | ||
|
|
beab573758 | ||
|
|
e46890fd76 | ||
|
|
3888638f8c | ||
|
|
44778c374f | ||
|
|
207d4df5e7 | ||
|
|
d454a7dafc | ||
|
|
53b4ddc4cb | ||
|
|
23c8780bff | ||
|
|
958ab4048c | ||
|
|
657d20d36e | ||
|
|
fde045241f | ||
|
|
b3be566426 | ||
|
|
1eebb550a8 | ||
|
|
fbe5f88417 | ||
|
|
d9609b9f51 | ||
|
|
815d7b2967 | ||
|
|
98ce7c81c8 | ||
|
|
e4d8f3d901 | ||
|
|
ca5dfdd25c | ||
|
|
11634c6567 | ||
|
|
f6a313f1a5 | ||
|
|
1a46898cde | ||
|
|
63ee30cbb3 | ||
|
|
20241f301b | ||
|
|
61c653c49c | ||
|
|
a7f4f992e1 | ||
|
|
daa9953d40 | ||
|
|
4771198c30 | ||
|
|
d8f3717119 | ||
|
|
33ab6fd09b | ||
|
|
1391e1339e | ||
|
|
2f2614737a | ||
|
|
85a62427f9 | ||
|
|
8fd91cb7df | ||
|
|
c5820a4f54 | ||
|
|
572eae596c | ||
|
|
6f3c189129 | ||
|
|
7a0017bd40 | ||
|
|
74f840f66b | ||
|
|
4a7c194157 | ||
|
|
116eb6dc5b | ||
|
|
0bab3c74ea | ||
|
|
6328de43e3 | ||
|
|
5becdc9ab5 | ||
|
|
26b6394b67 | ||
|
|
1b6086ab62 | ||
|
|
87a4536a2e | ||
|
|
d20b897ac8 | ||
|
|
6f26b064b9 | ||
|
|
3a2c78d17c | ||
|
|
19d375b4bd | ||
|
|
8162461618 | ||
|
|
0cadc3189c | ||
|
|
e971a9ebf5 | ||
|
|
19f85713ce | ||
|
|
4c41de6013 | ||
|
|
96f9cde1bc | ||
|
|
3feef0824c | ||
|
|
5f2ab55c93 | ||
|
|
0f75bfe17d | ||
|
|
7faa132622 | ||
|
|
b69e6da105 | ||
|
|
11edb128e9 | ||
|
|
fc4407aaef | ||
|
|
2a418e3282 | ||
|
|
59415542ff | ||
|
|
00416e26bb | ||
|
|
e936398e17 | ||
|
|
e3b45c3efd | ||
|
|
7ad759007a | ||
|
|
2fab554360 | ||
|
|
e98b6e6cb3 | ||
|
|
aa5147a52b | ||
|
|
83ebbe95c5 | ||
|
|
2ad71d046b | ||
|
|
099e1f900d | ||
|
|
0c6537e917 | ||
|
|
8937fb3d11 | ||
|
|
028085f8f9 | ||
|
|
b33932f47b | ||
|
|
d122939183 | ||
|
|
b09eb4e42d | ||
|
|
e75ddb878a | ||
|
|
6e3dca5a1a | ||
|
|
b069f51e6f | ||
|
|
bb1e6d06e4 | ||
|
|
f747abcc3b | ||
|
|
77738f72b4 | ||
|
|
61f11d12ff | ||
|
|
7e00b2c9a9 | ||
|
|
7dd4ab947b | ||
|
|
be213695a0 | ||
|
|
cde548a2f9 | ||
|
|
e76481f454 | ||
|
|
1a8d1d443e | ||
|
|
a14c8eb7d5 | ||
|
|
97ea52a6c1 | ||
|
|
0617182dfc | ||
|
|
bd99d76416 | ||
|
|
fdbe9305a9 | ||
|
|
fd772e42da | ||
|
|
df56797b38 | ||
|
|
28e72110bb | ||
|
|
e451c5f70c | ||
|
|
20b8fef950 | ||
|
|
47449a424d | ||
|
|
e8ab761be4 | ||
|
|
6463fc541b | ||
|
|
08b3194b96 | ||
|
|
62fa768e60 | ||
|
|
cafe7a9dc2 | ||
|
|
7ffc671c3a | ||
|
|
eaeea83547 | ||
|
|
76b758dbd2 | ||
|
|
ab19b109ce | ||
|
|
73c3216ca6 | ||
|
|
ee56c5b13c | ||
|
|
46768c8624 | ||
|
|
24340caa35 | ||
|
|
6dc92b00a6 | ||
|
|
43a81a3cb1 | ||
|
|
0df388cd96 | ||
|
|
c342f9cac5 | ||
|
|
21042934e3 | ||
|
|
888e024d0c | ||
|
|
fe9794ba53 | ||
|
|
e546acec1e | ||
|
|
272ad1d37f | ||
|
|
a87e661745 | ||
|
|
f750eb56ab | ||
|
|
118b604a66 | ||
|
|
cfd9343230 | ||
|
|
8bcc2c94b9 | ||
|
|
377930d004 | ||
|
|
a9526b7cc1 | ||
|
|
ff01a6359b | ||
|
|
6c3ea29157 | ||
|
|
36be1a8f7d | ||
|
|
691c3764ac | ||
|
|
aa0292ada1 | ||
|
|
e4429527e3 | ||
|
|
f06285e3a4 | ||
|
|
6d47cefefd | ||
|
|
fe71fc6a30 | ||
|
|
0e649bc70b | ||
|
|
e0915d8372 | ||
|
|
3f4d9cda85 | ||
|
|
4e25988961 | ||
|
|
b1502c754a | ||
|
|
303cef78ed | ||
|
|
a72f282156 | ||
|
|
32e77a2bd3 | ||
|
|
a53fdfae82 | ||
|
|
806ab5ad01 | ||
|
|
f5ddc0d7c6 | ||
|
|
a6eb5d32d8 | ||
|
|
b03c982706 | ||
|
|
7835ebd14f | ||
|
|
fd67049cf9 | ||
|
|
c2f05371e4 | ||
|
|
5c9c071086 | ||
|
|
f7677105ed | ||
|
|
9e2a73c7a7 | ||
|
|
c9f5f03d02 | ||
|
|
c313736334 | ||
|
|
1eb9a60b4a | ||
|
|
e50fe50daf | ||
|
|
643c83c2a0 | ||
|
|
44733d7655 | ||
|
|
fcdd43fc78 | ||
|
|
78643623c3 | ||
|
|
b27846ce39 | ||
|
|
b87b8eb7bb | ||
|
|
709dfdd3f2 | ||
|
|
faef28d5c4 | ||
|
|
309dd4f847 | ||
|
|
506897fab2 | ||
|
|
4e0aff053c | ||
|
|
2ba6fbbcc2 | ||
|
|
e987eac545 | ||
|
|
6b9781fee6 | ||
|
|
181ceb38cc | ||
|
|
595ce0ea19 | ||
|
|
b624330155 | ||
|
|
380c316869 | ||
|
|
31dacc2d21 | ||
|
|
b557a82009 | ||
|
|
e4af1c4244 | ||
|
|
7c26ac5578 | ||
|
|
2948d50b0d | ||
|
|
48fefddcb2 | ||
|
|
f4d8af2f0d | ||
|
|
afa3108623 | ||
|
|
6fcfddf19a | ||
|
|
6d2f442cbd | ||
|
|
e8260e7191 | ||
|
|
48a4367a2c | ||
|
|
edd3540f34 | ||
|
|
111c32c5ed | ||
|
|
af22ca3ae0 | ||
|
|
5e2caa326c | ||
|
|
50f9f60341 | ||
|
|
65f61b143a | ||
|
|
10f4892b7e | ||
|
|
f71d518f75 | ||
|
|
c5b11fe484 | ||
|
|
068fd04f15 | ||
|
|
a461750b55 | ||
|
|
291df6a0e4 | ||
|
|
8afeb4ea61 | ||
|
|
b30f246900 | ||
|
|
7fd042b197 | ||
|
|
b6b3e364f2 | ||
|
|
70e5f18971 | ||
|
|
1fb35593d5 | ||
|
|
b1b9c32644 | ||
|
|
8eeed7d42c | ||
|
|
584493d945 | ||
|
|
da8e551e77 | ||
|
|
a717930d5a | ||
|
|
abc000f614 | ||
|
|
cd51f1def3 | ||
|
|
f5573cf0ab | ||
|
|
1d036a4897 | ||
|
|
f9eced6244 | ||
|
|
90a7253c66 | ||
|
|
31e065f83a | ||
|
|
571f443339 | ||
|
|
4a4157919c | ||
|
|
e73aa0e81b | ||
|
|
2343246315 | ||
|
|
e5f41ce175 | ||
|
|
8184f2eaa9 | ||
|
|
e0bb465945 | ||
|
|
55749a63eb | ||
|
|
aa1b8db3ea | ||
|
|
023713fd67 | ||
|
|
35093c3e37 | ||
|
|
4e5dac3e25 | ||
|
|
c52e84ac41 | ||
|
|
7f8488771d | ||
|
|
57ff271f4b | ||
|
|
43703755f8 | ||
|
|
17b6cc00ab | ||
|
|
a03563b366 | ||
|
|
ff9da17498 | ||
|
|
722bc94270 | ||
|
|
d51a5db5b1 | ||
|
|
04541ae2ab | ||
|
|
c58a67815b | ||
|
|
085f964cd9 | ||
|
|
a8b6e448eb | ||
|
|
78ab8381d9 | ||
|
|
49a5d82086 | ||
|
|
4ed129ccac | ||
|
|
ed09dca17e | ||
|
|
e64fbb2f0e | ||
|
|
e37f8a6521 | ||
|
|
b54bcc0e20 | ||
|
|
db37d51bb1 | ||
|
|
197b9fc560 | ||
|
|
fd30b00205 | ||
|
|
f182379d24 | ||
|
|
32ba08980d | ||
|
|
1e1f08abb9 | ||
|
|
cbe20c0eed | ||
|
|
ec288ffa62 | ||
|
|
7e18c02c7e | ||
|
|
4a505cc239 | ||
|
|
35c81106c6 | ||
|
|
1094222d3f | ||
|
|
065d0db4c9 | ||
|
|
bc51537080 | ||
|
|
b7dfcb282b | ||
|
|
78a9411766 | ||
|
|
4724f67596 | ||
|
|
e0851bb86f | ||
|
|
08e68d9563 | ||
|
|
0b6dccae51 | ||
|
|
60adfd5046 | ||
|
|
3e782d355d | ||
|
|
22a7324b69 | ||
|
|
f3b4c50909 | ||
|
|
a45f27e6e9 | ||
|
|
2f84bf0cca | ||
|
|
3e2c3e5075 | ||
|
|
154259d0a6 | ||
|
|
7d2d05ff59 | ||
|
|
f7c587c9a8 | ||
|
|
9162b30b18 | ||
|
|
14cfe37c8b | ||
|
|
a27a0ab49d | ||
|
|
0742fe07ec | ||
|
|
65a92470d3 | ||
|
|
10dc1a2da2 | ||
|
|
aad2128c32 | ||
|
|
2640678cac | ||
|
|
8b90e2d53d | ||
|
|
f87175dc7f | ||
|
|
b30444c0d0 | ||
|
|
c1da0caf15 | ||
|
|
c4a8fc5b71 | ||
|
|
8eb46b5a4c | ||
|
|
8be16d1039 | ||
|
|
76e6208d1b | ||
|
|
bc09080ba5 | ||
|
|
a6eb257a3a | ||
|
|
e62450d255 | ||
|
|
1aa922f700 | ||
|
|
4c9d2f99b1 | ||
|
|
f6e899b570 | ||
|
|
695c39fba2 | ||
|
|
e5616cff98 | ||
|
|
76d5994c1e | ||
|
|
cbb40832a1 | ||
|
|
e4bdcde1ca | ||
|
|
863e119ff4 | ||
|
|
2ccf6dc872 | ||
|
|
24ebf1b4f1 | ||
|
|
ed2832434c | ||
|
|
5e160fca8f | ||
|
|
a0ef82e221 | ||
|
|
3e7ac3d66c | ||
|
|
730e6fa737 | ||
|
|
cdfcd9fddd | ||
|
|
b6930c10b9 | ||
|
|
852734580d | ||
|
|
d1dc6a9c1d | ||
|
|
4fa6d3ed3f | ||
|
|
92e190ad6c | ||
|
|
da4fcffef4 | ||
|
|
1a5731dd8e | ||
|
|
e764c5cd4e | ||
|
|
e23b247947 | ||
|
|
3d7792436f | ||
|
|
d8187fbea4 | ||
|
|
02259ad0a5 | ||
|
|
220a68df9a | ||
|
|
2ced24f69e | ||
|
|
ec91d0dc74 | ||
|
|
46874f4673 | ||
|
|
9eac47dc6c | ||
|
|
9e3fd5c2e0 | ||
|
|
ae4be6e2b1 | ||
|
|
434df49a7d | ||
|
|
c939c0fcd5 | ||
|
|
952c39f324 | ||
|
|
0fea7e2a70 | ||
|
|
c1baab68d0 | ||
|
|
ccef18f7a9 | ||
|
|
8cb056bde3 | ||
|
|
6ecaaee9e0 | ||
|
|
c5f916bda0 | ||
|
|
52a9a4649c | ||
|
|
d2219b4dbd | ||
|
|
155f603245 | ||
|
|
cb7630a6ab | ||
|
|
284fba1ce3 | ||
|
|
aa4bd6c88c | ||
|
|
623993930b | ||
|
|
dbf2c854c6 | ||
|
|
25351bc05c | ||
|
|
27cc5f499c | ||
|
|
b7c2f39a17 | ||
|
|
3541c1ccf8 | ||
|
|
7a05738d11 | ||
|
|
686220ae0c | ||
|
|
cf380d36b9 | ||
|
|
50bc0193ac | ||
|
|
2162a72831 | ||
|
|
313666f85b | ||
|
|
e9d79263b4 | ||
|
|
4ede6d65fd | ||
|
|
14d2eee371 | ||
|
|
717f370be0 | ||
|
|
d05e4b9727 | ||
|
|
697c53b4d8 | ||
|
|
d9b58ec3ce | ||
|
|
6c8b37d7ca | ||
|
|
39f43e766d | ||
|
|
5379a13944 | ||
|
|
cd0c1607ef | ||
|
|
26a4f71385 | ||
|
|
06b3e6ad71 | ||
|
|
79d22a8d77 | ||
|
|
9914212600 | ||
|
|
765f55e67b | ||
|
|
2d922cc035 | ||
|
|
42e0625ab3 | ||
|
|
c72e894fc7 | ||
|
|
5bc2342d47 | ||
|
|
ea2b0b5e59 | ||
|
|
d70cc0221a | ||
|
|
b12587b44e | ||
|
|
c4708bdc35 | ||
|
|
1fa2c0bf50 | ||
|
|
b4c70d357a | ||
|
|
f18262ee96 | ||
|
|
c1f1761482 | ||
|
|
067c3eea16 | ||
|
|
6957cc7001 | ||
|
|
7dea23eea8 | ||
|
|
319ec1f774 | ||
|
|
2079532e83 | ||
|
|
de1d646fe9 | ||
|
|
4bc3ab6285 | ||
|
|
1adc9cbb49 | ||
|
|
7cdf5eefc9 | ||
|
|
c7ee72647d | ||
|
|
5434af348e | ||
|
|
169cea0f01 | ||
|
|
a8f3ec8184 | ||
|
|
7796b2a12b | ||
|
|
d9cffd58ba | ||
|
|
e566386240 | ||
|
|
45af1e172f | ||
|
|
768b2e52a6 | ||
|
|
7abd2009b0 | ||
|
|
46f075e891 | ||
|
|
832c381ac4 | ||
|
|
e021282264 | ||
|
|
2a60d385c6 | ||
|
|
4d37e35675 | ||
|
|
df3868a280 | ||
|
|
0799bb8cf1 | ||
|
|
69048dede4 | ||
|
|
76df6d1f43 | ||
|
|
2d03b21f2b | ||
|
|
62cbd44933 | ||
|
|
44c8f6d8b0 | ||
|
|
f3fc1dd59c | ||
|
|
708931e48b | ||
|
|
81800d2883 | ||
|
|
d0411d7ddf | ||
|
|
70e232cab3 | ||
|
|
f90396bda4 | ||
|
|
ae8808b86e | ||
|
|
8d5b827432 | ||
|
|
cb672697e7 | ||
|
|
0bae9fc29b | ||
|
|
49c8b68700 | ||
|
|
1e2fcd17e0 | ||
|
|
468b9d2655 | ||
|
|
a3305ff791 | ||
|
|
814b0d5873 | ||
|
|
863f3e82ac | ||
|
|
529c756458 | ||
|
|
67b98dbdaa | ||
|
|
a16981cbe5 | ||
|
|
777bf338fa | ||
|
|
3ba8d9ebff | ||
|
|
db5384e19c | ||
|
|
fd3984287b | ||
|
|
31dbea4e0b | ||
|
|
0992e784f1 | ||
|
|
c59cc1fbb7 | ||
|
|
903edc79f7 | ||
|
|
4c94c69f02 | ||
|
|
4c57c214bd | ||
|
|
1cbeea3016 | ||
|
|
0d18738192 | ||
|
|
1e7c7db29b | ||
|
|
7c098a2665 | ||
|
|
3ab539be1e | ||
|
|
b46d5e4efc | ||
|
|
db06e11a7c | ||
|
|
757ed33e4f | ||
|
|
8eb5dfce85 | ||
|
|
f34db72a97 | ||
|
|
3dfdc8ee6f | ||
|
|
5a846296ca | ||
|
|
0bea015dcd | ||
|
|
fe0b401edd | ||
|
|
69f8e82c3f | ||
|
|
79d3d43a85 | ||
|
|
e8a7f596bc | ||
|
|
a096c00b68 | ||
|
|
e284ef8906 | ||
|
|
154a8750dc | ||
|
|
0de4ca4a19 | ||
|
|
23c9c9f72e | ||
|
|
96ff10c692 | ||
|
|
30bc7ea132 | ||
|
|
d9ea1591b0 | ||
|
|
0cc1bb5ad8 | ||
|
|
509bbd7605 | ||
|
|
4632afe1ab | ||
|
|
6680698ba6 | ||
|
|
2b06b12ca2 | ||
|
|
9b53916e06 | ||
|
|
f3ce1dd7a3 | ||
|
|
91b0426d68 | ||
|
|
63a5b95939 | ||
|
|
480a3fe171 | ||
|
|
b160eac49f | ||
|
|
37ba82b8b7 | ||
|
|
2d604145f1 | ||
|
|
d60a6df313 | ||
|
|
236d9e3028 | ||
|
|
175327e711 | ||
|
|
6342f99504 | ||
|
|
6164ae9f60 | ||
|
|
d2a5b70b2e | ||
|
|
b2be5dcb59 | ||
|
|
b67c03cc75 | ||
|
|
d613701780 | ||
|
|
4b62562fce | ||
|
|
6ffaca45da | ||
|
|
56fe0b32e6 | ||
|
|
f7c0d6af73 | ||
|
|
b625e2c47a | ||
|
|
97300d59a9 | ||
|
|
f45840a29f | ||
|
|
bfff6ed406 | ||
|
|
ad6f5fd6af | ||
|
|
7bdf349b9d | ||
|
|
9412fbcefb | ||
|
|
c2af0097c5 | ||
|
|
9e5b69ee54 | ||
|
|
f6e0d1d368 | ||
|
|
5bb18bee17 | ||
|
|
d0fb219939 | ||
|
|
e2b04726cf | ||
|
|
b293cdc9ba | ||
|
|
3f93b3a39d | ||
|
|
a4de6e45db | ||
|
|
213a89ab72 | ||
|
|
8dcca62d0c | ||
|
|
4ed0bcbda8 | ||
|
|
b2587e676d | ||
|
|
90af9b2f01 | ||
|
|
d915a0b945 | ||
|
|
ac9c5eaae9 | ||
|
|
0891da303c | ||
|
|
55e9b51faa | ||
|
|
55dc0ade47 | ||
|
|
2cf7083718 | ||
|
|
15df532d68 | ||
|
|
884d2302a9 | ||
|
|
bacdfd6018 | ||
|
|
dc7a3bbbd3 | ||
|
|
ff0d791783 | ||
|
|
a3d8a0dde0 | ||
|
|
a8c908d113 | ||
|
|
01849d5305 | ||
|
|
23968d3e2b | ||
|
|
7246a64ae5 | ||
|
|
729e050adb | ||
|
|
003452fbbb | ||
|
|
419b6bd0a3 | ||
|
|
668c3d9a08 | ||
|
|
9a6f878051 | ||
|
|
50fc750154 | ||
|
|
9fe8235eda | ||
|
|
f7b9c48998 | ||
|
|
17bf27c018 | ||
|
|
80ca5ea5fd | ||
|
|
3afa9ca403 | ||
|
|
842190e15e | ||
|
|
717775d9ab | ||
|
|
a19bb91041 | ||
|
|
a545982a28 | ||
|
|
2109df04ca | ||
|
|
f485cf8ebc | ||
|
|
bb48110f95 | ||
|
|
718adda749 | ||
|
|
a170c7ccb1 | ||
|
|
fec3fe3b6b | ||
|
|
00f19c9777 | ||
|
|
93aae28593 | ||
|
|
8be2b907b3 | ||
|
|
fcca07765b | ||
|
|
559e4e75eb | ||
|
|
8ae84614d5 | ||
|
|
18a7e8b22c | ||
|
|
01120f6120 | ||
|
|
07be6bb5ae | ||
|
|
39b4905ef1 | ||
|
|
6c49a5aa9d | ||
|
|
aaeff2ea0f | ||
|
|
cd48e78667 | ||
|
|
f2ab4e840e | ||
|
|
9a476f8283 | ||
|
|
8e24ad724c | ||
|
|
c70aba2ca5 | ||
|
|
c6a20961b8 | ||
|
|
4741354883 | ||
|
|
a3051f5d58 | ||
|
|
730207e75b | ||
|
|
27e067889d | ||
|
|
22c9433c1c | ||
|
|
c6b558cb3d | ||
|
|
a6d5598c08 | ||
|
|
13ee2abeef | ||
|
|
ca9c841477 | ||
|
|
0dbae3c46c | ||
|
|
045bcbc7da | ||
|
|
9f98e28b08 | ||
|
|
59dfbae9b4 | ||
|
|
3f0250957b | ||
|
|
73595d93f3 | ||
|
|
19b8755c89 | ||
|
|
14aad730de | ||
|
|
6c7eec5778 | ||
|
|
2c5ce5763a | ||
|
|
b568e1387a | ||
|
|
85bd46e457 | ||
|
|
bd4a77992e | ||
|
|
a8750ce8ad | ||
|
|
4e8887c80b | ||
|
|
c38a0cdec9 | ||
|
|
6f961edcb1 | ||
|
|
bdd9f30404 | ||
|
|
f94d5faaf2 | ||
|
|
c1ffd93f28 | ||
|
|
05bf7af859 | ||
|
|
eae359a3b8 | ||
|
|
2156906341 | ||
|
|
e7bd669362 | ||
|
|
17ac5b5e06 | ||
|
|
671cc753b5 | ||
|
|
fd81b47413 | ||
|
|
710b07a857 | ||
|
|
5b93d2642b | ||
|
|
38d792fd97 | ||
|
|
fed266f5ac | ||
|
|
a547d10ab9 | ||
|
|
4cc6043737 | ||
|
|
0a42313b6f | ||
|
|
0b53f541d1 | ||
|
|
ddd17b18d7 | ||
|
|
915f4cc618 | ||
|
|
d4d9b3e461 | ||
|
|
49f5221170 | ||
|
|
96459090a6 | ||
|
|
ccc8b38b77 | ||
|
|
c6d1c8063b | ||
|
|
0ffb6d6362 | ||
|
|
252aaa500e | ||
|
|
d456908e37 | ||
|
|
cd13bfb429 | ||
|
|
ff87bc5889 | ||
|
|
42cd80c172 | ||
|
|
123cd3a092 | ||
|
|
cbc3c4e6eb | ||
|
|
b50e39e5cb | ||
|
|
bbe5ef451a | ||
|
|
c359c0e747 | ||
|
|
99ecb0b60f | ||
|
|
cfc7e45020 | ||
|
|
0307d064ad | ||
|
|
89cd824c70 | ||
|
|
1066e8a5e9 | ||
|
|
d2c31df106 | ||
|
|
a56ffee8f7 | ||
|
|
7c798126e3 | ||
|
|
a755131488 | ||
|
|
648ff65a76 | ||
|
|
854d1c0a1a | ||
|
|
4f561aa9e9 | ||
|
|
8c1c4df10d | ||
|
|
a9e963e84b | ||
|
|
4a509610fe | ||
|
|
7de5066c87 | ||
|
|
24b1be1dd2 | ||
|
|
ee00213961 | ||
|
|
b51b32c758 | ||
|
|
d16e669538 | ||
|
|
50d258fae9 | ||
|
|
494cceff73 | ||
|
|
9885e61962 | ||
|
|
4b88a290c4 | ||
|
|
ee8335e5f1 | ||
|
|
fcde7fdb80 | ||
|
|
3d42da3e97 | ||
|
|
c81a37b740 | ||
|
|
4fa005ade0 | ||
|
|
bf656e892f | ||
|
|
abf074eaf4 | ||
|
|
47657b51ab | ||
|
|
76f8ffeb90 | ||
|
|
e68ae91b59 | ||
|
|
9222c21b4a | ||
|
|
c837d9c91c | ||
|
|
cdf7bef150 | ||
|
|
eb52da9702 | ||
|
|
8a1f2a151d | ||
|
|
1b4ced3e55 | ||
|
|
29cd068dbd | ||
|
|
6681614f1a | ||
|
|
1030db87d4 | ||
|
|
356ab30e89 | ||
|
|
0f09b8df77 | ||
|
|
23c495b939 | ||
|
|
2ac0420903 | ||
|
|
aae070f826 | ||
|
|
6ad825d1e0 | ||
|
|
7910506b3c | ||
|
|
5393d724c5 | ||
|
|
c8b1e4c4e6 | ||
|
|
d373cb602d | ||
|
|
58f195fc04 |
@@ -86,5 +86,5 @@ SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Cpp11
|
||||
TabWidth: 4
|
||||
UseTab: ForContinuationAndIndentation
|
||||
UseTab: AlignWithSpaces
|
||||
...
|
||||
|
||||
54
.github/CONTRIBUTING.md
vendored
54
.github/CONTRIBUTING.md
vendored
@@ -1,54 +0,0 @@
|
||||
# So you want to contribute to PCSX2? Great
|
||||
|
||||
As a first step, please review these links as they'll help you understand how the development of PCSX2 works.
|
||||
|
||||
* [Just Starting Out](#just-starting-out)
|
||||
* [Issue Reporting](#issue-reporting)
|
||||
* [Pull Request Guidelines](#pull-request-guidelines)
|
||||
* [General Documentation And Coding Strategies](#general-documentation-and-coding-strategies)
|
||||
* [Tasks](#tasks)
|
||||
|
||||
## Just Starting Out
|
||||
|
||||
* If you're unfamilar with git, check out this [brief introduction to Git](https://github.com/PCSX2/pcsx2/wiki/07-Git-survival-guide)
|
||||
* [How to build PCSX2 for Windows](https://github.com/PCSX2/pcsx2/wiki/12-Building-on-Windows)
|
||||
* [How to build PCSX2 for Linux](https://github.com/PCSX2/pcsx2/wiki/10-Building-on-Linux)
|
||||
|
||||
## Issue Reporting
|
||||
|
||||
* [How to write a useful issue](https://github.com/PCSX2/pcsx2/wiki/How-to-create-useful-and-valid-issues)
|
||||
|
||||
## Pull Request Guidelines
|
||||
|
||||
The following is a list of *general* style recommendations that will make reviewing and merging easier:
|
||||
|
||||
* Commit Messages
|
||||
* Please try to prefix your commit message, indicating what area of the project was modified.
|
||||
* For example `gs: message...`.
|
||||
* Looking at the project's commit history will help with keeping prefixes consistent overtime, *there is no strictly enforced list*.
|
||||
|
||||
* Try to keep messages brief and informative
|
||||
|
||||
* Remove unnecessary commits and squash commits together when appropriate.
|
||||
* If you are not familiar with rebasing with git, check out the following resources:
|
||||
* CLI - https://thoughtbot.com/blog/git-interactive-rebase-squash-amend-rewriting-history
|
||||
* GUI (SourceTree) - https://www.atlassian.com/blog/sourcetree/interactive-rebase-sourcetree
|
||||
|
||||
* Code Styling and Formatting
|
||||
* [Consult the style guide](https://github.com/tadanokojin/pcsx2/blob/coding-guide/pcsx2/Docs/Coding_Guidelines.md)
|
||||
|
||||
* Run `clang-format` using the configuration file in the root of the repository
|
||||
* Visual Studio Setup - https://devblogs.microsoft.com/cppblog/clangformat-support-in-visual-studio-2017-15-7-preview-1/
|
||||
* IMPORTANT - if you are running `clang-format` on unrelated changes (ie. formatting an entire file), please do so in a separate commit.
|
||||
* If you cannot scope your `clang-format` to just your changes and do not want to format unrelated code. Try your best to stick with the existing formatting already established in the file in question.
|
||||
|
||||
## General Documentation And Coding Strategies
|
||||
|
||||
* [Commenting Etiquette](https://github.com/PCSX2/pcsx2/wiki/06-Commenting-Etiquette)
|
||||
|
||||
* [Coding style](https://github.com/PCSX2/pcsx2/wiki/Code-Formatting-Guidelines)
|
||||
* [More comprehensive style-guide (Currently in Draft)](https://github.com/tadanokojin/pcsx2/blob/coding-guide/pcsx2/Docs/Coding_Guidelines.md)
|
||||
|
||||
## Tasks
|
||||
|
||||
* [Issues](https://github.com/PCSX2/pcsx2/issues)
|
||||
1
.github/FUNDING.yml
vendored
1
.github/FUNDING.yml
vendored
@@ -1,3 +1,4 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: [PCSX2]
|
||||
liberapay: PCSX2
|
||||
|
||||
4
.github/ISSUE_TEMPLATE/app_bug_report.yaml
vendored
4
.github/ISSUE_TEMPLATE/app_bug_report.yaml
vendored
@@ -59,7 +59,7 @@ body:
|
||||
attributes:
|
||||
label: PCSX2 Revision
|
||||
description: "Please ensure you are on the latest version before making an issue"
|
||||
placeholder: "Example: v1.7.1337"
|
||||
placeholder: "Example: v2.5.374"
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
@@ -70,6 +70,8 @@ body:
|
||||
- Windows 11
|
||||
- Windows 10 (64bit)
|
||||
- Linux (64bit) - Specify distro below
|
||||
- macOS 26 (Tahoe)
|
||||
- macOS 15 (Sequoia)
|
||||
- macOS 14 (Sonoma)
|
||||
- macOS 13 (Ventura)
|
||||
- macOS 12 (Monterey)
|
||||
|
||||
14
.github/ISSUE_TEMPLATE/emu_bug_report.yaml
vendored
14
.github/ISSUE_TEMPLATE/emu_bug_report.yaml
vendored
@@ -66,9 +66,9 @@ body:
|
||||
|
||||
Performance issues as a result of not meeting our hardware requirements are not valid.
|
||||
|
||||
Please read our known issues pages for AMD and Intel drivers.
|
||||
- [Intel Drivers](https://github.com/PCSX2/pcsx2/wiki/OpenGL-and-Intel-GPUs-All-you-need-to-know).
|
||||
- [AMD Drivers](https://github.com/PCSX2/pcsx2/wiki/OpenGL-and-AMD-GPUs---All-you-need-to-know).
|
||||
Please read our troubleshooting pages and our issue reporting guide.
|
||||
- [Troubleshooting page](https://pcsx2.net/docs/category/troubleshooting).
|
||||
- [Issue reporting guide](https://pcsx2.net/docs/troubleshooting/identify).
|
||||
|
||||
We are **not** accepting issues related to the **libretro** core. The libretro core is being maintained separately at this time
|
||||
- type: input
|
||||
@@ -76,7 +76,7 @@ body:
|
||||
attributes:
|
||||
label: PCSX2 Revision
|
||||
description: "We only accept bug reports for the latest dev version. Please try upgrading before making an issue."
|
||||
placeholder: "Example: v1.7.1337"
|
||||
placeholder: "Example: v2.5.374"
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
@@ -87,6 +87,8 @@ body:
|
||||
- Windows 11
|
||||
- Windows 10 (64bit)
|
||||
- Linux (64bit) - Specify distro below
|
||||
- macOS 26 (Tahoe)
|
||||
- macOS 15 (Sequoia)
|
||||
- macOS 14 (Sonoma)
|
||||
- macOS 13 (Ventura)
|
||||
- macOS 12 (Monterey)
|
||||
@@ -104,14 +106,14 @@ body:
|
||||
id: cpu
|
||||
attributes:
|
||||
label: CPU
|
||||
placeholder: "Example: i5-7600"
|
||||
placeholder: "Example: Intel i5 12400F"
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: gpu
|
||||
attributes:
|
||||
label: GPU
|
||||
placeholder: "Example: GTX 1070"
|
||||
placeholder: "Example: Nvidia RTX 4060"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
|
||||
3
.github/PULL_REQUEST_TEMPLATE.md
vendored
3
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -6,3 +6,6 @@
|
||||
|
||||
### Suggested Testing Steps
|
||||
<!-- If applicable, including examples you've already tested with / recommendations for how to test further is very helpful! -->
|
||||
|
||||
### Did you use AI to help find, test, or implement this issue or feature?
|
||||
<!-- Answer yes or no. If you answer yes, please provide a brief explanation how. -->
|
||||
|
||||
11
.github/labeler.yml
vendored
11
.github/labeler.yml
vendored
@@ -22,6 +22,10 @@
|
||||
- '3rdparty/**/*'
|
||||
- '**/3rdpartyDeps.props'
|
||||
- '.gitmodules'
|
||||
'requires-win-deps-build':
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- '.github/workflows/scripts/windows/*'
|
||||
'Documentation':
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
@@ -36,6 +40,13 @@
|
||||
- 'pcsx2-qt/**/*'
|
||||
- '3rdparty/Qt/*'
|
||||
- '3rdparty/Qt/**/*'
|
||||
'OSD / ImGui':
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- 'pcsx2/ImGui/*'
|
||||
- 'pcsx2/ImGui/**/*'
|
||||
- '3rdparty/imgui/*'
|
||||
- '3rdparty/imgui/**/*'
|
||||
'GameDB':
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
|
||||
57
.github/workflows/cron_publish_flatpak.yml
vendored
57
.github/workflows/cron_publish_flatpak.yml
vendored
@@ -6,36 +6,45 @@ on:
|
||||
workflow_dispatch: # As well as manually.
|
||||
|
||||
jobs:
|
||||
check:
|
||||
if: github.repository == 'PCSX2/pcsx2'
|
||||
name: "Check if release is needed"
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 180
|
||||
outputs:
|
||||
PCSX2_RELEASE: ${{ steps.getinfo.outputs.PCSX2_RELEASE }}
|
||||
FLATHUB_RELEASE: ${{ steps.getinfo.outputs.FLATHUB_RELEASE }}
|
||||
steps:
|
||||
- name: Get latest tag and Flathub release
|
||||
id: getinfo
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
PCSX2_RELEASE=$(gh api -H 'Accept: application/vnd.github+json' -H 'X-GitHub-Api-Version: 2022-11-28' /repos/PCSX2/pcsx2/releases | jq -r '.[0].tag_name')
|
||||
FLATHUB_RELEASE=$(curl -L -s https://flathub.org/api/v2/appstream/net.pcsx2.PCSX2 | jq -r '.releases | max_by(.version) | .version')
|
||||
echo "Latest PCSX2 release is: '${PCSX2_RELEASE}'"
|
||||
echo "Latest Flathub release is: '${FLATHUB_RELEASE}'"
|
||||
PCSX2_RELEASE=$(echo $PCSX2_RELEASE | sed 's/[^0-9]*//g')
|
||||
FLATHUB_RELEASE=$(echo $FLATHUB_RELEASE | sed 's/[^0-9]*//g')
|
||||
echo "PCSX2_RELEASE=${PCSX2_RELEASE}" >> "$GITHUB_OUTPUT"
|
||||
echo "FLATHUB_RELEASE=${FLATHUB_RELEASE}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
# check is disabled as the flathub api does not give us beta repository information
|
||||
# Alternatively we can "flatpak remote-info or parse the appstream directly for the beta repo"
|
||||
# Maybe in the future if we don't want to publish the same version twice if we get no commits
|
||||
# for 24 hours.
|
||||
|
||||
# check:
|
||||
# if: github.repository == 'PCSX2/pcsx2'
|
||||
# name: "Check if release is needed"
|
||||
# runs-on: ubuntu-latest
|
||||
# timeout-minutes: 180
|
||||
# outputs:
|
||||
# PCSX2_RELEASE: ${{ steps.getinfo.outputs.PCSX2_RELEASE }}
|
||||
# FLATHUB_RELEASE: ${{ steps.getinfo.outputs.FLATHUB_RELEASE }}
|
||||
# steps:
|
||||
# - name: Get latest tag and Flathub release
|
||||
# id: getinfo
|
||||
# env:
|
||||
# GH_TOKEN: ${{ github.token }}
|
||||
# run: |
|
||||
# PCSX2_RELEASE=$(gh api -H 'Accept: application/vnd.github+json' -H 'X-GitHub-Api-Version: 2022-11-28' /repos/PCSX2/pcsx2/releases | jq -r '.[0].tag_name')
|
||||
# FLATHUB_RELEASE=$(curl -L -s https://flathub.org/api/v2/appstream/net.pcsx2.PCSX2 | jq -r '.releases | max_by(.version) | .version')
|
||||
# echo "Latest PCSX2 release is: '${PCSX2_RELEASE}'"
|
||||
# echo "Latest Flathub release is: '${FLATHUB_RELEASE}'"
|
||||
# PCSX2_RELEASE=$(echo $PCSX2_RELEASE | sed 's/[^0-9]*//g')
|
||||
# FLATHUB_RELEASE=$(echo $FLATHUB_RELEASE | sed 's/[^0-9]*//g')
|
||||
# echo "PCSX2_RELEASE=${PCSX2_RELEASE}" >> "$GITHUB_OUTPUT"
|
||||
# echo "FLATHUB_RELEASE=${FLATHUB_RELEASE}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
build:
|
||||
needs: check
|
||||
# needs: check
|
||||
# outputs are automatically compared as strings. This doesn't work in our favour
|
||||
# Use fromJson() to convert them to proper integers...
|
||||
# see: https://github.com/github/docs/pull/25870
|
||||
# and: https://github.com/orgs/community/discussions/57480
|
||||
#if: fromJson(needs.check.outputs.FLATHUB_RELEASE) < fromJson(needs.check.outputs.PCSX2_RELEASE)
|
||||
|
||||
# if: fromJson(needs.check.outputs.FLATHUB_RELEASE) < fromJson(needs.check.outputs.PCSX2_RELEASE)
|
||||
# As the check step is disabled, perform repository check here
|
||||
if: github.repository == 'PCSX2/pcsx2'
|
||||
name: "Build and publish Flatpak"
|
||||
uses: ./.github/workflows/linux_build_flatpak.yml
|
||||
with:
|
||||
|
||||
@@ -11,13 +11,13 @@ jobs:
|
||||
name: "Update Base Translation"
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Update Base Translation
|
||||
run: ./.github/workflows/scripts/common/update_base_translation.sh
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@4320041ed380b20e97d388d56a7fb4f9b8c20e79
|
||||
uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725
|
||||
with:
|
||||
title: "Qt: Update Base Translation"
|
||||
commit-message: "[ci skip] Qt: Update Base Translation."
|
||||
|
||||
@@ -9,7 +9,7 @@ jobs:
|
||||
if: github.repository == 'PCSX2/pcsx2'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Get Latest DB and Prepare DB File
|
||||
run: |
|
||||
@@ -19,7 +19,7 @@ jobs:
|
||||
mv ./game_controller_db.txt ${{github.workspace}}/bin/resources/game_controller_db.txt
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@4320041ed380b20e97d388d56a7fb4f9b8c20e79
|
||||
uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725
|
||||
with:
|
||||
title: "PAD: Update to latest controller database"
|
||||
commit-message: "[ci skip] PAD: Update to latest controller database."
|
||||
|
||||
4
.github/workflows/lint_gamedb.yml
vendored
4
.github/workflows/lint_gamedb.yml
vendored
@@ -18,12 +18,12 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Install Packages
|
||||
run: |
|
||||
npm install -g ajv-cli prettier
|
||||
sudo apt-get -y install yamllint
|
||||
pip install yamllint
|
||||
|
||||
- name: Validate YAML
|
||||
run: |
|
||||
|
||||
27
.github/workflows/linux_build_flatpak.yml
vendored
27
.github/workflows/linux_build_flatpak.yml
vendored
@@ -45,28 +45,25 @@ jobs:
|
||||
name: ${{ inputs.jobName }}
|
||||
runs-on: ${{ inputs.os }}
|
||||
container:
|
||||
image: ghcr.io/flathub-infra/flatpak-github-actions:kde-6.7
|
||||
image: ghcr.io/flathub-infra/flatpak-github-actions:kde-6.9
|
||||
options: --privileged
|
||||
timeout-minutes: 60
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
set-safe-directory: ${{ env.GITHUB_WORKSPACE }}
|
||||
# 10 here, since the odds of having 10 untagged commits in a row should be slim to none
|
||||
# This is required for the tagging logic in generate-metainfo.sh
|
||||
fetch-depth: 10
|
||||
fetch-tags: true
|
||||
|
||||
# Work around container ownership issue
|
||||
- name: Set Safe Directory
|
||||
shell: bash
|
||||
run: git config --global --add safe.directory "*"
|
||||
|
||||
# Hackity hack. When running the workflow on a schedule, we don't have the tag,
|
||||
# it doesn't fetch tags, therefore we don't get a version. So grab them manually.
|
||||
# actions/checkout elides tags, fetch them primarily for releases
|
||||
- name: Fetch tags
|
||||
if: ${{ inputs.fetchTags }}
|
||||
run: git fetch --tags --no-recurse-submodules
|
||||
|
||||
- name: Add stable release identifier file
|
||||
if: ${{ inputs.stableBuild == true || inputs.stableBuild == 'true' }}
|
||||
shell: bash
|
||||
@@ -96,7 +93,7 @@ jobs:
|
||||
|
||||
- name: Build Flatpak (beta)
|
||||
if: ${{ inputs.stableBuild == false || inputs.stableBuild == 'false' }}
|
||||
uses: flathub-infra/flatpak-github-actions/flatpak-builder@23796715b3dfa4c86ddf50cf29c3cc8b3c82dca8
|
||||
uses: flatpak/flatpak-github-actions/flatpak-builder@92ae9851ad316786193b1fd3f40c4b51eb5cb101
|
||||
with:
|
||||
bundle: ${{ steps.artifact-metadata.outputs.artifact-name }}.flatpak
|
||||
upload-artifact: false
|
||||
@@ -112,7 +109,7 @@ jobs:
|
||||
|
||||
- name: Build Flatpak (stable)
|
||||
if: ${{ inputs.stableBuild == true || inputs.stableBuild == 'true' }}
|
||||
uses: flathub-infra/flatpak-github-actions/flatpak-builder@23796715b3dfa4c86ddf50cf29c3cc8b3c82dca8
|
||||
uses: flatpak/flatpak-github-actions/flatpak-builder@92ae9851ad316786193b1fd3f40c4b51eb5cb101
|
||||
with:
|
||||
bundle: ${{ steps.artifact-metadata.outputs.artifact-name }}.flatpak
|
||||
upload-artifact: false
|
||||
@@ -125,14 +122,14 @@ jobs:
|
||||
cache: true
|
||||
restore-cache: true
|
||||
cache-key: ${{ inputs.os }} ${{ inputs.platform }} ${{ inputs.compiler }} flatpak ${{ hashFiles('.github/workflows/scripts/linux/flatpak/**/*.json') }}
|
||||
|
||||
|
||||
#- name: Validate build
|
||||
# run: |
|
||||
# flatpak-builder-lint repo repo
|
||||
|
||||
- name: Push to Flathub (beta)
|
||||
if: ${{ inputs.publish == true && (inputs.stableBuild == false || inputs.stableBuild == 'false') }}
|
||||
uses: flathub-infra/flatpak-github-actions/flat-manager@23796715b3dfa4c86ddf50cf29c3cc8b3c82dca8
|
||||
uses: flatpak/flatpak-github-actions/flat-manager@92ae9851ad316786193b1fd3f40c4b51eb5cb101
|
||||
with:
|
||||
flat-manager-url: https://hub.flathub.org/
|
||||
repository: beta
|
||||
@@ -141,7 +138,7 @@ jobs:
|
||||
|
||||
- name: Push to Flathub (stable)
|
||||
if: ${{ inputs.publish == true && (inputs.stableBuild == true || inputs.stableBuild == 'true') }}
|
||||
uses: flathub-infra/flatpak-github-actions/flat-manager@23796715b3dfa4c86ddf50cf29c3cc8b3c82dca8
|
||||
uses: flatpak/flatpak-github-actions/flat-manager@92ae9851ad316786193b1fd3f40c4b51eb5cb101
|
||||
with:
|
||||
flat-manager-url: https://hub.flathub.org/
|
||||
repository: stable
|
||||
@@ -156,7 +153,7 @@ jobs:
|
||||
mv "./${{ steps.artifact-metadata.outputs.artifact-name }}.flatpak" "$GITHUB_WORKSPACE"/ci-artifacts/
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: ${{ steps.artifact-metadata.outputs.artifact-name }}
|
||||
path: ci-artifacts
|
||||
|
||||
23
.github/workflows/linux_build_qt.yml
vendored
23
.github/workflows/linux_build_qt.yml
vendored
@@ -55,11 +55,11 @@ jobs:
|
||||
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
||||
CCACHE_COMPRESS: true
|
||||
CCACHE_COMPRESSLEVEL: 9
|
||||
CCACHE_MAXSIZE: 500M
|
||||
CCACHE_MAXSIZE: 100M
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -92,7 +92,7 @@ jobs:
|
||||
run: echo "timestamp=$(date -u "+%Y-%m-%d-%H;%M;%S")" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: ccache cache files
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: .ccache
|
||||
key: ${{ inputs.os }} ${{ inputs.platform }} ${{ inputs.compiler }} ${{ inputs.detail }} ccache ${{ steps.ccache_cache_timestamp.outputs.timestamp }}
|
||||
@@ -104,24 +104,24 @@ jobs:
|
||||
sudo tools/retry.sh apt-add-repository -n 'deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-17 main'
|
||||
sudo tools/retry.sh apt-get update
|
||||
sudo tools/retry.sh apt-get -y install \
|
||||
build-essential ccache clang-17 cmake curl extra-cmake-modules git libasound2-dev libaio-dev libavcodec-dev libavformat-dev libavutil-dev \
|
||||
build-essential ccache clang-17 cmake curl extra-cmake-modules git libasound2-dev libaio-dev \
|
||||
libcurl4-openssl-dev libdbus-1-dev libdecor-0-dev libegl-dev libevdev-dev libfontconfig-dev libfreetype-dev libfuse2 libgtk-3-dev libgudev-1.0-dev \
|
||||
libharfbuzz-dev libinput-dev libopengl-dev libpcap-dev libpipewire-0.3-dev libpulse-dev libssl-dev libswresample-dev libswscale-dev libudev-dev \
|
||||
libwayland-dev libx11-dev libx11-xcb-dev libxcb1-dev libxcb-composite0-dev libxcb-cursor-dev libxcb-damage0-dev libxcb-glx0-dev libxcb-icccm4-dev \
|
||||
libharfbuzz-dev libinput-dev libopengl-dev libopus-dev libpcap-dev libpipewire-0.3-dev libpulse-dev libssl-dev libudev-dev libva-dev libvpl2 libvpl-dev \
|
||||
libwayland-dev libx11-dev libx11-xcb-dev libx264-dev libxcb1-dev libxcb-composite0-dev libxcb-cursor-dev libxcb-damage0-dev libxcb-glx0-dev libxcb-icccm4-dev \
|
||||
libxcb-image0-dev libxcb-keysyms1-dev libxcb-present-dev libxcb-randr0-dev libxcb-render0-dev libxcb-render-util0-dev libxcb-shape0-dev \
|
||||
libxcb-shm0-dev libxcb-sync-dev libxcb-util-dev libxcb-xfixes0-dev libxcb-xinput-dev libxcb-xkb-dev libxext-dev libxkbcommon-x11-dev libxrandr-dev \
|
||||
lld-17 llvm-17 ninja-build patchelf pkg-config zlib1g-dev
|
||||
lld-17 llvm-17 nasm ninja-build patchelf pkg-config zlib1g-dev
|
||||
|
||||
- name: Cache Dependencies
|
||||
id: cache-deps
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: ~/deps
|
||||
key: ${{ inputs.os }} ${{ inputs.platform }} deps ${{ hashFiles('.github/workflows/scripts/linux/build-dependencies-qt.sh', '.github/workflows/scripts/common/*.patch') }}
|
||||
|
||||
- name: Build Dependencies
|
||||
if: steps.cache-deps.outputs.cache-hit != 'true'
|
||||
run: .github/workflows/scripts/linux/build-dependencies-qt.sh "$HOME/deps"
|
||||
run: BUILD_FFMPEG=1 .github/workflows/scripts/linux/build-dependencies-qt.sh "$HOME/deps"
|
||||
|
||||
- name: Download patches
|
||||
run: |
|
||||
@@ -140,9 +140,12 @@ jobs:
|
||||
-DCMAKE_CXX_COMPILER=clang++-17 \
|
||||
-DCMAKE_EXE_LINKER_FLAGS_INIT="-fuse-ld=lld" \
|
||||
-DCMAKE_MODULE_LINKER_FLAGS_INIT="-fuse-ld=lld" \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DENABLE_SETCAP=OFF \
|
||||
-DDISABLE_ADVANCE_SIMD=TRUE \
|
||||
-DUSE_LINKED_FFMPEG=ON \
|
||||
-DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON \
|
||||
$ADDITIONAL_CMAKE_ARGS
|
||||
|
||||
- name: Build PCSX2
|
||||
@@ -171,7 +174,7 @@ jobs:
|
||||
|
||||
- name: Upload artifact
|
||||
if: inputs.buildAppImage == true
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: ${{ steps.artifact-metadata.outputs.artifact-name }}
|
||||
path: ci-artifacts
|
||||
|
||||
21
.github/workflows/macos_build.yml
vendored
21
.github/workflows/macos_build.yml
vendored
@@ -12,7 +12,7 @@ on:
|
||||
os:
|
||||
required: false
|
||||
type: string
|
||||
default: macos-14
|
||||
default: macos-26
|
||||
patchesUrl:
|
||||
required: false
|
||||
type: string
|
||||
@@ -42,13 +42,13 @@ jobs:
|
||||
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
||||
CCACHE_COMPRESS: true
|
||||
CCACHE_COMPRESSLEVEL: 9
|
||||
CCACHE_MAXSIZE: 500M
|
||||
CCACHE_MAXSIZE: 100M
|
||||
# Only way to use a secret in an if statement
|
||||
SIGN_KEY: ${{ secrets.APPLE_SIGN_P12_B64 }}
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
# actions/checkout elides tags, fetch them primarily for releases
|
||||
- name: Fetch Tags
|
||||
@@ -62,8 +62,11 @@ jobs:
|
||||
echo "#define DEFAULT_UPDATER_CHANNEL \"stable\"" > ./pcsx2-qt/DefaultUpdaterChannel.h
|
||||
cat ./pcsx2-qt/DefaultUpdaterChannel.h
|
||||
|
||||
- name: Use Xcode 15.2
|
||||
run: sudo xcode-select -s /Applications/Xcode_15.2.app
|
||||
- name: Use Xcode 26.0.1
|
||||
run: sudo xcode-select -s /Applications/Xcode_26.0.1.app
|
||||
|
||||
- name: Install Metal Toolchain
|
||||
run: xcodebuild -downloadComponent MetalToolchain
|
||||
|
||||
- name: Prepare Artifact Metadata
|
||||
id: artifact-metadata
|
||||
@@ -88,10 +91,10 @@ jobs:
|
||||
|
||||
- name: Cache Dependencies
|
||||
id: cache-deps
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: ~/deps
|
||||
key: ${{ inputs.os }} deps ${{ hashFiles('.github/workflows/scripts/macos/build-dependencies.sh', '.github/workflows/scripts/common/*.patch') }}
|
||||
key: ${{ inputs.os }} deps ${{ hashFiles('.github/workflows/scripts/macos/*', '.github/workflows/scripts/common/*.patch') }}
|
||||
|
||||
- name: Build Dependencies
|
||||
if: steps.cache-deps.outputs.cache-hit != 'true'
|
||||
@@ -109,7 +112,7 @@ jobs:
|
||||
run: echo "timestamp=$(date -u "+%Y-%m-%d-%H;%M;%S")" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Cache ccache cache
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: .ccache
|
||||
key: ${{ inputs.os }} ccache ${{ steps.ccache_cache_timestamp.outputs.timestamp }}
|
||||
@@ -194,7 +197,7 @@ jobs:
|
||||
cp "${{ steps.artifact-metadata.outputs.artifact-name }}.tar.xz" ci-artifacts/macOS.tar.xz
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: ${{ steps.artifact-metadata.outputs.artifact-name }}
|
||||
path: "*.tar.xz"
|
||||
|
||||
12
.github/workflows/release_cut_new.yml
vendored
12
.github/workflows/release_cut_new.yml
vendored
@@ -35,7 +35,7 @@ jobs:
|
||||
outputs:
|
||||
new_tag: ${{ steps.tag_version.outputs.new_tag }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
# Docs - https://github.com/mathieudutour/github-tag-action
|
||||
- name: Bump Version and Push Tag
|
||||
@@ -68,7 +68,7 @@ jobs:
|
||||
mv ./release-notes.md ${GITHUB_WORKSPACE}/release-notes.md
|
||||
|
||||
- name: Create a GitHub Release (Manual)
|
||||
uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda
|
||||
uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b
|
||||
if: steps.tag_version.outputs.new_tag && github.event_name == 'workflow_dispatch'
|
||||
with:
|
||||
body_path: ./release-notes.md
|
||||
@@ -77,7 +77,7 @@ jobs:
|
||||
tag_name: ${{ steps.tag_version.outputs.new_tag }}
|
||||
|
||||
- name: Create a GitHub Release (Push)
|
||||
uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda
|
||||
uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b
|
||||
if: steps.tag_version.outputs.new_tag && github.event_name != 'workflow_dispatch'
|
||||
with:
|
||||
body_path: ./release-notes.md
|
||||
@@ -163,12 +163,12 @@ jobs:
|
||||
name: "Upload Artifacts"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Prepare Artifact Folder
|
||||
run: mkdir ./ci-artifacts/
|
||||
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v7
|
||||
name: Download all Artifacts
|
||||
with:
|
||||
path: ./ci-artifacts/
|
||||
@@ -203,7 +203,7 @@ jobs:
|
||||
echo "TAG_VAL=${TAG_VAL}"
|
||||
gh release edit ${TAG_VAL} --draft=false --repo PCSX2/pcsx2
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 22
|
||||
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
diff --git a/src/core/indicators/ClassicDropIndicatorOverlay.h b/src/core/indicators/ClassicDropIndicatorOverlay.h
|
||||
index 2dfb9718a..9b01f002e 100644
|
||||
--- a/src/core/indicators/ClassicDropIndicatorOverlay.h
|
||||
+++ b/src/core/indicators/ClassicDropIndicatorOverlay.h
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
-#include "core/DropIndicatorOverlay.h"
|
||||
+#include <kddockwidgets/core/DropIndicatorOverlay.h>
|
||||
|
||||
namespace KDDockWidgets {
|
||||
|
||||
60
.github/workflows/scripts/common/qtapng-cmake.patch
vendored
Normal file
60
.github/workflows/scripts/common/qtapng-cmake.patch
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index bace076..bfb1c66 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -21,6 +21,10 @@ endif ()
|
||||
|
||||
find_package(Qt${APNG_QT_VERSION} REQUIRED COMPONENTS Core Gui)
|
||||
|
||||
+set(CMAKE_FIND_FRAMEWORK NEVER)
|
||||
+find_package(PNG 1.6.40 REQUIRED)
|
||||
+find_package(ZLIB REQUIRED)
|
||||
+
|
||||
add_subdirectory(src)
|
||||
|
||||
if(APNG_TESTS)
|
||||
diff --git a/cmake/FindZLib.cmake b/cmake/FindZLib.cmake
|
||||
deleted file mode 100644
|
||||
index f8e9220..0000000
|
||||
--- a/cmake/FindZLib.cmake
|
||||
+++ /dev/null
|
||||
@@ -1 +0,0 @@
|
||||
-add_library(ZLIB::ZLIB ALIAS zlibstatic) # use our zlib
|
||||
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
|
||||
index 697df95..0e89371 100644
|
||||
--- a/src/CMakeLists.txt
|
||||
+++ b/src/CMakeLists.txt
|
||||
@@ -1,2 +1 @@
|
||||
-add_subdirectory(3rdparty EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(plugins)
|
||||
diff --git a/src/plugins/imageformats/apng/CMakeLists.txt b/src/plugins/imageformats/apng/CMakeLists.txt
|
||||
index e1b3fd9..72164fb 100644
|
||||
--- a/src/plugins/imageformats/apng/CMakeLists.txt
|
||||
+++ b/src/plugins/imageformats/apng/CMakeLists.txt
|
||||
@@ -14,13 +14,10 @@ target_sources(ApngImagePlugin PRIVATE ${APNG_SOURCES})
|
||||
target_link_libraries(ApngImagePlugin PRIVATE
|
||||
Qt${APNG_QT_VERSION}::Core
|
||||
Qt${APNG_QT_VERSION}::Gui
|
||||
- png_static
|
||||
- zlibstatic
|
||||
+ PNG::PNG
|
||||
+ ZLIB::ZLIB
|
||||
)
|
||||
|
||||
-get_target_property(_png_include png_static INCLUDE_DIRECTORIES)
|
||||
-target_include_directories(ApngImagePlugin PRIVATE ${_png_include})
|
||||
-
|
||||
target_compile_definitions(ApngImagePlugin PRIVATE
|
||||
QT_DEPRECATED_WARNINGS
|
||||
QT_ASCII_CAST_WARNINGS
|
||||
@@ -31,3 +28,10 @@ set_target_properties(ApngImagePlugin PROPERTIES
|
||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/plugins/imageformats"
|
||||
LIBRARY_OUTPUT_NAME qapng
|
||||
)
|
||||
+
|
||||
+install(TARGETS ApngImagePlugin DESTINATION "plugins/imageformats")
|
||||
+
|
||||
+if(WIN32 AND MSVC)
|
||||
+ set_target_properties(ApngImagePlugin PROPERTIES DEBUG_POSTFIX d)
|
||||
+ install(FILES $<TARGET_PDB_FILE:ApngImagePlugin> DESTINATION "plugins/imageformats" OPTIONAL)
|
||||
+endif()
|
||||
@@ -9,6 +9,5 @@ set -e
|
||||
"$SCRIPTDIR/../../../../tools/retry.sh" sudo apt-get -y install qt6-l10n-tools python3
|
||||
|
||||
"$SCRIPTDIR/../../../../tools/generate_fullscreen_ui_translation_strings.py"
|
||||
"$SCRIPTDIR/../../../../pcsx2-qt/Translations/update_glyph_ranges.py"
|
||||
"$SCRIPTDIR/../../../../tools/generate_update_fa_glyph_ranges.py"
|
||||
PATH=/usr/lib/qt6/bin:$PATH "$SCRIPTDIR/../../../../pcsx2-qt/Translations/update_base_translation.sh"
|
||||
|
||||
79
.github/workflows/scripts/linux/appimage-qt.sh
vendored
79
.github/workflows/scripts/linux/appimage-qt.sh
vendored
@@ -43,22 +43,8 @@ STRIP=strip
|
||||
|
||||
declare -a MANUAL_LIBS=(
|
||||
"libshaderc_shared.so.1"
|
||||
)
|
||||
|
||||
declare -a MANUAL_QT_LIBS=(
|
||||
"libQt6WaylandEglClientHwIntegration.so.6"
|
||||
)
|
||||
|
||||
declare -a MANUAL_QT_PLUGINS=(
|
||||
"wayland-decoration-client"
|
||||
"wayland-graphics-integration-client"
|
||||
"wayland-shell-integration"
|
||||
)
|
||||
|
||||
declare -a REMOVE_LIBS=(
|
||||
'libwayland-client.so*'
|
||||
'libwayland-cursor.so*'
|
||||
'libwayland-egl.so*'
|
||||
"libharfbuzz.so.0"
|
||||
"libfreetype.so.6"
|
||||
)
|
||||
|
||||
set -e
|
||||
@@ -66,7 +52,6 @@ set -e
|
||||
LINUXDEPLOY=./linuxdeploy-x86_64.AppImage
|
||||
LINUXDEPLOY_PLUGIN_QT=./linuxdeploy-plugin-qt-x86_64.AppImage
|
||||
APPIMAGETOOL=./appimagetool-x86_64.AppImage
|
||||
PATCHELF=patchelf
|
||||
|
||||
if [ ! -f "$LINUXDEPLOY" ]; then
|
||||
"$PCSX2DIR/tools/retry.sh" wget -O "$LINUXDEPLOY" https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
|
||||
@@ -79,7 +64,7 @@ if [ ! -f "$LINUXDEPLOY_PLUGIN_QT" ]; then
|
||||
fi
|
||||
|
||||
if [ ! -f "$APPIMAGETOOL" ]; then
|
||||
"$PCSX2DIR/tools/retry.sh" wget -O "$APPIMAGETOOL" https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage
|
||||
"$PCSX2DIR/tools/retry.sh" wget -O "$APPIMAGETOOL" https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage
|
||||
chmod +x "$APPIMAGETOOL"
|
||||
fi
|
||||
|
||||
@@ -87,21 +72,16 @@ OUTDIR=$(realpath "./$APPDIRNAME")
|
||||
rm -fr "$OUTDIR"
|
||||
|
||||
echo "Locating extra libraries..."
|
||||
EXTRA_LIBS_ARGS=""
|
||||
EXTRA_LIBS_ARGS=()
|
||||
for lib in "${MANUAL_LIBS[@]}"; do
|
||||
srcpath=$(find "$DEPSDIR" -name "$lib")
|
||||
if [ ! -f "$srcpath" ]; then
|
||||
echo "Missinge extra library $lib. Exiting."
|
||||
echo "Missing extra library $lib. Exiting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Found $lib at $srcpath."
|
||||
|
||||
if [ "$EXTRA_LIBS_ARGS" == "" ]; then
|
||||
EXTRA_LIBS_ARGS="--library=$srcpath"
|
||||
else
|
||||
EXTRA_LIBS_ARGS="$EXTRA_LIBS_ARGS,$srcpath"
|
||||
fi
|
||||
EXTRA_LIBS_ARGS+=( "--library=$srcpath" )
|
||||
done
|
||||
|
||||
# Why the nastyness? linuxdeploy strips our main binary, and there's no option to turn it off.
|
||||
@@ -125,55 +105,20 @@ cp "$PCSX2DIR/.github/workflows/scripts/linux/pcsx2-qt.desktop" "net.pcsx2.PCSX2
|
||||
cp "$PCSX2DIR/bin/resources/icons/AppIconLarge.png" "PCSX2.png"
|
||||
|
||||
echo "Running linuxdeploy to create AppDir..."
|
||||
EXTRA_QT_PLUGINS="core;gui;svg;waylandclient;widgets;xcbqpa" \
|
||||
EXTRA_PLATFORM_PLUGINS="libqwayland-egl.so;libqwayland-generic.so" \
|
||||
# The wayland platform plugin requires the plugins deployed for the waylandcompositor module
|
||||
# Interestingly, specifying the module doesn't copy the module, only the required plugins for it
|
||||
# https://github.com/linuxdeploy/linuxdeploy-plugin-qt/issues/160#issuecomment-2655543893
|
||||
EXTRA_QT_MODULES="core;gui;svg;waylandclient;waylandcompositor;widgets;xcbqpa" \
|
||||
EXTRA_PLATFORM_PLUGINS="libqwayland.so" \
|
||||
DEPLOY_PLATFORM_THEMES="1" \
|
||||
QMAKE="$DEPSDIR/bin/qmake" \
|
||||
NO_STRIP="1" \
|
||||
$LINUXDEPLOY --plugin qt --appdir="$OUTDIR" --executable="$BUILDDIR/bin/pcsx2-qt" $EXTRA_LIBS_ARGS \
|
||||
$LINUXDEPLOY --plugin qt --appdir="$OUTDIR" --executable="$BUILDDIR/bin/pcsx2-qt" ${EXTRA_LIBS_ARGS[@]} \
|
||||
--desktop-file="net.pcsx2.PCSX2.desktop" --icon-file="PCSX2.png"
|
||||
|
||||
echo "Copying resources into AppDir..."
|
||||
cp -a "$BUILDDIR/bin/resources" "$OUTDIR/usr/bin"
|
||||
|
||||
# LinuxDeploy's Qt plugin doesn't include Wayland support. So manually copy in the additional Wayland libraries.
|
||||
echo "Copying Qt Wayland libraries..."
|
||||
for lib in "${MANUAL_QT_LIBS[@]}"; do
|
||||
srcpath="$DEPSDIR/lib/$lib"
|
||||
dstpath="$OUTDIR/usr/lib/$lib"
|
||||
echo " $srcpath -> $dstpath"
|
||||
cp "$srcpath" "$dstpath"
|
||||
$PATCHELF --set-rpath '$ORIGIN' "$dstpath"
|
||||
done
|
||||
|
||||
# .. and plugins.
|
||||
echo "Copying Qt Wayland plugins..."
|
||||
for GROUP in "${MANUAL_QT_PLUGINS[@]}"; do
|
||||
srcpath="$DEPSDIR/plugins/$GROUP"
|
||||
dstpath="$OUTDIR/usr/plugins/$GROUP"
|
||||
echo " $srcpath -> $dstpath"
|
||||
mkdir -p "$dstpath"
|
||||
|
||||
for srcsopath in $(find "$DEPSDIR/plugins/$GROUP" -iname '*.so'); do
|
||||
# This is ../../ because it's usually plugins/group/name.so
|
||||
soname=$(basename "$srcsopath")
|
||||
dstsopath="$dstpath/$soname"
|
||||
echo " $srcsopath -> $dstsopath"
|
||||
cp "$srcsopath" "$dstsopath"
|
||||
$PATCHELF --set-rpath '$ORIGIN/../../lib:$ORIGIN' "$dstsopath"
|
||||
done
|
||||
done
|
||||
|
||||
# Why do we have to manually remove these libs? Because the linuxdeploy Qt plugin
|
||||
# copies them, not the "main" linuxdeploy binary, and plugins don't inherit the
|
||||
# include list...
|
||||
for lib in "${REMOVE_LIBS[@]}"; do
|
||||
for libpath in $(find "$OUTDIR/usr/lib" -name "$lib"); do
|
||||
echo " Removing problematic library ${libpath}."
|
||||
rm -f "$libpath"
|
||||
done
|
||||
done
|
||||
|
||||
# Restore unstripped deps (for cache).
|
||||
rm -fr "$DEPSDIR"
|
||||
mv "$DEPSDIR.bak" "$DEPSDIR"
|
||||
|
||||
@@ -7,6 +7,10 @@ if [ "$#" -ne 1 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# The bundled ffmpeg has a lot of things disabled to reduce code size.
|
||||
# Users may want to use system ffmpeg for additional features
|
||||
: ${BUILD_FFMPEG:=0}
|
||||
|
||||
SCRIPTDIR=$(realpath $(dirname "${BASH_SOURCE[0]}"))
|
||||
NPROCS="$(getconf _NPROCESSORS_ONLN)"
|
||||
INSTALLDIR="$1"
|
||||
@@ -14,67 +18,126 @@ if [ "${INSTALLDIR:0:1}" != "/" ]; then
|
||||
INSTALLDIR="$PWD/$INSTALLDIR"
|
||||
fi
|
||||
|
||||
FFMPEG=8.0
|
||||
FREETYPE=2.14.1
|
||||
HARFBUZZ=12.2.0
|
||||
LIBBACKTRACE=ad106d5fdd5d960bd33fae1c48a351af567fd075
|
||||
LIBJPEGTURBO=3.1.0
|
||||
LIBPNG=1.6.45
|
||||
LIBWEBP=1.5.0
|
||||
LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
|
||||
SDL=SDL3-3.2.8
|
||||
QT=6.8.2
|
||||
LIBJPEGTURBO=3.1.2
|
||||
LIBPNG=1.6.53
|
||||
LIBWEBP=1.6.0
|
||||
NVENC=11.1.5.3
|
||||
SDL=SDL3-3.2.26
|
||||
QT=6.10.1
|
||||
QTAPNG=1.3.0
|
||||
LZ4=1.10.0
|
||||
VULKAN=1.4.328.1
|
||||
ZSTD=1.5.7
|
||||
KDDOCKWIDGETS=2.2.1
|
||||
KDDOCKWIDGETS=2.4.0
|
||||
PLUTOVG=1.3.2
|
||||
PLUTOSVG=0.0.7
|
||||
|
||||
SHADERC=2024.1
|
||||
SHADERC_GLSLANG=142052fa30f9eca191aa9dcf65359fcaed09eeec
|
||||
SHADERC_SPIRVHEADERS=5e3ad389ee56fca27c9705d093ae5387ce404df4
|
||||
SHADERC_SPIRVTOOLS=dd4b663e13c07fea4fbb3f70c1c91c86731099f7
|
||||
SHADERC=2025.4
|
||||
SHADERC_GLSLANG=7a47e2531cb334982b2a2dd8513dca0a3de4373d
|
||||
SHADERC_SPIRVHEADERS=b824a462d4256d720bebb40e78b9eb8f78bbb305
|
||||
SHADERC_SPIRVTOOLS=971a7b6e8d7740035bbff089bbbf9f42951ecfd5
|
||||
|
||||
mkdir -p deps-build
|
||||
cd deps-build
|
||||
|
||||
export PKG_CONFIG_PATH="$INSTALLDIR/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||
|
||||
cat > SHASUMS <<EOF
|
||||
b2751fccb6cc4c77708113cd78b561059b6fa904b24162fa0be2d60273d27b8e ffmpeg-$FFMPEG.tar.xz
|
||||
32427e8c471ac095853212a37aef816c60b42052d4d9e48230bab3bdf2936ccc freetype-$FREETYPE.tar.xz
|
||||
f63fc519f150465bd0bdafcdf3d0e9c23474f4c474171cd515ea1b3a72c081fb harfbuzz-$HARFBUZZ.tar.gz
|
||||
fd6f417fe9e3a071cf1424a5152d926a34c4a3c5070745470be6cf12a404ed79 $LIBBACKTRACE.zip
|
||||
9564c72b1dfd1d6fe6274c5f95a8d989b59854575d4bbee44ade7bc17aa9bc93 libjpeg-turbo-$LIBJPEGTURBO.tar.gz
|
||||
926485350139ffb51ef69760db35f78846c805fef3d59bfdcb2fba704663f370 libpng-$LIBPNG.tar.xz
|
||||
7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c libwebp-$LIBWEBP.tar.gz
|
||||
0728800155f3ed0a0c87e03addbd30ecbe374f7b080678bbca1506051d50dec3 $LZ4.tar.gz
|
||||
13388fabb361de768ecdf2b65e52bb27d1054cae6ccb6942ba926e378e00db03 $SDL.tar.gz
|
||||
8f0012234b464ce50890c490f18194f913a7b1f4e6a03d6644179fa0f867d0cf libjpeg-turbo-$LIBJPEGTURBO.tar.gz
|
||||
1d3fb8ccc2932d04aa3663e22ef5ef490244370f4e568d7850165068778d98d4 libpng-$LIBPNG.tar.xz
|
||||
e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 libwebp-$LIBWEBP.tar.gz
|
||||
dad488474a51a0b01d547cd2834893d6299328d2e30f479a3564088b5476bae2 $SDL.tar.gz
|
||||
452a1a290bd0cf18737fad0057dc17b7fdf10a73eda2d6d4f31ba04fda25ef2c libpng-$LIBPNG-apng.patch.gz
|
||||
537512904744b35e232912055ccf8ec66d768639ff3abe5788d90d792ec5f48b lz4-$LZ4.tar.gz
|
||||
2974b91062197e0527dffa3aadd8fe3bfa6681ae45f5ff9181bc0ca6479abd59 nv-codec-headers-$NVENC.tar.gz
|
||||
c465aa56757e7746ac707f582b6e2d51546569a4a2488c1172fb543aa5fdfc2c vulkan-sdk-$VULKAN.tar.gz
|
||||
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
|
||||
012043ce6d411e6e8a91fdc4e05e6bedcfa10fcb1347d3c33908f7fdd10dfe05 qtbase-everywhere-src-$QT.tar.xz
|
||||
d2a1bbb84707b8a0aec29227b170be00f04383fbf2361943596d09e7e443c8e1 qtimageformats-everywhere-src-$QT.tar.xz
|
||||
aa2579f21ca66d19cbcf31d87e9067e07932635d36869c8239d4decd0a9dc1fa qtsvg-everywhere-src-$QT.tar.xz
|
||||
326381b7d43f07913612f291abc298ae79bd95382e2233abce982cff2b53d2c0 qttools-everywhere-src-$QT.tar.xz
|
||||
d2106e8a580bfd77702c4c1840299288d344902b0e2c758ca813ea04c6d6a3d1 qttranslations-everywhere-src-$QT.tar.xz
|
||||
5e46157908295f2bf924462d8c0855b0508ba338ced9e810891fefa295dc9647 qtwayland-everywhere-src-$QT.tar.xz
|
||||
eb3b5f0c16313d34f208d90c2fa1e588a23283eed63b101edd5422be6165d528 shaderc-$SHADERC.tar.gz
|
||||
aa27e4454ce631c5a17924ce0624eac736da19fc6f5a2ab15a6c58da7b36950f shaderc-glslang-$SHADERC_GLSLANG.tar.gz
|
||||
5d866ce34a4b6908e262e5ebfffc0a5e11dd411640b5f24c85a80ad44c0d4697 shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz
|
||||
03ee1a2c06f3b61008478f4abe9423454e53e580b9488b47c8071547c6a9db47 shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz
|
||||
8693e06abee0c88517d8480b22647702a51a0708f3c876ed5385d9a4e356e1a5 KDDockWidgets-$KDDOCKWIDGETS.tar.gz
|
||||
5a6226f7e23db51fdc3223121eba53f3f5447cf0cc4d6cb82a3a2df7a65d265d qtbase-everywhere-src-$QT.tar.xz
|
||||
498eabdf2381db96f808942b3e3c765f6360fe6c0e9961f0a45ff7a4c68d7a72 qtimageformats-everywhere-src-$QT.tar.xz
|
||||
c02f355a58f3bbcf404a628bf488b6aeb2d84a94c269afdb86f6e529343ab01f qtsvg-everywhere-src-$QT.tar.xz
|
||||
8148408380ffea03101a26305c812b612ea30dbc07121e58707601522404d49b qttools-everywhere-src-$QT.tar.xz
|
||||
8e49a2df88a12c376a479ae7bd272a91cf57ebb4e7c0cf7341b3565df99d2314 qttranslations-everywhere-src-$QT.tar.xz
|
||||
49bf6db800227a6b2c971f4c5d03dd1e81297e7ffb296ce4a96437304f27cb13 qtwayland-everywhere-src-$QT.tar.xz
|
||||
f1d3be3489f758efe1a8f12118a212febbe611aa670af32e0159fa3c1feab2a6 QtApng-$QTAPNG.tar.gz
|
||||
8a89fb6612ace8954470aae004623374a8fc8b7a34a4277bee5527173b064faf shaderc-$SHADERC.tar.gz
|
||||
272d2725b140e09e85b96eecdc59c2e00c1a14cda2301767e1bf3c363a44b931 shaderc-glslang-$SHADERC_GLSLANG.tar.gz
|
||||
c693867f10a7760ef1bcf85419d51783586768cc2c601d03841bc6a8b2554b9c shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz
|
||||
06b0a042f2e121e954badb4fd78c9e2d4bc7ed6087eceb26ab559c23cf94334f shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz
|
||||
51dbf24fe72e43dd7cb9a289d3cab47112010f1a2ed69b6fc8ac0dff31991ed2 KDDockWidgets-$KDDOCKWIDGETS.tar.gz
|
||||
7bd4e79ce18b1d47517e7e91fbb7cf19d4f01942804a519bc7c0bf32b6325dd5 plutovg-$PLUTOVG.tar.gz
|
||||
78561b571ac224030cdc450ca2986b4de915c2ba7616004a6d71a379bffd15f3 plutosvg-$PLUTOSVG.tar.gz
|
||||
EOF
|
||||
|
||||
curl -L \
|
||||
-o "freetype-$FREETYPE.tar.xz" "https://sourceforge.net/projects/freetype/files/freetype2/$FREETYPE/freetype-$FREETYPE.tar.xz/download" \
|
||||
-o "harfbuzz-$HARFBUZZ.tar.gz" "https://github.com/harfbuzz/harfbuzz/archive/refs/tags/$HARFBUZZ.tar.gz" \
|
||||
-O "https://github.com/ianlancetaylor/libbacktrace/archive/$LIBBACKTRACE.zip" \
|
||||
-O "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/$LIBJPEGTURBO/libjpeg-turbo-$LIBJPEGTURBO.tar.gz" \
|
||||
-O "https://downloads.sourceforge.net/project/libpng/libpng16/$LIBPNG/libpng-$LIBPNG.tar.xz" \
|
||||
-O "https://download.sourceforge.net/libpng-apng/libpng-$LIBPNG-apng.patch.gz" \
|
||||
-O "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-$LIBWEBP.tar.gz" \
|
||||
-O "https://github.com/lz4/lz4/archive/$LZ4.tar.gz" \
|
||||
-O "https://github.com/lz4/lz4/releases/download/v$LZ4/lz4-$LZ4.tar.gz" \
|
||||
-O "https://libsdl.org/release/$SDL.tar.gz" \
|
||||
-O "https://github.com/facebook/zstd/releases/download/v$ZSTD/zstd-$ZSTD.tar.gz" \
|
||||
-O "https://github.com/KhronosGroup/Vulkan-Headers/archive/refs/tags/vulkan-sdk-$VULKAN.tar.gz" \
|
||||
-O "https://github.com/FFmpeg/nv-codec-headers/releases/download/n$NVENC/nv-codec-headers-$NVENC.tar.gz" \
|
||||
-O "https://ffmpeg.org/releases/ffmpeg-$FFMPEG.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtbase-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtimageformats-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtsvg-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qttools-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qttranslations-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtwayland-everywhere-src-$QT.tar.xz" \
|
||||
-o "QtApng-$QTAPNG.tar.gz" "https://github.com/jurplel/QtApng/archive/refs/tags/$QTAPNG.tar.gz" \
|
||||
-o "shaderc-$SHADERC.tar.gz" "https://github.com/google/shaderc/archive/refs/tags/v$SHADERC.tar.gz" \
|
||||
-o "shaderc-glslang-$SHADERC_GLSLANG.tar.gz" "https://github.com/KhronosGroup/glslang/archive/$SHADERC_GLSLANG.tar.gz" \
|
||||
-o "shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz" "https://github.com/KhronosGroup/SPIRV-Headers/archive/$SHADERC_SPIRVHEADERS.tar.gz" \
|
||||
-o "shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz" "https://github.com/KhronosGroup/SPIRV-Tools/archive/$SHADERC_SPIRVTOOLS.tar.gz" \
|
||||
-o "KDDockWidgets-$KDDOCKWIDGETS.tar.gz" "https://github.com/KDAB/KDDockWidgets/archive/v$KDDOCKWIDGETS.tar.gz"
|
||||
-o "KDDockWidgets-$KDDOCKWIDGETS.tar.gz" "https://github.com/KDAB/KDDockWidgets/archive/v$KDDOCKWIDGETS.tar.gz" \
|
||||
-o "plutovg-$PLUTOVG.tar.gz" "https://github.com/sammycage/plutovg/archive/v$PLUTOVG.tar.gz" \
|
||||
-o "plutosvg-$PLUTOSVG.tar.gz" "https://github.com/sammycage/plutosvg/archive/v$PLUTOSVG.tar.gz"
|
||||
|
||||
shasum -a 256 --check SHASUMS
|
||||
|
||||
if [ "$BUILD_FFMPEG" -ne 0 ]; then
|
||||
echo "Installing vulkan headers..."
|
||||
rm -fr "Vulkan-Headers-vulkan-sdk-$VULKAN"
|
||||
tar xf "vulkan-sdk-$VULKAN.tar.gz"
|
||||
cd "Vulkan-Headers-vulkan-sdk-$VULKAN"
|
||||
cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR"
|
||||
make -C build install
|
||||
cd ..
|
||||
|
||||
echo "Installing nvenc headers..."
|
||||
rm -fr "nv-codec-headers-$NVENC"
|
||||
tar xf "nv-codec-headers-$NVENC.tar.gz"
|
||||
make -C "nv-codec-headers-$NVENC" PREFIX="$INSTALLDIR" install
|
||||
|
||||
echo "Installing FFmpeg..."
|
||||
rm -fr "ffmpeg-$FFMPEG"
|
||||
tar xf "ffmpeg-$FFMPEG.tar.xz"
|
||||
cd "ffmpeg-$FFMPEG"
|
||||
CFLAGS="-Os $CFLAGS" CXXFLAGS="-Os $CXXFLAGS" \
|
||||
./configure --prefix="$INSTALLDIR" \
|
||||
--disable-all --disable-autodetect --disable-static --enable-shared \
|
||||
--enable-avcodec --enable-avformat --enable-avutil --enable-swresample --enable-swscale \
|
||||
--enable-gpl --enable-libx264 --enable-libopus --enable-vulkan --enable-ffnvcodec --enable-nvenc --enable-vaapi --enable-libvpl \
|
||||
--enable-encoder=ffv1,qtrle,libx264*,aac,flac,libopus,pcm_s16be,pcm_s16le,*_vulkan,*_qsv,*_nvenc,*_vaapi \
|
||||
--enable-muxer=avi,matroska,mov,mp3,mp4,wav \
|
||||
--enable-protocol=file
|
||||
make "-j$NPROCS"
|
||||
make install
|
||||
cd ..
|
||||
fi
|
||||
|
||||
echo "Building libbacktrace..."
|
||||
rm -fr "libbacktrace-$LIBBACKTRACE"
|
||||
unzip "$LIBBACKTRACE.zip"
|
||||
@@ -87,7 +150,9 @@ cd ..
|
||||
echo "Building libpng..."
|
||||
rm -fr "libpng-$LIBPNG"
|
||||
tar xf "libpng-$LIBPNG.tar.xz"
|
||||
gunzip -d -f "libpng-$LIBPNG-apng.patch.gz"
|
||||
cd "libpng-$LIBPNG"
|
||||
patch -p1 < "../libpng-$LIBPNG-apng.patch"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DBUILD_SHARED_LIBS=ON -DBUILD_SHARED_LIBS=ON -DPNG_TESTS=OFF -DPNG_STATIC=OFF -DPNG_SHARED=ON -DPNG_TOOLS=OFF -B build -G Ninja
|
||||
cmake --build build --parallel
|
||||
ninja -C build install
|
||||
@@ -97,14 +162,16 @@ echo "Building libjpegturbo..."
|
||||
rm -fr "libjpeg-turbo-$LIBJPEGTURBO"
|
||||
tar xf "libjpeg-turbo-$LIBJPEGTURBO.tar.gz"
|
||||
cd "libjpeg-turbo-$LIBJPEGTURBO"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DENABLE_STATIC=OFF -DENABLE_SHARED=ON -B build -G Ninja
|
||||
# On non debian or debian based Linux systems, libjpeg-turbo will set CMAKE_INSTALL_DEFAULT_LIBDIR "lib64" (or libx32)
|
||||
# That will prevent CMake from finding the deps libjpeg later on. if we set CMAKE_INSTALL_DEFAULT_LIBDIR, libjpeg-turbo will leave it as is, so set it to "lib"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DENABLE_STATIC=OFF -DENABLE_SHARED=ON -DCMAKE_INSTALL_DEFAULT_LIBDIR="lib" -B build -G Ninja
|
||||
cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building LZ4..."
|
||||
rm -fr "lz4-$LZ4"
|
||||
tar xf "$LZ4.tar.gz"
|
||||
tar xf "lz4-$LZ4.tar.gz"
|
||||
cd "lz4-$LZ4"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DBUILD_SHARED_LIBS=ON -DLZ4_BUILD_CLI=OFF -DLZ4_BUILD_LEGACY_LZ4C=OFF -B build-dir -G Ninja build/cmake
|
||||
cmake --build build-dir --parallel
|
||||
@@ -131,6 +198,35 @@ cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building FreeType without HarfBuzz..."
|
||||
rm -fr "freetype-$FREETYPE"
|
||||
tar xf "freetype-$FREETYPE.tar.xz"
|
||||
cd "freetype-$FREETYPE"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DBUILD_SHARED_LIBS=ON -DFT_REQUIRE_ZLIB=ON -DFT_REQUIRE_PNG=ON -DFT_DISABLE_BZIP2=TRUE -DFT_DISABLE_BROTLI=TRUE -DFT_DISABLE_HARFBUZZ=TRUE -B build -G Ninja
|
||||
cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building HarfBuzz..."
|
||||
rm -fr "harfbuzz-$HARFBUZZ"
|
||||
tar xf "harfbuzz-$HARFBUZZ.tar.gz"
|
||||
cd "harfbuzz-$HARFBUZZ"
|
||||
# Add an SOVERSION to match system harfbuzz
|
||||
sed -i 's/PROPERTIES VISIBILITY_INLINES_HIDDEN TRUE)/PROPERTIES VISIBILITY_INLINES_HIDDEN TRUE SOVERSION 0)/g' CMakeLists.txt
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DBUILD_SHARED_LIBS=ON -DHB_BUILD_UTILS=OFF -DHB_HAVE_FREETYPE=ON -DHB_HAVE_GOBJECT=ON -B build -G Ninja
|
||||
cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building FreeType with HarfBuzz..."
|
||||
rm -fr "freetype-$FREETYPE"
|
||||
tar xf "freetype-$FREETYPE.tar.xz"
|
||||
cd "freetype-$FREETYPE"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DBUILD_SHARED_LIBS=ON -DFT_REQUIRE_ZLIB=ON -DFT_REQUIRE_PNG=ON -DFT_DISABLE_BZIP2=TRUE -DFT_DISABLE_BROTLI=TRUE -DFT_REQUIRE_HARFBUZZ=TRUE -B build -G Ninja
|
||||
cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building SDL..."
|
||||
rm -fr "$SDL"
|
||||
tar xf "$SDL.tar.gz"
|
||||
@@ -151,7 +247,7 @@ tar xf "qtbase-everywhere-src-$QT.tar.xz"
|
||||
cd "qtbase-everywhere-src-$QT"
|
||||
mkdir build
|
||||
cd build
|
||||
../configure -prefix "$INSTALLDIR" -release -dbus-linked -gui -widgets -fontconfig -qt-doubleconversion -ssl -openssl-runtime -opengl desktop -qpa xcb,wayland -xkbcommon -xcb -gtk -- -DFEATURE_dbus=ON -DFEATURE_icu=OFF -DFEATURE_printsupport=OFF -DFEATURE_sql=OFF -DFEATURE_system_png=ON -DFEATURE_system_jpeg=ON -DFEATURE_system_zlib=ON -DFEATURE_system_freetype=ON -DFEATURE_system_harfbuzz=ON
|
||||
../configure -prefix "$INSTALLDIR" -release -dbus-linked -gui -widgets -fontconfig -qt-doubleconversion -ssl -openssl-runtime -opengl desktop -qpa xcb,wayland -xkbcommon -xcb -gtk -- --log-level=STATUS -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DFEATURE_dbus=ON -DFEATURE_icu=OFF -DFEATURE_printsupport=OFF -DFEATURE_sql=OFF -DFEATURE_system_png=ON -DFEATURE_system_jpeg=ON -DFEATURE_system_zlib=ON -DFEATURE_system_freetype=ON -DFEATURE_system_harfbuzz=ON
|
||||
cmake --build . --parallel
|
||||
ninja install
|
||||
cd ../../
|
||||
@@ -193,32 +289,9 @@ echo "Installing Qt Tools..."
|
||||
rm -fr "qttools-everywhere-src-$QT"
|
||||
tar xf "qttools-everywhere-src-$QT.tar.xz"
|
||||
cd "qttools-everywhere-src-$QT"
|
||||
# Force disable clang scanning, it gets very confused.
|
||||
patch -u configure.cmake <<EOF
|
||||
--- configure.cmake
|
||||
+++ configure.cmake
|
||||
@@ -14,12 +14,12 @@
|
||||
# Presumably because 6.0 ClangConfig.cmake files are not good enough?
|
||||
# In any case explicitly request a minimum version of 8.x for now, otherwise
|
||||
# building with CMake will fail at compilation time.
|
||||
-qt_find_package(WrapLibClang 8 PROVIDED_TARGETS WrapLibClang::WrapLibClang)
|
||||
+#qt_find_package(WrapLibClang 8 PROVIDED_TARGETS WrapLibClang::WrapLibClang)
|
||||
# special case end
|
||||
|
||||
-if(TARGET WrapLibClang::WrapLibClang)
|
||||
- set(TEST_libclang "ON" CACHE BOOL "Required libclang version found." FORCE)
|
||||
-endif()
|
||||
+#if(TARGET WrapLibClang::WrapLibClang)
|
||||
+# set(TEST_libclang "ON" CACHE BOOL "Required libclang version found." FORCE)
|
||||
+#endif()
|
||||
|
||||
|
||||
|
||||
EOF
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DFEATURE_assistant=OFF -DFEATURE_clang=OFF -DFEATURE_designer=ON -DFEATURE_kmap2qmap=OFF -DFEATURE_pixeltool=OFF -DFEATURE_pkg_config=OFF -DFEATURE_qev=OFF -DFEATURE_qtattributionsscanner=OFF -DFEATURE_qtdiag=OFF -DFEATURE_qtplugininfo=OFF
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DFEATURE_assistant=OFF -DFEATURE_clang=OFF -DFEATURE_designer=OFF -DFEATURE_kmap2qmap=OFF -DFEATURE_pixeltool=OFF -DFEATURE_pkg_config=OFF -DFEATURE_qev=OFF -DFEATURE_qtattributionsscanner=OFF -DFEATURE_qtdiag=OFF -DFEATURE_qtplugininfo=OFF
|
||||
cmake --build . --parallel
|
||||
ninja install
|
||||
cd ../../
|
||||
@@ -234,16 +307,43 @@ cmake --build . --parallel
|
||||
ninja install
|
||||
cd ../../
|
||||
|
||||
echo "Building Qt APNG..."
|
||||
rm -fr "QtApng-$QTAPNG"
|
||||
tar xf "QtApng-$QTAPNG.tar.gz"
|
||||
cd "QtApng-$QTAPNG"
|
||||
patch -p1 < "$SCRIPTDIR/../common/qtapng-cmake.patch"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -B build -G Ninja
|
||||
cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building KDDockWidgets..."
|
||||
rm -fr "KDDockWidgets-$KDDOCKWIDGETS"
|
||||
tar xf "KDDockWidgets-$KDDOCKWIDGETS.tar.gz"
|
||||
cd "KDDockWidgets-$KDDOCKWIDGETS"
|
||||
patch -p1 < "$SCRIPTDIR/../common/kddockwidgets-dodgy-include.patch"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DKDDockWidgets_QT6=true -DKDDockWidgets_EXAMPLES=false -DKDDockWidgets_FRONTENDS=qtwidgets -B build -G Ninja
|
||||
cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building PlutoVG..."
|
||||
rm -fr "plutovg-$PLUTOVG"
|
||||
tar xf "plutovg-$PLUTOVG.tar.gz"
|
||||
cd "plutovg-$PLUTOVG"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DBUILD_SHARED_LIBS=ON -DPLUTOVG_BUILD_EXAMPLES=OFF -B build -G Ninja
|
||||
cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building PlutoSVG..."
|
||||
rm -fr "plutosvg-$PLUTOSVG"
|
||||
tar xf "plutosvg-$PLUTOSVG.tar.gz"
|
||||
cd "plutosvg-$PLUTOSVG"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DBUILD_SHARED_LIBS=ON -DPLUTOSVG_ENABLE_FREETYPE=ON -DPLUTOSVG_BUILD_EXAMPLES=OFF -B build -G Ninja
|
||||
cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building shaderc..."
|
||||
rm -fr "shaderc-$SHADERC"
|
||||
tar xf "shaderc-$SHADERC.tar.gz"
|
||||
|
||||
196
.github/workflows/scripts/linux/build-dependencies-runner.sh
vendored
Executable file
196
.github/workflows/scripts/linux/build-dependencies-runner.sh
vendored
Executable file
@@ -0,0 +1,196 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Syntax: $0 <output directory>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SCRIPTDIR=$(realpath $(dirname "${BASH_SOURCE[0]}"))
|
||||
NPROCS="$(getconf _NPROCESSORS_ONLN)"
|
||||
INSTALLDIR="$1"
|
||||
if [ "${INSTALLDIR:0:1}" != "/" ]; then
|
||||
INSTALLDIR="$PWD/$INSTALLDIR"
|
||||
fi
|
||||
|
||||
FREETYPE=2.14.1
|
||||
HARFBUZZ=12.2.0
|
||||
LIBBACKTRACE=ad106d5fdd5d960bd33fae1c48a351af567fd075
|
||||
LIBPNG=1.6.51
|
||||
LIBWEBP=1.6.0
|
||||
SDL=SDL3-3.2.26
|
||||
LZ4=1.10.0
|
||||
ZSTD=1.5.7
|
||||
PLUTOVG=1.3.2
|
||||
PLUTOSVG=0.0.7
|
||||
|
||||
SHADERC=2025.4
|
||||
SHADERC_GLSLANG=7a47e2531cb334982b2a2dd8513dca0a3de4373d
|
||||
SHADERC_SPIRVHEADERS=b824a462d4256d720bebb40e78b9eb8f78bbb305
|
||||
SHADERC_SPIRVTOOLS=971a7b6e8d7740035bbff089bbbf9f42951ecfd5
|
||||
|
||||
mkdir -p deps-build
|
||||
cd deps-build
|
||||
|
||||
cat > SHASUMS <<EOF
|
||||
32427e8c471ac095853212a37aef816c60b42052d4d9e48230bab3bdf2936ccc freetype-$FREETYPE.tar.xz
|
||||
f63fc519f150465bd0bdafcdf3d0e9c23474f4c474171cd515ea1b3a72c081fb harfbuzz-$HARFBUZZ.tar.gz
|
||||
fd6f417fe9e3a071cf1424a5152d926a34c4a3c5070745470be6cf12a404ed79 $LIBBACKTRACE.zip
|
||||
a050a892d3b4a7bb010c3a95c7301e49656d72a64f1fc709a90b8aded192bed2 libpng-$LIBPNG.tar.xz
|
||||
e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 libwebp-$LIBWEBP.tar.gz
|
||||
dad488474a51a0b01d547cd2834893d6299328d2e30f479a3564088b5476bae2 $SDL.tar.gz
|
||||
9c16ec5654be709f062a705d0c6f529193f1c2123fe7f102fda6733913689023 libpng-$LIBPNG-apng.patch.gz
|
||||
537512904744b35e232912055ccf8ec66d768639ff3abe5788d90d792ec5f48b lz4-$LZ4.tar.gz
|
||||
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
|
||||
8a89fb6612ace8954470aae004623374a8fc8b7a34a4277bee5527173b064faf shaderc-$SHADERC.tar.gz
|
||||
272d2725b140e09e85b96eecdc59c2e00c1a14cda2301767e1bf3c363a44b931 shaderc-glslang-$SHADERC_GLSLANG.tar.gz
|
||||
c693867f10a7760ef1bcf85419d51783586768cc2c601d03841bc6a8b2554b9c shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz
|
||||
06b0a042f2e121e954badb4fd78c9e2d4bc7ed6087eceb26ab559c23cf94334f shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz
|
||||
7bd4e79ce18b1d47517e7e91fbb7cf19d4f01942804a519bc7c0bf32b6325dd5 plutovg-$PLUTOVG.tar.gz
|
||||
78561b571ac224030cdc450ca2986b4de915c2ba7616004a6d71a379bffd15f3 plutosvg-$PLUTOSVG.tar.gz
|
||||
EOF
|
||||
|
||||
curl -L \
|
||||
-o "freetype-$FREETYPE.tar.xz" "https://sourceforge.net/projects/freetype/files/freetype2/$FREETYPE/freetype-$FREETYPE.tar.xz/download" \
|
||||
-o "harfbuzz-$HARFBUZZ.tar.gz" "https://github.com/harfbuzz/harfbuzz/archive/refs/tags/$HARFBUZZ.tar.gz" \
|
||||
-O "https://github.com/ianlancetaylor/libbacktrace/archive/$LIBBACKTRACE.zip" \
|
||||
-O "https://downloads.sourceforge.net/project/libpng/libpng16/$LIBPNG/libpng-$LIBPNG.tar.xz" \
|
||||
-O "https://download.sourceforge.net/libpng-apng/libpng-$LIBPNG-apng.patch.gz" \
|
||||
-O "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-$LIBWEBP.tar.gz" \
|
||||
-O "https://github.com/lz4/lz4/releases/download/v$LZ4/lz4-$LZ4.tar.gz" \
|
||||
-O "https://libsdl.org/release/$SDL.tar.gz" \
|
||||
-O "https://github.com/facebook/zstd/releases/download/v$ZSTD/zstd-$ZSTD.tar.gz" \
|
||||
-o "shaderc-$SHADERC.tar.gz" "https://github.com/google/shaderc/archive/refs/tags/v$SHADERC.tar.gz" \
|
||||
-o "shaderc-glslang-$SHADERC_GLSLANG.tar.gz" "https://github.com/KhronosGroup/glslang/archive/$SHADERC_GLSLANG.tar.gz" \
|
||||
-o "shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz" "https://github.com/KhronosGroup/SPIRV-Headers/archive/$SHADERC_SPIRVHEADERS.tar.gz" \
|
||||
-o "shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz" "https://github.com/KhronosGroup/SPIRV-Tools/archive/$SHADERC_SPIRVTOOLS.tar.gz" \
|
||||
-o "plutovg-$PLUTOVG.tar.gz" "https://github.com/sammycage/plutovg/archive/v$PLUTOVG.tar.gz" \
|
||||
-o "plutosvg-$PLUTOSVG.tar.gz" "https://github.com/sammycage/plutosvg/archive/v$PLUTOSVG.tar.gz"
|
||||
|
||||
shasum -a 256 --check SHASUMS
|
||||
|
||||
echo "Building libbacktrace..."
|
||||
rm -fr "libbacktrace-$LIBBACKTRACE"
|
||||
unzip "$LIBBACKTRACE.zip"
|
||||
cd "libbacktrace-$LIBBACKTRACE"
|
||||
./configure --prefix="$INSTALLDIR"
|
||||
make
|
||||
make install
|
||||
cd ..
|
||||
|
||||
echo "Building libpng..."
|
||||
rm -fr "libpng-$LIBPNG"
|
||||
tar xf "libpng-$LIBPNG.tar.xz"
|
||||
gunzip -d -f "libpng-$LIBPNG-apng.patch.gz"
|
||||
cd "libpng-$LIBPNG"
|
||||
patch -p1 < "../libpng-$LIBPNG-apng.patch"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DBUILD_SHARED_LIBS=ON -DBUILD_SHARED_LIBS=ON -DPNG_TESTS=OFF -DPNG_STATIC=OFF -DPNG_SHARED=ON -DPNG_TOOLS=OFF -B build -G Ninja
|
||||
cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building LZ4..."
|
||||
rm -fr "lz4-$LZ4"
|
||||
tar xf "lz4-$LZ4.tar.gz"
|
||||
cd "lz4-$LZ4"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DBUILD_SHARED_LIBS=ON -DLZ4_BUILD_CLI=OFF -DLZ4_BUILD_LEGACY_LZ4C=OFF -B build-dir -G Ninja build/cmake
|
||||
cmake --build build-dir --parallel
|
||||
ninja -C build-dir install
|
||||
cd ..
|
||||
|
||||
echo "Building Zstandard..."
|
||||
rm -fr "zstd-$ZSTD"
|
||||
tar xf "zstd-$ZSTD.tar.gz"
|
||||
cd "zstd-$ZSTD"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DBUILD_SHARED_LIBS=ON -DZSTD_BUILD_SHARED=ON -DZSTD_BUILD_STATIC=OFF -DZSTD_BUILD_PROGRAMS=OFF -B build -G Ninja build/cmake
|
||||
cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building FreeType without HarfBuzz..."
|
||||
rm -fr "freetype-$FREETYPE"
|
||||
tar xf "freetype-$FREETYPE.tar.xz"
|
||||
cd "freetype-$FREETYPE"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DBUILD_SHARED_LIBS=ON -DFT_REQUIRE_ZLIB=ON -DFT_REQUIRE_PNG=ON -DFT_DISABLE_BZIP2=TRUE -DFT_DISABLE_BROTLI=TRUE -DFT_DISABLE_HARFBUZZ=TRUE -B build -G Ninja
|
||||
cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building HarfBuzz..."
|
||||
rm -fr "harfbuzz-$HARFBUZZ"
|
||||
tar xf "harfbuzz-$HARFBUZZ.tar.gz"
|
||||
cd "harfbuzz-$HARFBUZZ"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DBUILD_SHARED_LIBS=ON -DHB_BUILD_UTILS=OFF -DHB_HAVE_FREETYPE=ON -B build -G Ninja
|
||||
cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building WebP..."
|
||||
rm -fr "libwebp-$LIBWEBP"
|
||||
tar xf "libwebp-$LIBWEBP.tar.gz"
|
||||
cd "libwebp-$LIBWEBP"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -B build -G Ninja \
|
||||
-DWEBP_BUILD_ANIM_UTILS=OFF -DWEBP_BUILD_CWEBP=OFF -DWEBP_BUILD_DWEBP=OFF -DWEBP_BUILD_GIF2WEBP=OFF -DWEBP_BUILD_IMG2WEBP=OFF \
|
||||
-DWEBP_BUILD_VWEBP=OFF -DWEBP_BUILD_WEBPINFO=OFF -DWEBP_BUILD_WEBPMUX=OFF -DWEBP_BUILD_EXTRAS=OFF -DBUILD_SHARED_LIBS=ON
|
||||
cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building FreeType with HarfBuzz..."
|
||||
rm -fr "freetype-$FREETYPE"
|
||||
tar xf "freetype-$FREETYPE.tar.xz"
|
||||
cd "freetype-$FREETYPE"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DBUILD_SHARED_LIBS=ON -DFT_REQUIRE_ZLIB=ON -DFT_REQUIRE_PNG=ON -DFT_DISABLE_BZIP2=TRUE -DFT_DISABLE_BROTLI=TRUE -DFT_REQUIRE_HARFBUZZ=TRUE -B build -G Ninja
|
||||
cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building SDL..."
|
||||
rm -fr "$SDL"
|
||||
tar xf "$SDL.tar.gz"
|
||||
cd "$SDL"
|
||||
cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DBUILD_SHARED_LIBS=ON -DSDL_SHARED=ON -DSDL_STATIC=OFF -G Ninja
|
||||
cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building PlutoVG..."
|
||||
rm -fr "plutovg-$PLUTOVG"
|
||||
tar xf "plutovg-$PLUTOVG.tar.gz"
|
||||
cd "plutovg-$PLUTOVG"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DBUILD_SHARED_LIBS=ON -DPLUTOVG_BUILD_EXAMPLES=OFF -B build -G Ninja
|
||||
cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building PlutoSVG..."
|
||||
rm -fr "plutosvg-$PLUTOSVG"
|
||||
tar xf "plutosvg-$PLUTOSVG.tar.gz"
|
||||
cd "plutosvg-$PLUTOSVG"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DBUILD_SHARED_LIBS=ON -DPLUTOSVG_ENABLE_FREETYPE=ON -DPLUTOSVG_BUILD_EXAMPLES=OFF -B build -G Ninja
|
||||
cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building shaderc..."
|
||||
rm -fr "shaderc-$SHADERC"
|
||||
tar xf "shaderc-$SHADERC.tar.gz"
|
||||
cd "shaderc-$SHADERC"
|
||||
cd third_party
|
||||
tar xf "../../shaderc-glslang-$SHADERC_GLSLANG.tar.gz"
|
||||
mv "glslang-$SHADERC_GLSLANG" "glslang"
|
||||
tar xf "../../shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz"
|
||||
mv "SPIRV-Headers-$SHADERC_SPIRVHEADERS" "spirv-headers"
|
||||
tar xf "../../shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz"
|
||||
mv "SPIRV-Tools-$SHADERC_SPIRVTOOLS" "spirv-tools"
|
||||
cd ..
|
||||
patch -p1 < "$SCRIPTDIR/../common/shaderc-changes.patch"
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DSHADERC_SKIP_TESTS=ON -DSHADERC_SKIP_EXAMPLES=ON -DSHADERC_SKIP_COPYRIGHT_CHECK=ON -B build -G Ninja
|
||||
cmake --build build --parallel
|
||||
ninja -C build install
|
||||
cd ..
|
||||
|
||||
echo "Cleaning up..."
|
||||
cd ..
|
||||
rm -r deps-build
|
||||
48
.github/workflows/scripts/linux/build-gammaray.sh
vendored
Executable file
48
.github/workflows/scripts/linux/build-gammaray.sh
vendored
Executable file
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
if [ "$#" -ne 2 ]; then
|
||||
echo "Syntax: $0 <deps directory> <output directory>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DEPSDIR=$(realpath "$1")
|
||||
INSTALLDIR=$(realpath "$2")
|
||||
|
||||
if [ ! -d "$DEPSDIR/include/QtCore" ]; then
|
||||
echo "Error: The build-dependencies-qt.sh script must be run on the deps directory first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
GAMMARAY=master
|
||||
|
||||
mkdir -p gammaray-build
|
||||
cd gammaray-build
|
||||
|
||||
echo "Downloading..."
|
||||
curl -L -o "GammaRay-$GAMMARAY.tar.gz" https://github.com/KDAB/GammaRay/archive/$GAMMARAY.tar.gz
|
||||
|
||||
rm -fr "GammaRay-$GAMMARAY"
|
||||
|
||||
echo "Extracting..."
|
||||
tar xf "GammaRay-$GAMMARAY.tar.gz"
|
||||
|
||||
cd "GammaRay-$GAMMARAY"
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
echo "Configuring..."
|
||||
cmake -DCMAKE_PREFIX_PATH="$DEPSDIR" -G Ninja -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DGAMMARAY_BUILD_DOCS=false ..
|
||||
|
||||
echo "Building..."
|
||||
cmake --build . --parallel
|
||||
|
||||
echo "Installing..."
|
||||
cmake --build . --target install
|
||||
|
||||
cd ../..
|
||||
|
||||
echo "Cleaning up..."
|
||||
cd ..
|
||||
rm -r gammaray-build
|
||||
@@ -14,8 +14,8 @@
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://libsdl.org/release/SDL3-3.2.8.tar.gz",
|
||||
"sha256": "13388fabb361de768ecdf2b65e52bb27d1054cae6ccb6942ba926e378e00db03"
|
||||
"url": "https://libsdl.org/release/SDL3-3.2.26.tar.gz",
|
||||
"sha256": "dad488474a51a0b01d547cd2834893d6299328d2e30f479a3564088b5476bae2"
|
||||
}
|
||||
],
|
||||
"cleanup": [
|
||||
|
||||
@@ -15,24 +15,24 @@
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/google/shaderc.git",
|
||||
"commit": "47a9387ef5b3600d30d84c71ec77a59dc7db46fa"
|
||||
"commit": "73743588fe9c39f2f1c780a087d94afac691a189"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://github.com/KhronosGroup/glslang/archive/142052fa30f9eca191aa9dcf65359fcaed09eeec.tar.gz",
|
||||
"sha256": "aa27e4454ce631c5a17924ce0624eac736da19fc6f5a2ab15a6c58da7b36950f",
|
||||
"url": "https://github.com/KhronosGroup/glslang/archive/7a47e2531cb334982b2a2dd8513dca0a3de4373d.tar.gz",
|
||||
"sha256": "272d2725b140e09e85b96eecdc59c2e00c1a14cda2301767e1bf3c363a44b931",
|
||||
"dest": "third_party/glslang"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://github.com/KhronosGroup/SPIRV-Headers/archive/5e3ad389ee56fca27c9705d093ae5387ce404df4.tar.gz",
|
||||
"sha256": "5d866ce34a4b6908e262e5ebfffc0a5e11dd411640b5f24c85a80ad44c0d4697",
|
||||
"url": "https://github.com/KhronosGroup/SPIRV-Headers/archive/b824a462d4256d720bebb40e78b9eb8f78bbb305.tar.gz",
|
||||
"sha256": "c693867f10a7760ef1bcf85419d51783586768cc2c601d03841bc6a8b2554b9c",
|
||||
"dest": "third_party/spirv-headers"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://github.com/KhronosGroup/SPIRV-Tools/archive/dd4b663e13c07fea4fbb3f70c1c91c86731099f7.tar.gz",
|
||||
"sha256": "03ee1a2c06f3b61008478f4abe9423454e53e580b9488b47c8071547c6a9db47",
|
||||
"url": "https://github.com/KhronosGroup/SPIRV-Tools/archive/971a7b6e8d7740035bbff089bbbf9f42951ecfd5.tar.gz",
|
||||
"sha256": "06b0a042f2e121e954badb4fd78c9e2d4bc7ed6087eceb26ab559c23cf94334f",
|
||||
"dest": "third_party/spirv-tools"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -14,13 +14,9 @@
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/KDAB/KDDockWidgets.git",
|
||||
"tag": "v2.2.1",
|
||||
"commit": "3aaccddc00a11a643e0959a24677838993de15ac",
|
||||
"tag": "v2.3.0",
|
||||
"commit": "c38711026e17e34916dd82c6fcbdcc0d2342f541",
|
||||
"disable-submodules": true
|
||||
},
|
||||
{
|
||||
"type": "patch",
|
||||
"path": "../../../common/kddockwidgets-dodgy-include.patch"
|
||||
}
|
||||
],
|
||||
"cleanup": [
|
||||
|
||||
28
.github/workflows/scripts/linux/flatpak/modules/24-plutovg.json
vendored
Normal file
28
.github/workflows/scripts/linux/flatpak/modules/24-plutovg.json
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "plutovg",
|
||||
"buildsystem": "cmake-ninja",
|
||||
"builddir": true,
|
||||
"config-opts": [
|
||||
"-DBUILD_SHARED_LIBS=ON",
|
||||
"-DPLUTOVG_BUILD_EXAMPLES=OFF"
|
||||
],
|
||||
"build-options": {
|
||||
"strip": true
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/sammycage/plutovg.git",
|
||||
"tag": "v1.3.2",
|
||||
"commit": "5695a711dd1cff1f01fa6542f3fe6a15de082c63"
|
||||
}
|
||||
],
|
||||
"cleanup": [
|
||||
"/bin",
|
||||
"/include",
|
||||
"/lib/*.a",
|
||||
"/lib/*.la",
|
||||
"/lib/cmake",
|
||||
"/lib/pkgconfig"
|
||||
]
|
||||
}
|
||||
29
.github/workflows/scripts/linux/flatpak/modules/25-plutosvg.json
vendored
Normal file
29
.github/workflows/scripts/linux/flatpak/modules/25-plutosvg.json
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "plutosvg",
|
||||
"buildsystem": "cmake-ninja",
|
||||
"builddir": true,
|
||||
"config-opts": [
|
||||
"-DBUILD_SHARED_LIBS=ON",
|
||||
"-DPLUTOSVG_BUILD_EXAMPLES=OFF",
|
||||
"-DPLUTOSVG_ENABLE_FREETYPE=ON"
|
||||
],
|
||||
"build-options": {
|
||||
"strip": true
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/sammycage/plutosvg.git",
|
||||
"tag": "v0.0.7",
|
||||
"commit": "31f7d2675416cd777c8e86220b035364873b2a8b"
|
||||
}
|
||||
],
|
||||
"cleanup": [
|
||||
"/bin",
|
||||
"/include",
|
||||
"/lib/*.a",
|
||||
"/lib/*.la",
|
||||
"/lib/cmake",
|
||||
"/lib/pkgconfig"
|
||||
]
|
||||
}
|
||||
46
.github/workflows/scripts/linux/flatpak/modules/26-libpng.json
vendored
Normal file
46
.github/workflows/scripts/linux/flatpak/modules/26-libpng.json
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"name": "libpng",
|
||||
"buildsystem": "cmake-ninja",
|
||||
"builddir": true,
|
||||
"config-opts": [
|
||||
"-DPNG_TESTS=OFF",
|
||||
"-DPNG_STATIC=OFF",
|
||||
"-DPNG_SHARED=ON",
|
||||
"-DPNG_TOOLS=OFF"
|
||||
],
|
||||
"build-options": {
|
||||
"strip": true
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://downloads.sourceforge.net/project/libpng/libpng16/1.6.53/libpng-1.6.53.tar.xz",
|
||||
"sha256": "1d3fb8ccc2932d04aa3663e22ef5ef490244370f4e568d7850165068778d98d4"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://download.sourceforge.net/libpng-apng/libpng-1.6.53-apng.patch.gz",
|
||||
"dest-filename": "libpng-1.6.53-apng.patch.gz",
|
||||
"sha256": "452a1a290bd0cf18737fad0057dc17b7fdf10a73eda2d6d4f31ba04fda25ef2c"
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"commands":
|
||||
[
|
||||
"gunzip -f libpng-1.6.53-apng.patch.gz",
|
||||
"patch -p1 < \"libpng-1.6.53-apng.patch\""
|
||||
]
|
||||
}
|
||||
],
|
||||
"cleanup": [
|
||||
"/bin",
|
||||
"/include",
|
||||
"/lib/*.a",
|
||||
"/lib/*.la",
|
||||
"/lib/cmake",
|
||||
"/lib/libpng",
|
||||
"/lib/pkgconfig",
|
||||
"/share/man"
|
||||
]
|
||||
}
|
||||
|
||||
29
.github/workflows/scripts/linux/flatpak/modules/27-qtapng.json
vendored
Normal file
29
.github/workflows/scripts/linux/flatpak/modules/27-qtapng.json
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "qtapng",
|
||||
"buildsystem": "cmake-ninja",
|
||||
"builddir": true,
|
||||
"config-opts": [
|
||||
"-DCMAKE_PREFIX_PATH=\"${FLATPAK_DEST}\""
|
||||
],
|
||||
"build-options": {
|
||||
"strip": true
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/jurplel/QtApng.git",
|
||||
"tag": "1.3.0",
|
||||
"commit": "bd15516b281204e90ecd5b80b00d1274b062f5fc"
|
||||
},
|
||||
{
|
||||
"type": "patch",
|
||||
"path": "../../../common/qtapng-cmake.patch"
|
||||
}
|
||||
],
|
||||
"cleanup": [
|
||||
"/plugins"
|
||||
],
|
||||
"post-install": [
|
||||
"mv ${FLATPAK_DEST}/plugins/* ${FLATPAK_DEST}/bin/"
|
||||
]
|
||||
}
|
||||
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"app-id": "net.pcsx2.PCSX2",
|
||||
"runtime": "org.kde.Platform",
|
||||
"runtime-version": "6.8",
|
||||
"runtime-version": "6.10",
|
||||
"sdk": "org.kde.Sdk",
|
||||
"sdk-extensions": [
|
||||
"org.freedesktop.Sdk.Extension.llvm18"
|
||||
"org.freedesktop.Sdk.Extension.llvm20"
|
||||
],
|
||||
"add-extensions": {
|
||||
"org.freedesktop.Platform.ffmpeg-full": {
|
||||
"directory": "lib/ffmpeg",
|
||||
"version": "24.08",
|
||||
"version": "25.08",
|
||||
"add-ld-path": ".",
|
||||
"autodownload": true
|
||||
}
|
||||
@@ -22,7 +22,8 @@
|
||||
"--socket=wayland",
|
||||
"--socket=fallback-x11",
|
||||
"--socket=pulseaudio",
|
||||
"--talk-name=org.freedesktop.ScreenSaver"
|
||||
"--talk-name=org.freedesktop.ScreenSaver",
|
||||
"--filesystem=xdg-run/gamescope-0:ro"
|
||||
],
|
||||
"modules": [
|
||||
"modules/10-libpcap.json",
|
||||
@@ -30,6 +31,10 @@
|
||||
"modules/21-libbacktrace.json",
|
||||
"modules/22-shaderc.json",
|
||||
"modules/23-kddockwidgets.json",
|
||||
"modules/24-plutovg.json",
|
||||
"modules/25-plutosvg.json",
|
||||
"modules/26-libpng.json",
|
||||
"modules/27-qtapng.json",
|
||||
{
|
||||
"name": "pcsx2",
|
||||
"buildsystem": "cmake-ninja",
|
||||
@@ -43,10 +48,11 @@
|
||||
"cxxflags": "",
|
||||
"cxxflags-override": true,
|
||||
"config-opts": [
|
||||
"-DCMAKE_PREFIX_PATH=\"${FLATPAK_DEST}\"",
|
||||
"-DCMAKE_BUILD_TYPE=Release",
|
||||
"-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON",
|
||||
"-DCMAKE_C_COMPILER=/usr/lib/sdk/llvm18/bin/clang",
|
||||
"-DCMAKE_CXX_COMPILER=/usr/lib/sdk/llvm18/bin/clang++",
|
||||
"-DCMAKE_C_COMPILER=/usr/lib/sdk/llvm20/bin/clang",
|
||||
"-DCMAKE_CXX_COMPILER=/usr/lib/sdk/llvm20/bin/clang++",
|
||||
"-DCMAKE_EXE_LINKER_FLAGS_INIT=-fuse-ld=lld",
|
||||
"-DCMAKE_MODULE_LINKER_FLAGS_INIT=-fuse-ld=lld",
|
||||
"-DCMAKE_SHARED_LINKER_FLAGS_INIT=-fuse-ld=lld",
|
||||
|
||||
@@ -12,12 +12,24 @@ GIT_DATE=$(git log -1 --pretty=%cd --date=iso8601)
|
||||
GIT_VERSION=$(git tag --points-at HEAD)
|
||||
GIT_HASH=$(git rev-parse HEAD)
|
||||
|
||||
if [[ "${GIT_VERSION}" == "" ]]; then
|
||||
# In the odd event that we run this script before the release gets tagged.
|
||||
GIT_VERSION=$(git describe --tags)
|
||||
if [[ "${GIT_VERSION}" == "" ]]; then
|
||||
GIT_VERSION=$(git rev-parse HEAD)
|
||||
fi
|
||||
if [[ -z "${GIT_VERSION}" ]]; then
|
||||
if git branch -r --contains HEAD | grep -q 'origin/master'; then
|
||||
# Our master doesn't have a tagged commit
|
||||
# This happens when the commit is "ci skip"
|
||||
# abbrev so we have just the latest tag
|
||||
# ie v2.3.420 (Yes, that's the current master at the time of writing)
|
||||
GIT_VERSION=$(git describe --tags --abbrev=0)
|
||||
else
|
||||
# We are probably building a PR
|
||||
# Keep the short SHA in the version
|
||||
# ie v2.3.420-1-g10dc1a2da
|
||||
GIT_VERSION=$(git describe --tags)
|
||||
fi
|
||||
|
||||
if [[ -z "${GIT_VERSION}" ]]; then
|
||||
# Fallback to raw commit hash
|
||||
GIT_VERSION=$(git rev-parse HEAD)
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "GIT_DATE: ${GIT_DATE}"
|
||||
|
||||
@@ -11,7 +11,7 @@ merge_binaries() {
|
||||
"
|
||||
pushd "$X86DIR"
|
||||
for X86BIN in $(find . -type f \( -name '*.dylib' -o -name '*.a' -o -perm +111 \)); do
|
||||
if file "$X86DIR/$X86BIN" | grep "Mach-O " >/dev/null; then
|
||||
if file "$X86DIR/$X86BIN" | grep "Mach-O.*x86_64" >/dev/null; then
|
||||
ARMBIN="${ARMDIR}/${X86BIN}"
|
||||
echo "Merge $ARMBIN to $X86BIN..."
|
||||
lipo -create "$X86BIN" "$ARMBIN" -o "$X86BIN"
|
||||
@@ -38,23 +38,26 @@ if [ "${INSTALLDIR:0:1}" != "/" ]; then
|
||||
INSTALLDIR="$PWD/$INSTALLDIR"
|
||||
fi
|
||||
|
||||
FREETYPE=2.13.3
|
||||
HARFBUZZ=10.0.1
|
||||
SDL=SDL3-3.2.8
|
||||
FREETYPE=2.14.1
|
||||
HARFBUZZ=12.2.0
|
||||
SDL=SDL3-3.2.26
|
||||
ZSTD=1.5.7
|
||||
LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
|
||||
LIBPNG=1.6.45
|
||||
LIBJPEGTURBO=3.1.0
|
||||
LIBWEBP=1.5.0
|
||||
FFMPEG=6.0
|
||||
LZ4=1.10.0
|
||||
LIBPNG=1.6.53
|
||||
LIBJPEGTURBO=3.1.2
|
||||
LIBWEBP=1.6.0
|
||||
FFMPEG=8.0
|
||||
MOLTENVK=1.2.9
|
||||
QT=6.7.3
|
||||
KDDOCKWIDGETS=2.2.1
|
||||
QT=6.10.1
|
||||
QTAPNG=1.3.0
|
||||
KDDOCKWIDGETS=2.4.0
|
||||
PLUTOVG=1.3.2
|
||||
PLUTOSVG=0.0.7
|
||||
|
||||
SHADERC=2024.1
|
||||
SHADERC_GLSLANG=142052fa30f9eca191aa9dcf65359fcaed09eeec
|
||||
SHADERC_SPIRVHEADERS=5e3ad389ee56fca27c9705d093ae5387ce404df4
|
||||
SHADERC_SPIRVTOOLS=dd4b663e13c07fea4fbb3f70c1c91c86731099f7
|
||||
SHADERC=2025.4
|
||||
SHADERC_GLSLANG=7a47e2531cb334982b2a2dd8513dca0a3de4373d
|
||||
SHADERC_SPIRVHEADERS=b824a462d4256d720bebb40e78b9eb8f78bbb305
|
||||
SHADERC_SPIRVTOOLS=971a7b6e8d7740035bbff089bbbf9f42951ecfd5
|
||||
|
||||
mkdir -p deps-build
|
||||
cd deps-build
|
||||
@@ -75,26 +78,30 @@ CMAKE_ARCH_ARM64=-DCMAKE_OSX_ARCHITECTURES="arm64"
|
||||
CMAKE_ARCH_UNIVERSAL=-DCMAKE_OSX_ARCHITECTURES="x86_64;arm64"
|
||||
|
||||
cat > SHASUMS <<EOF
|
||||
0550350666d427c74daeb85d5ac7bb353acba5f76956395995311a9c6f063289 freetype-$FREETYPE.tar.xz
|
||||
e7358ea86fe10fb9261931af6f010d4358dac64f7074420ca9bc94aae2bdd542 harfbuzz-$HARFBUZZ.tar.gz
|
||||
13388fabb361de768ecdf2b65e52bb27d1054cae6ccb6942ba926e378e00db03 $SDL.tar.gz
|
||||
32427e8c471ac095853212a37aef816c60b42052d4d9e48230bab3bdf2936ccc freetype-$FREETYPE.tar.xz
|
||||
f63fc519f150465bd0bdafcdf3d0e9c23474f4c474171cd515ea1b3a72c081fb harfbuzz-$HARFBUZZ.tar.gz
|
||||
dad488474a51a0b01d547cd2834893d6299328d2e30f479a3564088b5476bae2 $SDL.tar.gz
|
||||
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
|
||||
0728800155f3ed0a0c87e03addbd30ecbe374f7b080678bbca1506051d50dec3 $LZ4.tar.gz
|
||||
926485350139ffb51ef69760db35f78846c805fef3d59bfdcb2fba704663f370 libpng-$LIBPNG.tar.xz
|
||||
7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c libwebp-$LIBWEBP.tar.gz
|
||||
9564c72b1dfd1d6fe6274c5f95a8d989b59854575d4bbee44ade7bc17aa9bc93 libjpeg-turbo-$LIBJPEGTURBO.tar.gz
|
||||
57be87c22d9b49c112b6d24bc67d42508660e6b718b3db89c44e47e289137082 ffmpeg-$FFMPEG.tar.xz
|
||||
537512904744b35e232912055ccf8ec66d768639ff3abe5788d90d792ec5f48b lz4-$LZ4.tar.gz
|
||||
1d3fb8ccc2932d04aa3663e22ef5ef490244370f4e568d7850165068778d98d4 libpng-$LIBPNG.tar.xz
|
||||
e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 libwebp-$LIBWEBP.tar.gz
|
||||
452a1a290bd0cf18737fad0057dc17b7fdf10a73eda2d6d4f31ba04fda25ef2c libpng-$LIBPNG-apng.patch.gz
|
||||
8f0012234b464ce50890c490f18194f913a7b1f4e6a03d6644179fa0f867d0cf libjpeg-turbo-$LIBJPEGTURBO.tar.gz
|
||||
b2751fccb6cc4c77708113cd78b561059b6fa904b24162fa0be2d60273d27b8e ffmpeg-$FFMPEG.tar.xz
|
||||
f415a09385030c6510a936155ce211f617c31506db5fbc563e804345f1ecf56e v$MOLTENVK.tar.gz
|
||||
8ccbb9ab055205ac76632c9eeddd1ed6fc66936fc56afc2ed0fd5d9e23da3097 qtbase-everywhere-src-$QT.tar.xz
|
||||
9fd58144081654c3373768dd96ead294023830927b14fe3d3c1ef641fb324753 qtimageformats-everywhere-src-$QT.tar.xz
|
||||
40142cb71fb1e07ad612bc361b67f5d54cd9367f9979ae6b86124a064deda06b qtsvg-everywhere-src-$QT.tar.xz
|
||||
f03bb7df619cd9ac9dba110e30b7bcab5dd88eb8bdc9cc752563b4367233203f qttools-everywhere-src-$QT.tar.xz
|
||||
dcc762acac043b9bb5e4d369b6d6f53e0ecfcf76a408fe0db5f7ef071c9d6dc8 qttranslations-everywhere-src-$QT.tar.xz
|
||||
eb3b5f0c16313d34f208d90c2fa1e588a23283eed63b101edd5422be6165d528 shaderc-$SHADERC.tar.gz
|
||||
aa27e4454ce631c5a17924ce0624eac736da19fc6f5a2ab15a6c58da7b36950f shaderc-glslang-$SHADERC_GLSLANG.tar.gz
|
||||
5d866ce34a4b6908e262e5ebfffc0a5e11dd411640b5f24c85a80ad44c0d4697 shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz
|
||||
03ee1a2c06f3b61008478f4abe9423454e53e580b9488b47c8071547c6a9db47 shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz
|
||||
8693e06abee0c88517d8480b22647702a51a0708f3c876ed5385d9a4e356e1a5 KDDockWidgets-$KDDOCKWIDGETS.tar.gz
|
||||
5a6226f7e23db51fdc3223121eba53f3f5447cf0cc4d6cb82a3a2df7a65d265d qtbase-everywhere-src-$QT.tar.xz
|
||||
498eabdf2381db96f808942b3e3c765f6360fe6c0e9961f0a45ff7a4c68d7a72 qtimageformats-everywhere-src-$QT.tar.xz
|
||||
c02f355a58f3bbcf404a628bf488b6aeb2d84a94c269afdb86f6e529343ab01f qtsvg-everywhere-src-$QT.tar.xz
|
||||
8148408380ffea03101a26305c812b612ea30dbc07121e58707601522404d49b qttools-everywhere-src-$QT.tar.xz
|
||||
8e49a2df88a12c376a479ae7bd272a91cf57ebb4e7c0cf7341b3565df99d2314 qttranslations-everywhere-src-$QT.tar.xz
|
||||
f1d3be3489f758efe1a8f12118a212febbe611aa670af32e0159fa3c1feab2a6 QtApng-$QTAPNG.tar.gz
|
||||
8a89fb6612ace8954470aae004623374a8fc8b7a34a4277bee5527173b064faf shaderc-$SHADERC.tar.gz
|
||||
272d2725b140e09e85b96eecdc59c2e00c1a14cda2301767e1bf3c363a44b931 shaderc-glslang-$SHADERC_GLSLANG.tar.gz
|
||||
c693867f10a7760ef1bcf85419d51783586768cc2c601d03841bc6a8b2554b9c shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz
|
||||
06b0a042f2e121e954badb4fd78c9e2d4bc7ed6087eceb26ab559c23cf94334f shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz
|
||||
51dbf24fe72e43dd7cb9a289d3cab47112010f1a2ed69b6fc8ac0dff31991ed2 KDDockWidgets-$KDDOCKWIDGETS.tar.gz
|
||||
7bd4e79ce18b1d47517e7e91fbb7cf19d4f01942804a519bc7c0bf32b6325dd5 plutovg-$PLUTOVG.tar.gz
|
||||
78561b571ac224030cdc450ca2986b4de915c2ba7616004a6d71a379bffd15f3 plutosvg-$PLUTOSVG.tar.gz
|
||||
EOF
|
||||
|
||||
curl -C - -L \
|
||||
@@ -102,22 +109,26 @@ curl -C - -L \
|
||||
-o "harfbuzz-$HARFBUZZ.tar.gz" "https://github.com/harfbuzz/harfbuzz/archive/refs/tags/$HARFBUZZ.tar.gz" \
|
||||
-O "https://libsdl.org/release/$SDL.tar.gz" \
|
||||
-O "https://github.com/facebook/zstd/releases/download/v$ZSTD/zstd-$ZSTD.tar.gz" \
|
||||
-O "https://github.com/lz4/lz4/archive/$LZ4.tar.gz" \
|
||||
-O "https://github.com/lz4/lz4/releases/download/v$LZ4/lz4-$LZ4.tar.gz" \
|
||||
-O "https://downloads.sourceforge.net/project/libpng/libpng16/$LIBPNG/libpng-$LIBPNG.tar.xz" \
|
||||
-O "https://download.sourceforge.net/libpng-apng/libpng-$LIBPNG-apng.patch.gz" \
|
||||
-O "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/$LIBJPEGTURBO/libjpeg-turbo-$LIBJPEGTURBO.tar.gz" \
|
||||
-O "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-$LIBWEBP.tar.gz" \
|
||||
-O "https://ffmpeg.org/releases/ffmpeg-$FFMPEG.tar.xz" \
|
||||
-O "https://github.com/KhronosGroup/MoltenVK/archive/refs/tags/v$MOLTENVK.tar.gz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtbase-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtimageformats-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtsvg-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qttools-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qttranslations-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qtbase-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qtimageformats-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qtsvg-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qttools-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qttranslations-everywhere-src-$QT.tar.xz" \
|
||||
-o "QtApng-$QTAPNG.tar.gz" "https://github.com/jurplel/QtApng/archive/refs/tags/$QTAPNG.tar.gz" \
|
||||
-o "shaderc-$SHADERC.tar.gz" "https://github.com/google/shaderc/archive/refs/tags/v$SHADERC.tar.gz" \
|
||||
-o "shaderc-glslang-$SHADERC_GLSLANG.tar.gz" "https://github.com/KhronosGroup/glslang/archive/$SHADERC_GLSLANG.tar.gz" \
|
||||
-o "shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz" "https://github.com/KhronosGroup/SPIRV-Headers/archive/$SHADERC_SPIRVHEADERS.tar.gz" \
|
||||
-o "shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz" "https://github.com/KhronosGroup/SPIRV-Tools/archive/$SHADERC_SPIRVTOOLS.tar.gz" \
|
||||
-o "KDDockWidgets-$KDDOCKWIDGETS.tar.gz" "https://github.com/KDAB/KDDockWidgets/archive/v$KDDOCKWIDGETS.tar.gz"
|
||||
-o "KDDockWidgets-$KDDOCKWIDGETS.tar.gz" "https://github.com/KDAB/KDDockWidgets/archive/v$KDDOCKWIDGETS.tar.gz" \
|
||||
-o "plutovg-$PLUTOVG.tar.gz" "https://github.com/sammycage/plutovg/archive/v$PLUTOVG.tar.gz" \
|
||||
-o "plutosvg-$PLUTOSVG.tar.gz" "https://github.com/sammycage/plutosvg/archive/v$PLUTOSVG.tar.gz"
|
||||
|
||||
shasum -a 256 --check SHASUMS
|
||||
|
||||
@@ -181,7 +192,7 @@ cd ..
|
||||
|
||||
echo "Installing LZ4..."
|
||||
rm -fr "lz4-$LZ4"
|
||||
tar xf "$LZ4.tar.gz"
|
||||
tar xf "lz4-$LZ4.tar.gz"
|
||||
cd "lz4-$LZ4"
|
||||
cmake "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_X64" -DBUILD_SHARED_LIBS=ON -DLZ4_BUILD_CLI=OFF -DLZ4_BUILD_LEGACY_LZ4C=OFF -B build-dir build/cmake
|
||||
make -C build-dir "-j$NPROCS"
|
||||
@@ -194,7 +205,9 @@ cd ..
|
||||
echo "Installing libpng..."
|
||||
rm -fr "libpng-$LIBPNG"
|
||||
tar xf "libpng-$LIBPNG.tar.xz"
|
||||
gunzip -d -f "libpng-$LIBPNG-apng.patch.gz"
|
||||
cd "libpng-$LIBPNG"
|
||||
patch -p1 < "../libpng-$LIBPNG-apng.patch"
|
||||
cmake "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_X64" -DBUILD_SHARED_LIBS=ON -DPNG_TESTS=OFF -DPNG_FRAMEWORK=OFF -B build
|
||||
make -C build "-j$NPROCS"
|
||||
cmake "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_ARM64" -DBUILD_SHARED_LIBS=ON -DPNG_TESTS=OFF -DPNG_FRAMEWORK=OFF -DPNG_ARM_NEON=on -B build-arm64
|
||||
@@ -207,8 +220,11 @@ echo "Installing libjpegturbo..."
|
||||
rm -fr "libjpeg-turbo-$LIBJPEGTURBO"
|
||||
tar xf "libjpeg-turbo-$LIBJPEGTURBO.tar.gz"
|
||||
cd "libjpeg-turbo-$LIBJPEGTURBO"
|
||||
cmake "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_ARM64" -DENABLE_STATIC=OFF -DENABLE_SHARED=ON -B build-arm64
|
||||
cmake "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_X64" -DENABLE_STATIC=OFF -DENABLE_SHARED=ON -B build
|
||||
make -C build "-j$NPROCS"
|
||||
cmake "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_ARM64" -DENABLE_STATIC=OFF -DENABLE_SHARED=ON -B build-arm64
|
||||
make -C build-arm64 "-j$NPROCS"
|
||||
merge_binaries $(realpath build) $(realpath build-arm64)
|
||||
make -C build install
|
||||
cd ..
|
||||
|
||||
@@ -269,6 +285,10 @@ echo "Installing Qt Base..."
|
||||
rm -fr "qtbase-everywhere-src-$QT"
|
||||
tar xf "qtbase-everywhere-src-$QT.tar.xz"
|
||||
cd "qtbase-everywhere-src-$QT"
|
||||
|
||||
# Patch Qt to support macOS 11
|
||||
patch -p1 < "$SCRIPTDIR/qt-macos11compat.patch"
|
||||
|
||||
# since we don't have a direct reference to QtSvg, it doesn't deployed directly from the main binary
|
||||
# (only indirectly from iconengines), and the libqsvg.dylib imageformat plugin does not get deployed.
|
||||
# We could run macdeployqt twice, but that's even more janky than patching it.
|
||||
@@ -304,7 +324,7 @@ tar xf "qtsvg-everywhere-src-$QT.tar.xz"
|
||||
cd "qtsvg-everywhere-src-$QT"
|
||||
mkdir build
|
||||
cd build
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_UNIVERSAL"
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_UNIVERSAL" -DQT_GENERATE_SBOM=OFF
|
||||
make "-j$NPROCS"
|
||||
make install
|
||||
cd ../..
|
||||
@@ -315,7 +335,7 @@ tar xf "qtimageformats-everywhere-src-$QT.tar.xz"
|
||||
cd "qtimageformats-everywhere-src-$QT"
|
||||
mkdir build
|
||||
cd build
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_UNIVERSAL" -DFEATURE_system_webp=ON
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_UNIVERSAL" -DQT_GENERATE_SBOM=OFF -DFEATURE_system_webp=ON
|
||||
make "-j$NPROCS"
|
||||
make install
|
||||
cd ../..
|
||||
@@ -326,7 +346,7 @@ tar xf "qttools-everywhere-src-$QT.tar.xz"
|
||||
cd "qttools-everywhere-src-$QT"
|
||||
mkdir build
|
||||
cd build
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_UNIVERSAL" -DFEATURE_assistant=OFF -DFEATURE_clang=OFF -DFEATURE_designer=OFF -DFEATURE_kmap2qmap=OFF -DFEATURE_pixeltool=OFF -DFEATURE_pkg_config=OFF -DFEATURE_qev=OFF -DFEATURE_qtattributionsscanner=OFF -DFEATURE_qtdiag=OFF -DFEATURE_qtplugininfo=OFF
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_UNIVERSAL" -DQT_GENERATE_SBOM=OFF -DFEATURE_assistant=OFF -DFEATURE_clang=OFF -DFEATURE_designer=OFF -DFEATURE_kmap2qmap=OFF -DFEATURE_pixeltool=OFF -DFEATURE_pkg_config=OFF -DFEATURE_qev=OFF -DFEATURE_qtattributionsscanner=OFF -DFEATURE_qtdiag=OFF -DFEATURE_qtplugininfo=OFF
|
||||
make "-j$NPROCS"
|
||||
make install
|
||||
cd ../..
|
||||
@@ -355,19 +375,46 @@ tar xf "qttranslations-everywhere-src-$QT.tar.xz"
|
||||
cd "qttranslations-everywhere-src-$QT"
|
||||
mkdir build
|
||||
cd build
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_UNIVERSAL"
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_UNIVERSAL" -DQT_GENERATE_SBOM=OFF
|
||||
make "-j$NPROCS"
|
||||
make install
|
||||
cd ../..
|
||||
|
||||
echo "Building Qt APNG..."
|
||||
rm -fr "QtApng-$QTAPNG"
|
||||
tar xf "QtApng-$QTAPNG.tar.gz"
|
||||
cd "QtApng-$QTAPNG"
|
||||
patch -p1 < "$SCRIPTDIR/../common/qtapng-cmake.patch"
|
||||
cmake "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_UNIVERSAL" -B build
|
||||
make -C build "-j$NPROCS"
|
||||
make -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building KDDockWidgets..."
|
||||
rm -fr "KDDockWidgets-$KDDOCKWIDGETS"
|
||||
tar xf "KDDockWidgets-$KDDOCKWIDGETS.tar.gz"
|
||||
cd "KDDockWidgets-$KDDOCKWIDGETS"
|
||||
patch -p1 < "$SCRIPTDIR/../common/kddockwidgets-dodgy-include.patch"
|
||||
cmake "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_UNIVERSAL" -DKDDockWidgets_QT6=true -DKDDockWidgets_EXAMPLES=false -DKDDockWidgets_FRONTENDS=qtwidgets -B build
|
||||
cmake --build build --parallel
|
||||
cmake --install build
|
||||
make -C build "-j$NPROCS"
|
||||
make -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building PlutoVG..."
|
||||
rm -fr "plutovg-$PLUTOVG"
|
||||
tar xf "plutovg-$PLUTOVG.tar.gz"
|
||||
cd "plutovg-$PLUTOVG"
|
||||
cmake "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_UNIVERSAL" -DBUILD_SHARED_LIBS=ON -DPLUTOVG_BUILD_EXAMPLES=OFF -B build
|
||||
make -C build "-j$NPROCS"
|
||||
make -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building PlutoSVG..."
|
||||
rm -fr "plutosvg-$PLUTOSVG"
|
||||
tar xf "plutosvg-$PLUTOSVG.tar.gz"
|
||||
cd "plutosvg-$PLUTOSVG"
|
||||
cmake "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_UNIVERSAL" -DBUILD_SHARED_LIBS=ON -DPLUTOSVG_ENABLE_FREETYPE=ON -DPLUTOSVG_BUILD_EXAMPLES=OFF -B build
|
||||
make -C build "-j$NPROCS"
|
||||
make -C build install
|
||||
cd ..
|
||||
|
||||
echo "Cleaning up..."
|
||||
|
||||
@@ -20,23 +20,26 @@ if [ "${INSTALLDIR:0:1}" != "/" ]; then
|
||||
INSTALLDIR="$PWD/$INSTALLDIR"
|
||||
fi
|
||||
|
||||
FREETYPE=2.13.3
|
||||
HARFBUZZ=10.0.1
|
||||
SDL=SDL3-3.2.8
|
||||
FREETYPE=2.14.1
|
||||
HARFBUZZ=12.2.0
|
||||
SDL=SDL3-3.2.26
|
||||
ZSTD=1.5.7
|
||||
LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
|
||||
LIBPNG=1.6.45
|
||||
LIBJPEGTURBO=3.1.0
|
||||
LIBWEBP=1.5.0
|
||||
FFMPEG=6.0
|
||||
LZ4=1.10.0
|
||||
LIBPNG=1.6.53
|
||||
LIBJPEGTURBO=3.1.2
|
||||
LIBWEBP=1.6.0
|
||||
FFMPEG=8.0
|
||||
MOLTENVK=1.2.9
|
||||
QT=6.7.3
|
||||
KDDOCKWIDGETS=2.2.1
|
||||
QT=6.10.1
|
||||
QTAPNG=1.3.0
|
||||
KDDOCKWIDGETS=2.4.0
|
||||
PLUTOVG=1.3.2
|
||||
PLUTOSVG=0.0.7
|
||||
|
||||
SHADERC=2024.1
|
||||
SHADERC_GLSLANG=142052fa30f9eca191aa9dcf65359fcaed09eeec
|
||||
SHADERC_SPIRVHEADERS=5e3ad389ee56fca27c9705d093ae5387ce404df4
|
||||
SHADERC_SPIRVTOOLS=dd4b663e13c07fea4fbb3f70c1c91c86731099f7
|
||||
SHADERC=2025.4
|
||||
SHADERC_GLSLANG=7a47e2531cb334982b2a2dd8513dca0a3de4373d
|
||||
SHADERC_SPIRVHEADERS=b824a462d4256d720bebb40e78b9eb8f78bbb305
|
||||
SHADERC_SPIRVTOOLS=971a7b6e8d7740035bbff089bbbf9f42951ecfd5
|
||||
|
||||
mkdir -p deps-build
|
||||
cd deps-build
|
||||
@@ -51,30 +54,35 @@ CMAKE_COMMON=(
|
||||
-DCMAKE_PREFIX_PATH="$INSTALLDIR"
|
||||
-DCMAKE_INSTALL_PREFIX="$INSTALLDIR"
|
||||
-DCMAKE_OSX_ARCHITECTURES="x86_64"
|
||||
-DCMAKE_APPLE_SILICON_PROCESSOR="x86_64"
|
||||
-DCMAKE_INSTALL_NAME_DIR='$<INSTALL_PREFIX>/lib'
|
||||
)
|
||||
|
||||
cat > SHASUMS <<EOF
|
||||
0550350666d427c74daeb85d5ac7bb353acba5f76956395995311a9c6f063289 freetype-$FREETYPE.tar.xz
|
||||
e7358ea86fe10fb9261931af6f010d4358dac64f7074420ca9bc94aae2bdd542 harfbuzz-$HARFBUZZ.tar.gz
|
||||
13388fabb361de768ecdf2b65e52bb27d1054cae6ccb6942ba926e378e00db03 $SDL.tar.gz
|
||||
32427e8c471ac095853212a37aef816c60b42052d4d9e48230bab3bdf2936ccc freetype-$FREETYPE.tar.xz
|
||||
f63fc519f150465bd0bdafcdf3d0e9c23474f4c474171cd515ea1b3a72c081fb harfbuzz-$HARFBUZZ.tar.gz
|
||||
dad488474a51a0b01d547cd2834893d6299328d2e30f479a3564088b5476bae2 $SDL.tar.gz
|
||||
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
|
||||
0728800155f3ed0a0c87e03addbd30ecbe374f7b080678bbca1506051d50dec3 $LZ4.tar.gz
|
||||
926485350139ffb51ef69760db35f78846c805fef3d59bfdcb2fba704663f370 libpng-$LIBPNG.tar.xz
|
||||
7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c libwebp-$LIBWEBP.tar.gz
|
||||
9564c72b1dfd1d6fe6274c5f95a8d989b59854575d4bbee44ade7bc17aa9bc93 libjpeg-turbo-$LIBJPEGTURBO.tar.gz
|
||||
57be87c22d9b49c112b6d24bc67d42508660e6b718b3db89c44e47e289137082 ffmpeg-$FFMPEG.tar.xz
|
||||
537512904744b35e232912055ccf8ec66d768639ff3abe5788d90d792ec5f48b lz4-$LZ4.tar.gz
|
||||
1d3fb8ccc2932d04aa3663e22ef5ef490244370f4e568d7850165068778d98d4 libpng-$LIBPNG.tar.xz
|
||||
e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 libwebp-$LIBWEBP.tar.gz
|
||||
452a1a290bd0cf18737fad0057dc17b7fdf10a73eda2d6d4f31ba04fda25ef2c libpng-$LIBPNG-apng.patch.gz
|
||||
8f0012234b464ce50890c490f18194f913a7b1f4e6a03d6644179fa0f867d0cf libjpeg-turbo-$LIBJPEGTURBO.tar.gz
|
||||
b2751fccb6cc4c77708113cd78b561059b6fa904b24162fa0be2d60273d27b8e ffmpeg-$FFMPEG.tar.xz
|
||||
f415a09385030c6510a936155ce211f617c31506db5fbc563e804345f1ecf56e v$MOLTENVK.tar.gz
|
||||
8ccbb9ab055205ac76632c9eeddd1ed6fc66936fc56afc2ed0fd5d9e23da3097 qtbase-everywhere-src-$QT.tar.xz
|
||||
9fd58144081654c3373768dd96ead294023830927b14fe3d3c1ef641fb324753 qtimageformats-everywhere-src-$QT.tar.xz
|
||||
40142cb71fb1e07ad612bc361b67f5d54cd9367f9979ae6b86124a064deda06b qtsvg-everywhere-src-$QT.tar.xz
|
||||
f03bb7df619cd9ac9dba110e30b7bcab5dd88eb8bdc9cc752563b4367233203f qttools-everywhere-src-$QT.tar.xz
|
||||
dcc762acac043b9bb5e4d369b6d6f53e0ecfcf76a408fe0db5f7ef071c9d6dc8 qttranslations-everywhere-src-$QT.tar.xz
|
||||
eb3b5f0c16313d34f208d90c2fa1e588a23283eed63b101edd5422be6165d528 shaderc-$SHADERC.tar.gz
|
||||
aa27e4454ce631c5a17924ce0624eac736da19fc6f5a2ab15a6c58da7b36950f shaderc-glslang-$SHADERC_GLSLANG.tar.gz
|
||||
5d866ce34a4b6908e262e5ebfffc0a5e11dd411640b5f24c85a80ad44c0d4697 shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz
|
||||
03ee1a2c06f3b61008478f4abe9423454e53e580b9488b47c8071547c6a9db47 shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz
|
||||
8693e06abee0c88517d8480b22647702a51a0708f3c876ed5385d9a4e356e1a5 KDDockWidgets-$KDDOCKWIDGETS.tar.gz
|
||||
5a6226f7e23db51fdc3223121eba53f3f5447cf0cc4d6cb82a3a2df7a65d265d qtbase-everywhere-src-$QT.tar.xz
|
||||
498eabdf2381db96f808942b3e3c765f6360fe6c0e9961f0a45ff7a4c68d7a72 qtimageformats-everywhere-src-$QT.tar.xz
|
||||
c02f355a58f3bbcf404a628bf488b6aeb2d84a94c269afdb86f6e529343ab01f qtsvg-everywhere-src-$QT.tar.xz
|
||||
8148408380ffea03101a26305c812b612ea30dbc07121e58707601522404d49b qttools-everywhere-src-$QT.tar.xz
|
||||
8e49a2df88a12c376a479ae7bd272a91cf57ebb4e7c0cf7341b3565df99d2314 qttranslations-everywhere-src-$QT.tar.xz
|
||||
f1d3be3489f758efe1a8f12118a212febbe611aa670af32e0159fa3c1feab2a6 QtApng-$QTAPNG.tar.gz
|
||||
8a89fb6612ace8954470aae004623374a8fc8b7a34a4277bee5527173b064faf shaderc-$SHADERC.tar.gz
|
||||
272d2725b140e09e85b96eecdc59c2e00c1a14cda2301767e1bf3c363a44b931 shaderc-glslang-$SHADERC_GLSLANG.tar.gz
|
||||
c693867f10a7760ef1bcf85419d51783586768cc2c601d03841bc6a8b2554b9c shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz
|
||||
06b0a042f2e121e954badb4fd78c9e2d4bc7ed6087eceb26ab559c23cf94334f shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz
|
||||
51dbf24fe72e43dd7cb9a289d3cab47112010f1a2ed69b6fc8ac0dff31991ed2 KDDockWidgets-$KDDOCKWIDGETS.tar.gz
|
||||
7bd4e79ce18b1d47517e7e91fbb7cf19d4f01942804a519bc7c0bf32b6325dd5 plutovg-$PLUTOVG.tar.gz
|
||||
78561b571ac224030cdc450ca2986b4de915c2ba7616004a6d71a379bffd15f3 plutosvg-$PLUTOSVG.tar.gz
|
||||
EOF
|
||||
|
||||
curl -L \
|
||||
@@ -82,22 +90,26 @@ curl -L \
|
||||
-o "harfbuzz-$HARFBUZZ.tar.gz" "https://github.com/harfbuzz/harfbuzz/archive/refs/tags/$HARFBUZZ.tar.gz" \
|
||||
-O "https://libsdl.org/release/$SDL.tar.gz" \
|
||||
-O "https://github.com/facebook/zstd/releases/download/v$ZSTD/zstd-$ZSTD.tar.gz" \
|
||||
-O "https://github.com/lz4/lz4/archive/$LZ4.tar.gz" \
|
||||
-O "https://github.com/lz4/lz4/releases/download/v$LZ4/lz4-$LZ4.tar.gz" \
|
||||
-O "https://downloads.sourceforge.net/project/libpng/libpng16/$LIBPNG/libpng-$LIBPNG.tar.xz" \
|
||||
-O "https://download.sourceforge.net/libpng-apng/libpng-$LIBPNG-apng.patch.gz" \
|
||||
-O "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/$LIBJPEGTURBO/libjpeg-turbo-$LIBJPEGTURBO.tar.gz" \
|
||||
-O "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-$LIBWEBP.tar.gz" \
|
||||
-O "https://ffmpeg.org/releases/ffmpeg-$FFMPEG.tar.xz" \
|
||||
-O "https://github.com/KhronosGroup/MoltenVK/archive/refs/tags/v$MOLTENVK.tar.gz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtbase-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtimageformats-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtsvg-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qttools-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qttranslations-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qtbase-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qtimageformats-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qtsvg-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qttools-everywhere-src-$QT.tar.xz" \
|
||||
-O "https://download.qt.io/archive/qt/${QT%.*}/$QT/submodules/qttranslations-everywhere-src-$QT.tar.xz" \
|
||||
-o "QtApng-$QTAPNG.tar.gz" "https://github.com/jurplel/QtApng/archive/refs/tags/$QTAPNG.tar.gz" \
|
||||
-o "shaderc-$SHADERC.tar.gz" "https://github.com/google/shaderc/archive/refs/tags/v$SHADERC.tar.gz" \
|
||||
-o "shaderc-glslang-$SHADERC_GLSLANG.tar.gz" "https://github.com/KhronosGroup/glslang/archive/$SHADERC_GLSLANG.tar.gz" \
|
||||
-o "shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz" "https://github.com/KhronosGroup/SPIRV-Headers/archive/$SHADERC_SPIRVHEADERS.tar.gz" \
|
||||
-o "shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz" "https://github.com/KhronosGroup/SPIRV-Tools/archive/$SHADERC_SPIRVTOOLS.tar.gz" \
|
||||
-o "KDDockWidgets-$KDDOCKWIDGETS.tar.gz" "https://github.com/KDAB/KDDockWidgets/archive/v$KDDOCKWIDGETS.tar.gz"
|
||||
-o "KDDockWidgets-$KDDOCKWIDGETS.tar.gz" "https://github.com/KDAB/KDDockWidgets/archive/v$KDDOCKWIDGETS.tar.gz" \
|
||||
-o "plutovg-$PLUTOVG.tar.gz" "https://github.com/sammycage/plutovg/archive/v$PLUTOVG.tar.gz" \
|
||||
-o "plutosvg-$PLUTOSVG.tar.gz" "https://github.com/sammycage/plutosvg/archive/v$PLUTOSVG.tar.gz"
|
||||
|
||||
shasum -a 256 --check SHASUMS
|
||||
|
||||
@@ -140,7 +152,7 @@ cd ..
|
||||
|
||||
echo "Installing LZ4..."
|
||||
rm -fr "lz4-$LZ4"
|
||||
tar xf "$LZ4.tar.gz"
|
||||
tar xf "lz4-$LZ4.tar.gz"
|
||||
cd "lz4-$LZ4"
|
||||
cmake "${CMAKE_COMMON[@]}" -DBUILD_SHARED_LIBS=ON -DLZ4_BUILD_CLI=OFF -DLZ4_BUILD_LEGACY_LZ4C=OFF -B build-dir build/cmake
|
||||
make -C build-dir "-j$NPROCS"
|
||||
@@ -150,7 +162,9 @@ cd ..
|
||||
echo "Installing libpng..."
|
||||
rm -fr "libpng-$LIBPNG"
|
||||
tar xf "libpng-$LIBPNG.tar.xz"
|
||||
gunzip -d -f "libpng-$LIBPNG-apng.patch.gz"
|
||||
cd "libpng-$LIBPNG"
|
||||
patch -p1 < "../libpng-$LIBPNG-apng.patch"
|
||||
cmake "${CMAKE_COMMON[@]}" -DBUILD_SHARED_LIBS=ON -DPNG_TESTS=OFF -DPNG_FRAMEWORK=OFF -B build
|
||||
make -C build "-j$NPROCS"
|
||||
make -C build install
|
||||
@@ -220,26 +234,15 @@ rm -fr "qtbase-everywhere-src-$QT"
|
||||
tar xf "qtbase-everywhere-src-$QT.tar.xz"
|
||||
cd "qtbase-everywhere-src-$QT"
|
||||
|
||||
# Patch Qt to support macOS 11
|
||||
patch -p1 < "$SCRIPTDIR/qt-macos11compat.patch"
|
||||
|
||||
# since we don't have a direct reference to QtSvg, it doesn't deployed directly from the main binary
|
||||
# (only indirectly from iconengines), and the libqsvg.dylib imageformat plugin does not get deployed.
|
||||
# We could run macdeployqt twice, but that's even more janky than patching it.
|
||||
|
||||
# https://github.com/qt/qtbase/commit/7b018629c3c3ab23665bf1da00c43c1546042035
|
||||
# The QProcess default wait time of 30s may be too short in e.g. CI environments where processes may be blocked
|
||||
# for a longer time waiting for CPU or IO.
|
||||
|
||||
patch -u src/tools/macdeployqt/shared/shared.cpp <<EOF
|
||||
--- shared.cpp
|
||||
+++ shared.cpp
|
||||
@@ -152,7 +152,7 @@
|
||||
LogDebug() << " inspecting" << binaryPath;
|
||||
QProcess otool;
|
||||
otool.start("otool", QStringList() << "-L" << binaryPath);
|
||||
- otool.waitForFinished();
|
||||
+ otool.waitForFinished(-1);
|
||||
|
||||
if (otool.exitStatus() != QProcess::NormalExit || otool.exitCode() != 0) {
|
||||
LogError() << otool.readAllStandardError();
|
||||
@@ -1122,14 +1122,8 @@
|
||||
addPlugins(QStringLiteral("networkinformation"));
|
||||
}
|
||||
@@ -258,7 +261,7 @@ patch -u src/tools/macdeployqt/shared/shared.cpp <<EOF
|
||||
|
||||
// Platforminputcontext plugins if QtGui is in use
|
||||
EOF
|
||||
cmake -B build "${CMAKE_COMMON[@]}" -DFEATURE_dbus=OFF -DFEATURE_framework=OFF -DFEATURE_icu=OFF -DFEATURE_opengl=OFF -DFEATURE_sql=OFF -DFEATURE_gssapi=OFF -DFEATURE_system_png=ON -DFEATURE_system_jpeg=ON -DFEATURE_system_zlib=ON -DFEATURE_system_freetype=ON -DFEATURE_system_harfbuzz=ON
|
||||
cmake -B build "${CMAKE_COMMON[@]}" -DCMAKE_BUILD_TYPE=MinSizeRel -DFEATURE_dbus=OFF -DFEATURE_framework=OFF -DFEATURE_icu=OFF -DFEATURE_opengl=OFF -DFEATURE_sql=OFF -DFEATURE_gssapi=OFF -DFEATURE_system_png=ON -DFEATURE_system_jpeg=ON -DFEATURE_system_zlib=ON -DFEATURE_system_freetype=ON -DFEATURE_system_harfbuzz=ON
|
||||
make -C build "-j$NPROCS"
|
||||
make -C build install
|
||||
cd ..
|
||||
@@ -269,7 +272,7 @@ tar xf "qtsvg-everywhere-src-$QT.tar.xz"
|
||||
cd "qtsvg-everywhere-src-$QT"
|
||||
mkdir build
|
||||
cd build
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- "${CMAKE_COMMON[@]}"
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- "${CMAKE_COMMON[@]}" -DQT_GENERATE_SBOM=OFF
|
||||
make "-j$NPROCS"
|
||||
make install
|
||||
cd ../..
|
||||
@@ -280,7 +283,7 @@ tar xf "qtimageformats-everywhere-src-$QT.tar.xz"
|
||||
cd "qtimageformats-everywhere-src-$QT"
|
||||
mkdir build
|
||||
cd build
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- "${CMAKE_COMMON[@]}" -DFEATURE_system_webp=ON
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- "${CMAKE_COMMON[@]}" -DQT_GENERATE_SBOM=OFF -DFEATURE_system_webp=ON
|
||||
make "-j$NPROCS"
|
||||
make install
|
||||
cd ../..
|
||||
@@ -291,7 +294,7 @@ tar xf "qttools-everywhere-src-$QT.tar.xz"
|
||||
cd "qttools-everywhere-src-$QT"
|
||||
mkdir build
|
||||
cd build
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- "${CMAKE_COMMON[@]}" -DFEATURE_assistant=OFF -DFEATURE_clang=OFF -DFEATURE_designer=ON -DFEATURE_kmap2qmap=OFF -DFEATURE_pixeltool=OFF -DFEATURE_pkg_config=OFF -DFEATURE_qev=OFF -DFEATURE_qtattributionsscanner=OFF -DFEATURE_qtdiag=OFF -DFEATURE_qtplugininfo=OFF
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- "${CMAKE_COMMON[@]}" -DQT_GENERATE_SBOM=OFF -DFEATURE_assistant=OFF -DFEATURE_clang=OFF -DFEATURE_designer=ON -DFEATURE_kmap2qmap=OFF -DFEATURE_pixeltool=OFF -DFEATURE_pkg_config=OFF -DFEATURE_qev=OFF -DFEATURE_qtattributionsscanner=OFF -DFEATURE_qtdiag=OFF -DFEATURE_qtplugininfo=OFF
|
||||
make "-j$NPROCS"
|
||||
make install
|
||||
cd ../..
|
||||
@@ -320,21 +323,48 @@ tar xf "qttranslations-everywhere-src-$QT.tar.xz"
|
||||
cd "qttranslations-everywhere-src-$QT"
|
||||
mkdir build
|
||||
cd build
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- "${CMAKE_COMMON[@]}"
|
||||
"$INSTALLDIR/bin/qt-configure-module" .. -- "${CMAKE_COMMON[@]}" -DQT_GENERATE_SBOM=OFF
|
||||
make "-j$NPROCS"
|
||||
make install
|
||||
cd ../..
|
||||
|
||||
echo "Building Qt APNG..."
|
||||
rm -fr "QtApng-$QTAPNG"
|
||||
tar xf "QtApng-$QTAPNG.tar.gz"
|
||||
cd "QtApng-$QTAPNG"
|
||||
patch -p1 < "$SCRIPTDIR/../common/qtapng-cmake.patch"
|
||||
cmake "${CMAKE_COMMON[@]}" -B build
|
||||
make -C build "-j$NPROCS"
|
||||
make -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building KDDockWidgets..."
|
||||
rm -fr "KDDockWidgets-$KDDOCKWIDGETS"
|
||||
tar xf "KDDockWidgets-$KDDOCKWIDGETS.tar.gz"
|
||||
cd "KDDockWidgets-$KDDOCKWIDGETS"
|
||||
patch -p1 < "$SCRIPTDIR/../common/kddockwidgets-dodgy-include.patch"
|
||||
cmake "${CMAKE_COMMON[@]}" -DKDDockWidgets_QT6=true -DKDDockWidgets_EXAMPLES=false -DKDDockWidgets_FRONTENDS=qtwidgets -B build
|
||||
make -C build "-j$NPROCS"
|
||||
make -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building PlutoVG..."
|
||||
rm -fr "plutovg-$PLUTOVG"
|
||||
tar xf "plutovg-$PLUTOVG.tar.gz"
|
||||
cd "plutovg-$PLUTOVG"
|
||||
cmake "${CMAKE_COMMON[@]}" -DBUILD_SHARED_LIBS=ON -DPLUTOVG_BUILD_EXAMPLES=OFF -B build
|
||||
make -C build "-j$NPROCS"
|
||||
make -C build install
|
||||
cd ..
|
||||
|
||||
echo "Building PlutoSVG..."
|
||||
rm -fr "plutosvg-$PLUTOSVG"
|
||||
tar xf "plutosvg-$PLUTOSVG.tar.gz"
|
||||
cd "plutosvg-$PLUTOSVG"
|
||||
cmake "${CMAKE_COMMON[@]}" -DBUILD_SHARED_LIBS=ON -DPLUTOSVG_ENABLE_FREETYPE=ON -DPLUTOSVG_BUILD_EXAMPLES=OFF -B build
|
||||
make -C build "-j$NPROCS"
|
||||
make -C build install
|
||||
cd ..
|
||||
|
||||
echo "Cleaning up..."
|
||||
cd ..
|
||||
rm -rf deps-build
|
||||
|
||||
116
.github/workflows/scripts/macos/qt-macos11compat.patch
vendored
Normal file
116
.github/workflows/scripts/macos/qt-macos11compat.patch
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
diff --git a/.cmake.conf b/.cmake.conf
|
||||
--- a/.cmake.conf
|
||||
+++ b/.cmake.conf
|
||||
@@ -51,7 +51,7 @@ set(QT_MAX_NEW_POLICY_CMAKE_VERSION_QT_APPLE "3.21")
|
||||
set(QT_SUPPORTED_MIN_MACOS_SDK_VERSION "14")
|
||||
set(QT_SUPPORTED_MAX_MACOS_SDK_VERSION "26")
|
||||
set(QT_SUPPORTED_MIN_MACOS_XCODE_VERSION "15")
|
||||
-set(QT_SUPPORTED_MIN_MACOS_VERSION "13")
|
||||
+set(QT_SUPPORTED_MIN_MACOS_VERSION "11")
|
||||
set(QT_SUPPORTED_MAX_MACOS_VERSION_TESTED "26")
|
||||
|
||||
set(QT_SUPPORTED_MIN_IOS_SDK_VERSION "17")
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -12,6 +12,10 @@ cmake_minimum_required(VERSION 3.16)
|
||||
# Get the repo version and CMake policy details
|
||||
include(.cmake.conf)
|
||||
|
||||
+if(APPLE)
|
||||
+ add_compile_options(-Werror=unguarded-availability-new)
|
||||
+endif()
|
||||
+
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/QtBaseHelpers.cmake)
|
||||
|
||||
qt_internal_check_if_path_has_symlinks("${CMAKE_BINARY_DIR}")
|
||||
diff --git a/src/corelib/global/qsysinfo.cpp b/src/corelib/global/qsysinfo.cpp
|
||||
--- a/src/corelib/global/qsysinfo.cpp
|
||||
+++ b/src/corelib/global/qsysinfo.cpp
|
||||
@@ -1027,7 +1027,7 @@ QByteArray QSysInfo::machineUniqueId()
|
||||
{
|
||||
#if defined(Q_OS_DARWIN) && __has_include(<IOKit/IOKitLib.h>)
|
||||
char uuid[UuidStringLen + 1];
|
||||
- io_service_t service = IOServiceGetMatchingService(kIOMainPortDefault, IOServiceMatching("IOPlatformExpertDevice"));
|
||||
+ io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice"));
|
||||
QCFString stringRef = (CFStringRef)IORegistryEntryCreateCFProperty(service, CFSTR(kIOPlatformUUIDKey), kCFAllocatorDefault, 0);
|
||||
CFStringGetCString(stringRef, uuid, sizeof(uuid), kCFStringEncodingMacRoman);
|
||||
return QByteArray(uuid);
|
||||
diff --git a/src/corelib/kernel/qcore_mac.mm b/src/corelib/kernel/qcore_mac.mm
|
||||
--- a/src/corelib/kernel/qcore_mac.mm
|
||||
+++ b/src/corelib/kernel/qcore_mac.mm
|
||||
@@ -367,7 +367,7 @@ bool qt_apple_runningWithLiquidGlass()
|
||||
return config;
|
||||
#endif
|
||||
|
||||
- QIOType<io_registry_entry_t> nvram = IORegistryEntryFromPath(kIOMainPortDefault, "IODeviceTree:/options");
|
||||
+ QIOType<io_registry_entry_t> nvram = IORegistryEntryFromPath(kIOMasterPortDefault, "IODeviceTree:/options");
|
||||
if (!nvram) {
|
||||
qWarning("Failed to locate NVRAM entry in IO registry");
|
||||
return {};
|
||||
diff --git a/src/gui/platform/darwin/qappleiconengine.mm b/src/gui/platform/darwin/qappleiconengine.mm
|
||||
--- a/src/gui/platform/darwin/qappleiconengine.mm
|
||||
+++ b/src/gui/platform/darwin/qappleiconengine.mm
|
||||
@@ -366,12 +366,16 @@
|
||||
weight:NSFontWeightRegular
|
||||
scale:NSImageSymbolScaleLarge];
|
||||
|
||||
+ auto *primaryColor = [NSColor colorWithSRGBRed:color.redF()
|
||||
+ green:color.greenF()
|
||||
+ blue:color.blueF()
|
||||
+ alpha:color.alphaF()];
|
||||
+
|
||||
+ if (@available(macOS 13, *)) {
|
||||
+
|
||||
// Apply tint color first, which switches the configuration to palette mode
|
||||
config = [config configurationByApplyingConfiguration:
|
||||
- [NSImageSymbolConfiguration configurationWithPaletteColors:@[
|
||||
- [NSColor colorWithSRGBRed:color.redF() green:color.greenF()
|
||||
- blue:color.blueF() alpha:color.alphaF()]
|
||||
- ]]];
|
||||
+ [NSImageSymbolConfiguration configurationWithPaletteColors:@[primaryColor]]];
|
||||
|
||||
// Then switch back to monochrome, as palette mode gives a different look
|
||||
// than monochrome, even with a single color.
|
||||
@@ -379,6 +383,18 @@
|
||||
[NSImageSymbolConfiguration configurationPreferringMonochrome]];
|
||||
|
||||
return [image imageWithSymbolConfiguration:config];
|
||||
+
|
||||
+ } else {
|
||||
+ NSImage *configuredImage = [image imageWithSymbolConfiguration:config];
|
||||
+ return [NSImage imageWithSize:configuredImage.size flipped:NO
|
||||
+ drawingHandler:^BOOL(NSRect) {
|
||||
+ [primaryColor set];
|
||||
+ NSRect imageRect = {NSZeroPoint, configuredImage.size};
|
||||
+ [configuredImage drawInRect:imageRect];
|
||||
+ NSRectFillUsingOperation(imageRect, NSCompositingOperationSourceIn);
|
||||
+ return YES;
|
||||
+ }];
|
||||
+ }
|
||||
}
|
||||
#elif defined(QT_PLATFORM_UIKIT)
|
||||
auto *configuredImage(const UIImage *image, const QColor &color)
|
||||
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
|
||||
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
|
||||
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
|
||||
@@ -323,6 +323,8 @@ a normal (not maximized or full screen) top-level window.
|
||||
m_view.safeAreaInsets.bottom
|
||||
};
|
||||
|
||||
+ if (@available(macOS 12, *)) {
|
||||
+
|
||||
// The screen's safe area insets represent the distances from the screen's
|
||||
// edges at which content isn't obscured. The view's safe area margins do
|
||||
// not include the screen's insets automatically, so we need to manually
|
||||
@@ -355,6 +357,10 @@ a normal (not maximized or full screen) top-level window.
|
||||
};
|
||||
|
||||
return (screenSafeAreaMargins | viewSafeAreaMargins).toMargins();
|
||||
+
|
||||
+ } else {
|
||||
+ return viewSafeAreaMargins.toMargins();
|
||||
+ }
|
||||
}
|
||||
|
||||
void QCocoaWindow::updateSafeAreaMarginsIfNeeded()
|
||||
@@ -66,7 +66,7 @@ const embed = new MessageEmbed()
|
||||
.setDescription("To download the latest or previous builds, [visit the official downloads page](https://pcsx2.net/downloads/).")
|
||||
.addFields(
|
||||
{ name: 'Version', value: releaseInfo.tag_name, inline: true },
|
||||
{ name: 'Installation Steps', value: '[See Here](https://github.com/PCSX2/pcsx2/wiki/Nightly-Build-Usage-Guide)', inline: true },
|
||||
{ name: 'Installation Steps', value: '[See Here](https://pcsx2.net/docs/category/setup)', inline: true },
|
||||
{ name: 'Included Changes', value: releaseInfo.body, inline: false }
|
||||
);
|
||||
console.log(embed);
|
||||
|
||||
411
.github/workflows/scripts/releases/generate-release-notes/package-lock.json
generated
vendored
411
.github/workflows/scripts/releases/generate-release-notes/package-lock.json
generated
vendored
@@ -9,123 +9,11 @@
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@octokit/plugin-retry": "^3.0.9",
|
||||
"@octokit/plugin-throttling": "^3.5.2",
|
||||
"@octokit/plugin-throttling": "^9.6.0",
|
||||
"@octokit/rest": "^21.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/auth-token": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
|
||||
"integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/core": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz",
|
||||
"integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@octokit/auth-token": "^2.4.4",
|
||||
"@octokit/graphql": "^4.5.8",
|
||||
"@octokit/request": "^5.6.0",
|
||||
"@octokit/request-error": "^2.0.5",
|
||||
"@octokit/types": "^6.0.3",
|
||||
"before-after-hook": "^2.2.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/endpoint": {
|
||||
"version": "6.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
|
||||
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/graphql": {
|
||||
"version": "4.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
|
||||
"integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@octokit/request": "^5.6.0",
|
||||
"@octokit/types": "^6.0.3",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/openapi-types": {
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.1.0.tgz",
|
||||
"integrity": "sha512-dWZfYvCCdjZzDYA3lIAMF72Q0jld8xidqCq5Ryw09eBJXZdcM6he0vWBTvw/b5UnGYqexxOyHWgfrsTlUJL3Gw=="
|
||||
},
|
||||
"node_modules/@octokit/plugin-retry": {
|
||||
"version": "3.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-3.0.9.tgz",
|
||||
"integrity": "sha512-r+fArdP5+TG6l1Rv/C9hVoty6tldw6cE2pRHNGmFPdyfrc696R6JjrQ3d7HdVqGwuzfyrcaLAKD7K8TX8aehUQ==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"bottleneck": "^2.15.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-throttling": {
|
||||
"version": "3.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-3.5.2.tgz",
|
||||
"integrity": "sha512-Eu7kfJxU8vmHqWGNszWpg+GVp2tnAfax3XQV5CkYPEE69C+KvInJXW9WajgSeW+cxYe0UVdouzCtcreGNuJo7A==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.1",
|
||||
"bottleneck": "^2.15.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": "^3.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request": {
|
||||
"version": "5.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.2.tgz",
|
||||
"integrity": "sha512-je66CvSEVf0jCpRISxkUcCa0UkxmFs6eGDRSbfJtAVwbLH5ceqF+YEyC8lj8ystKyZTy8adWr0qmkY52EfOeLA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@octokit/endpoint": "^6.0.1",
|
||||
"@octokit/request-error": "^2.1.0",
|
||||
"@octokit/types": "^6.16.1",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"node-fetch": "^2.6.1",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request-error": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
|
||||
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"deprecation": "^2.0.0",
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest": {
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-21.1.1.tgz",
|
||||
"integrity": "sha512-sTQV7va0IUVZcntzy1q3QqPm/r8rWtDCqpRAmb8eXXnKkjoQEtFe3Nt5GTVsHft+R6jJoHeSiVLcgcvhtue/rg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/core": "^6.1.4",
|
||||
"@octokit/plugin-paginate-rest": "^11.4.2",
|
||||
"@octokit/plugin-request-log": "^5.3.1",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^13.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/auth-token": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-5.1.2.tgz",
|
||||
"integrity": "sha512-JcQDsBdg49Yky2w2ld20IHAlwr8d/d8N6NiOXbtuoPCqzbsiJgF633mVUw3x4mo0H5ypataQIX7SFu3yy44Mpw==",
|
||||
@@ -134,7 +22,7 @@
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/core": {
|
||||
"node_modules/@octokit/core": {
|
||||
"version": "6.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-6.1.4.tgz",
|
||||
"integrity": "sha512-lAS9k7d6I0MPN+gb9bKDt7X8SdxknYqAMh44S5L+lNqIN2NuV8nvv3g8rPp7MuRxcOpxpUIATWprO0C34a8Qmg==",
|
||||
@@ -152,7 +40,22 @@
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/endpoint": {
|
||||
"node_modules/@octokit/core/node_modules/@octokit/openapi-types": {
|
||||
"version": "24.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz",
|
||||
"integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/core/node_modules/@octokit/types": {
|
||||
"version": "13.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz",
|
||||
"integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^24.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/endpoint": {
|
||||
"version": "10.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.3.tgz",
|
||||
"integrity": "sha512-nBRBMpKPhQUxCsQQeW+rCJ/OPSMcj3g0nfHn01zGYZXuNDvvXudF/TYY6APj5THlurerpFN4a/dQAIAaM6BYhA==",
|
||||
@@ -165,7 +68,22 @@
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/graphql": {
|
||||
"node_modules/@octokit/endpoint/node_modules/@octokit/openapi-types": {
|
||||
"version": "24.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz",
|
||||
"integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/endpoint/node_modules/@octokit/types": {
|
||||
"version": "13.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz",
|
||||
"integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^24.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/graphql": {
|
||||
"version": "8.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-8.2.1.tgz",
|
||||
"integrity": "sha512-n57hXtOoHrhwTWdvhVkdJHdhTv0JstjDbDRhJfwIRNfFqmSo1DaK/mD2syoNUoLCyqSjBpGAKOG0BuwF392slw==",
|
||||
@@ -179,6 +97,139 @@
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/graphql/node_modules/@octokit/openapi-types": {
|
||||
"version": "24.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz",
|
||||
"integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/graphql/node_modules/@octokit/types": {
|
||||
"version": "13.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz",
|
||||
"integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^24.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/openapi-types": {
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.1.0.tgz",
|
||||
"integrity": "sha512-dWZfYvCCdjZzDYA3lIAMF72Q0jld8xidqCq5Ryw09eBJXZdcM6he0vWBTvw/b5UnGYqexxOyHWgfrsTlUJL3Gw=="
|
||||
},
|
||||
"node_modules/@octokit/plugin-retry": {
|
||||
"version": "3.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-3.0.9.tgz",
|
||||
"integrity": "sha512-r+fArdP5+TG6l1Rv/C9hVoty6tldw6cE2pRHNGmFPdyfrc696R6JjrQ3d7HdVqGwuzfyrcaLAKD7K8TX8aehUQ==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"bottleneck": "^2.15.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-throttling": {
|
||||
"version": "9.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-9.6.0.tgz",
|
||||
"integrity": "sha512-zn7m1N3vpJDaVzLqjCRdJ0cRzNiekHEWPi8Ww9xyPNrDt5PStHvVE0eR8wy4RSU8Eg7YO8MHyvn6sv25EGVhhg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^13.7.0",
|
||||
"bottleneck": "^2.15.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": "^6.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-throttling/node_modules/@octokit/openapi-types": {
|
||||
"version": "24.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz",
|
||||
"integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/plugin-throttling/node_modules/@octokit/types": {
|
||||
"version": "13.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz",
|
||||
"integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^24.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request": {
|
||||
"version": "9.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-9.2.2.tgz",
|
||||
"integrity": "sha512-dZl0ZHx6gOQGcffgm1/Sf6JfEpmh34v3Af2Uci02vzUYz6qEN6zepoRtmybWXIGXFIK8K9ylE3b+duCWqhArtg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/endpoint": "^10.1.3",
|
||||
"@octokit/request-error": "^6.1.7",
|
||||
"@octokit/types": "^13.6.2",
|
||||
"fast-content-type-parse": "^2.0.0",
|
||||
"universal-user-agent": "^7.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request-error": {
|
||||
"version": "6.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.7.tgz",
|
||||
"integrity": "sha512-69NIppAwaauwZv6aOzb+VVLwt+0havz9GT5YplkeJv7fG7a40qpLt/yZKyiDxAhgz0EtgNdNcb96Z0u+Zyuy2g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^13.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request-error/node_modules/@octokit/openapi-types": {
|
||||
"version": "24.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz",
|
||||
"integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/request-error/node_modules/@octokit/types": {
|
||||
"version": "13.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz",
|
||||
"integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^24.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request/node_modules/@octokit/openapi-types": {
|
||||
"version": "24.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz",
|
||||
"integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/request/node_modules/@octokit/types": {
|
||||
"version": "13.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz",
|
||||
"integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^24.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest": {
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-21.1.1.tgz",
|
||||
"integrity": "sha512-sTQV7va0IUVZcntzy1q3QqPm/r8rWtDCqpRAmb8eXXnKkjoQEtFe3Nt5GTVsHft+R6jJoHeSiVLcgcvhtue/rg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/core": "^6.1.4",
|
||||
"@octokit/plugin-paginate-rest": "^11.4.2",
|
||||
"@octokit/plugin-request-log": "^5.3.1",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^13.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
@@ -227,34 +278,6 @@
|
||||
"@octokit/core": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/request": {
|
||||
"version": "9.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-9.2.2.tgz",
|
||||
"integrity": "sha512-dZl0ZHx6gOQGcffgm1/Sf6JfEpmh34v3Af2Uci02vzUYz6qEN6zepoRtmybWXIGXFIK8K9ylE3b+duCWqhArtg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/endpoint": "^10.1.3",
|
||||
"@octokit/request-error": "^6.1.7",
|
||||
"@octokit/types": "^13.6.2",
|
||||
"fast-content-type-parse": "^2.0.0",
|
||||
"universal-user-agent": "^7.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/request-error": {
|
||||
"version": "6.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.7.tgz",
|
||||
"integrity": "sha512-69NIppAwaauwZv6aOzb+VVLwt+0havz9GT5YplkeJv7fG7a40qpLt/yZKyiDxAhgz0EtgNdNcb96Z0u+Zyuy2g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^13.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
@@ -264,18 +287,6 @@
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/before-after-hook": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-3.0.2.tgz",
|
||||
"integrity": "sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/universal-user-agent": {
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz",
|
||||
"integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/@octokit/types": {
|
||||
"version": "6.33.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.33.0.tgz",
|
||||
@@ -285,22 +296,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/before-after-hook": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz",
|
||||
"integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==",
|
||||
"peer": true
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-3.0.2.tgz",
|
||||
"integrity": "sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/bottleneck": {
|
||||
"version": "2.19.5",
|
||||
"resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz",
|
||||
"integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw=="
|
||||
},
|
||||
"node_modules/deprecation": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
|
||||
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/fast-content-type-parse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-2.0.1.tgz",
|
||||
@@ -317,77 +322,11 @@
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/is-plain-object": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
||||
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/node-fetch": {
|
||||
"version": "2.6.7",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"encoding": "^0.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"encoding": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/universal-user-agent": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
|
||||
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||
"peer": true
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz",
|
||||
"integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==",
|
||||
"license": "ISC"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@octokit/plugin-retry": "^3.0.9",
|
||||
"@octokit/plugin-throttling": "^3.5.2",
|
||||
"@octokit/plugin-throttling": "^9.6.0",
|
||||
"@octokit/rest": "^21.1.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,45 +42,53 @@ echo INSTALLDIR=%INSTALLDIR%
|
||||
|
||||
cd "%BUILDDIR%"
|
||||
|
||||
set FREETYPE=2.13.3
|
||||
set HARFBUZZ=10.0.1
|
||||
set LIBJPEGTURBO=3.1.0
|
||||
set LIBPNG=1645
|
||||
set LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
|
||||
set QT=6.8.2
|
||||
set QTMINOR=6.8
|
||||
set SDL=SDL3-3.2.8
|
||||
set WEBP=1.5.0
|
||||
set FREETYPE=2.14.1
|
||||
set HARFBUZZ=12.2.0
|
||||
set LIBJPEGTURBO=3.1.2
|
||||
set LIBPNG=1653
|
||||
set LIBPNGLONG=1.6.53
|
||||
set SDL=SDL3-3.2.26
|
||||
set QT=6.10.1
|
||||
set QTMINOR=6.10
|
||||
set QTAPNG=1.3.0
|
||||
set LZ4=1.10.0
|
||||
set WEBP=1.6.0
|
||||
set ZLIB=1.3.1
|
||||
set ZLIBSHORT=131
|
||||
set ZSTD=1.5.7
|
||||
set KDDOCKWIDGETS=2.2.1
|
||||
set KDDOCKWIDGETS=2.4.0
|
||||
set PLUTOVG=1.3.2
|
||||
set PLUTOSVG=0.0.7
|
||||
|
||||
set SHADERC=2024.1
|
||||
set SHADERC_GLSLANG=142052fa30f9eca191aa9dcf65359fcaed09eeec
|
||||
set SHADERC_SPIRVHEADERS=5e3ad389ee56fca27c9705d093ae5387ce404df4
|
||||
set SHADERC_SPIRVTOOLS=dd4b663e13c07fea4fbb3f70c1c91c86731099f7
|
||||
set SHADERC=2025.4
|
||||
set SHADERC_GLSLANG=7a47e2531cb334982b2a2dd8513dca0a3de4373d
|
||||
set SHADERC_SPIRVHEADERS=b824a462d4256d720bebb40e78b9eb8f78bbb305
|
||||
set SHADERC_SPIRVTOOLS=971a7b6e8d7740035bbff089bbbf9f42951ecfd5
|
||||
|
||||
call :downloadfile "freetype-%FREETYPE%.tar.gz" https://sourceforge.net/projects/freetype/files/freetype2/%FREETYPE%/freetype-%FREETYPE%.tar.gz/download 5c3a8e78f7b24c20b25b54ee575d6daa40007a5f4eea2845861c3409b3021747 || goto error
|
||||
call :downloadfile "harfbuzz-%HARFBUZZ%.zip" https://github.com/harfbuzz/harfbuzz/archive/refs/tags/%HARFBUZZ%.zip 8adf9f5a4b6022aa2744f45c89ce347df46fea8403e99f01d650b11c417d0aa8 || goto error
|
||||
call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lpng1645.zip a66c4b1350b67776e90263e2550933067cd9ccbd318db489f84dcc0d2b033249 || goto error
|
||||
call :downloadfile "libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/%LIBJPEGTURBO%/libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" 9564c72b1dfd1d6fe6274c5f95a8d989b59854575d4bbee44ade7bc17aa9bc93 || goto error
|
||||
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" 7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c || goto error
|
||||
call :downloadfile "lz4-%LZ4%.zip" "https://github.com/lz4/lz4/archive/%LZ4%.zip" 0c33119688d6b180c7e760b0acd70059222389cfd581632623784bee27e51a31 || goto error
|
||||
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 7f8ff5c8246db4145301bc122601a5f8cef25ee2c326eddb3e88668849c61ddf || goto error
|
||||
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" 44087aec0caa4aa81437e787917d29d97536484a682a5d51ec035878e57c0b5c || goto error
|
||||
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 83c72b5dfad04854acf61d592e3f9cdc2ed894779aab8d0470d966715266caaf || goto error
|
||||
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 144d55e4d199793a76c53f19872633a79aec0314039f6f99b6a10b5be7a78fbf || goto error
|
||||
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" 102539447c1c76d206f24bcca2c911270cf53991548d9c3d7d0d01855f651e3b || goto error
|
||||
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 33ccac9f99a357ffd83cb2d7179a0c0ffcba85a14d23d86619d5dc9721ded42f || goto error
|
||||
call :downloadfile "zlib%ZLIBSHORT%.zip" "https://zlib.net/zlib%ZLIBSHORT%.zip" 72af66d44fcc14c22013b46b814d5d2514673dda3d115e64b690c1ad636e7b17 || goto error
|
||||
call :downloadfile "freetype-%FREETYPE%.tar.gz" https://sourceforge.net/projects/freetype/files/freetype2/%FREETYPE%/freetype-%FREETYPE%.tar.gz/download 174d9e53402e1bf9ec7277e22ec199ba3e55a6be2c0740cb18c0ee9850fc8c34 || goto error
|
||||
call :downloadfile "harfbuzz-%HARFBUZZ%.zip" https://github.com/harfbuzz/harfbuzz/archive/refs/tags/%HARFBUZZ%.zip 31490c781bacd2ce56862555b11c51c964977c39f14f51b817dfaecf0be089fe || goto error
|
||||
call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lpng1653.zip 140566abc64bb2320cb35f1d154d1cb3eb7174a12234d33bfdffb446bdc0a1d2 || goto error
|
||||
call :downloadfile "lpng%LIBPNG%-apng.patch.gz" https://download.sourceforge.net/libpng-apng/libpng-%LIBPNGLONG%-apng.patch.gz 452a1a290bd0cf18737fad0057dc17b7fdf10a73eda2d6d4f31ba04fda25ef2c || goto error
|
||||
call :downloadfile "libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/%LIBJPEGTURBO%/libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" 8f0012234b464ce50890c490f18194f913a7b1f4e6a03d6644179fa0f867d0cf || goto error
|
||||
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 || goto error
|
||||
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 739356eef1192fff9d641c320a8f5ef4a10506b8927def4b9ceb764c7e947369 || goto error
|
||||
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" c43f471a808b07fc541528410e94ce89c6745bdc1d744492e19911d35fbf7d33 || goto error
|
||||
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 2d828d8c999fdd18167937c071781c22321c643b04a106c714411c2356cdb26d || goto error
|
||||
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" ddd74a417d2397eb085d047a9b6ba52b76e748055817f728fe691f8456035d23 || goto error
|
||||
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" db8e49ed50912c3c064a4f9ada7791c09eccec5a8d53463a19608eaab17679f0 || goto error
|
||||
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 868eb651e395d48ade5932ef2c386e606e054eb5888ebe5284fbd8cb63ed935a || goto error
|
||||
call :downloadfile "QtApng-%QTAPNG%.zip" "https://github.com/jurplel/QtApng/archive/refs/tags/%QTAPNG%.zip" 5176082cdd468047a7eb1ec1f106b032f57df207aa318d559b29606b00d159ac || goto error
|
||||
call :downloadfile "lz4-%LZ4%.zip" "https://github.com/lz4/lz4/archive/refs/tags/v%LZ4%.zip" 3224b4c80f351f194984526ef396f6079bd6332dd9825c72ac0d7a37b3cdc565 || goto error
|
||||
call :downloadfile "zlib%ZLIBSHORT%.zip" "https://github.com/madler/zlib/releases/download/v%ZLIB%/zlib%ZLIBSHORT%.zip" 72af66d44fcc14c22013b46b814d5d2514673dda3d115e64b690c1ad636e7b17 || goto error
|
||||
call :downloadfile "zstd-%ZSTD%.zip" "https://github.com/facebook/zstd/archive/refs/tags/v%ZSTD%.zip" 7897bc5d620580d9b7cd3539c44b59d78f3657d33663fe97a145e07b4ebd69a4 || goto error
|
||||
call :downloadfile "KDDockWidgets-%KDDOCKWIDGETS%.zip" "https://github.com/KDAB/KDDockWidgets/archive/v2.2.1.zip" 78b5e242bf47476e150175b7de934ab84069459e151beb2d5ce84fd067138aa5 || goto error
|
||||
call :downloadfile "KDDockWidgets-%KDDOCKWIDGETS%.zip" "https://github.com/KDAB/KDDockWidgets/archive/v%KDDOCKWIDGETS%.zip" 47ddb48197872055f0adf8e90a7235f8a3b795ca1ee3a28ac2c504c673ae3806 || goto error
|
||||
call :downloadfile "plutovg-%PLUTOVG%.zip" "https://github.com/sammycage/plutovg/archive/v%PLUTOVG%.zip" 4fe4e48f28aa80171b2166d45c0976ab0f21eecedb52cd4c3ef73b5afb48fac9 || goto error
|
||||
call :downloadfile "plutosvg-%PLUTOSVG%.zip" "https://github.com/sammycage/plutosvg/archive/v%PLUTOSVG%.zip" 82dee2c57ad712bdd6d6d81d3e76249d89caa4b5a4214353660fd5adff12201a || goto error
|
||||
|
||||
call :downloadfile "shaderc-%SHADERC%.zip" "https://github.com/google/shaderc/archive/refs/tags/v%SHADERC%.zip" 6c9f42ed6bf42750f5369b089909abfdcf0101488b4a1f41116d5159d00af8e7 || goto error
|
||||
call :downloadfile "shaderc-glslang-%SHADERC_GLSLANG%.zip" "https://github.com/KhronosGroup/glslang/archive/%SHADERC_GLSLANG%.zip" 03ad8a6fa987af4653d0cfe6bdaed41bcf617f1366a151fb1574da75950cd3e8 || goto error
|
||||
call :downloadfile "shaderc-spirv-headers-%SHADERC_SPIRVHEADERS%.zip" "https://github.com/KhronosGroup/SPIRV-Headers/archive/%SHADERC_SPIRVHEADERS%.zip" fa59a54334feaba5702b9c25724c3f4746123865769b36dd5a28d9ef5e9d39ab || goto error
|
||||
call :downloadfile "shaderc-spirv-tools-%SHADERC_SPIRVTOOLS%.zip" "https://github.com/KhronosGroup/SPIRV-Tools/archive/%SHADERC_SPIRVTOOLS%.zip" bf385994c20293485b378c27dfdbd77a31b949deabccd9218a977f173eda9f6f || goto error
|
||||
call :downloadfile "shaderc-%SHADERC%.zip" "https://github.com/google/shaderc/archive/refs/tags/v%SHADERC%.zip" fab72d1a38eacea52710d18edb95dfd75db894ad869675d07a1eb26827da9b15 || goto error
|
||||
call :downloadfile "shaderc-glslang-%SHADERC_GLSLANG%.zip" "https://github.com/KhronosGroup/glslang/archive/%SHADERC_GLSLANG%.zip" 4a118247386ffba9160113f146f2189ba5abe3995db357114d7112ede6bd3cd1 || goto error
|
||||
call :downloadfile "shaderc-spirv-headers-%SHADERC_SPIRVHEADERS%.zip" "https://github.com/KhronosGroup/SPIRV-Headers/archive/%SHADERC_SPIRVHEADERS%.zip" 9a38cb3b14484f5038d78cd5df89404f2f5b389a6ad91f9f1df4ae71bb9490dc || goto error
|
||||
call :downloadfile "shaderc-spirv-tools-%SHADERC_SPIRVTOOLS%.zip" "https://github.com/KhronosGroup/SPIRV-Tools/archive/%SHADERC_SPIRVTOOLS%.zip" a26383c836a84fab5b03aed5d98e8e27d6c0a9cdbc3b0f462ccfe0a11a3d91ea || goto error
|
||||
|
||||
if %DEBUG%==1 (
|
||||
echo Building debug and release libraries...
|
||||
@@ -88,7 +96,7 @@ if %DEBUG%==1 (
|
||||
echo Building release libraries...
|
||||
)
|
||||
|
||||
set FORCEPDB=-DCMAKE_SHARED_LINKER_FLAGS_RELEASE="/DEBUG"
|
||||
set FORCEPDB=-DCMAKE_SHARED_LINKER_FLAGS_RELEASE="/DEBUG" -DCMAKE_SHARED_LINKER_FLAGS_MINSIZEREL="/DEBUG"
|
||||
set ARM64TOOLCHAIN=-DCMAKE_TOOLCHAIN_FILE="%SCRIPTDIR%\cmake-toolchain-windows-arm64.cmake"
|
||||
|
||||
echo Building Zlib...
|
||||
@@ -103,7 +111,10 @@ cd .. || goto error
|
||||
echo Building libpng...
|
||||
rmdir /S /Q "lpng%LIBPNG%"
|
||||
%SEVENZIP% x "lpng%LIBPNG%.zip" || goto error
|
||||
rem apng not in released libpng yet
|
||||
%SEVENZIP% x "lpng%LIBPNG%-apng.patch.gz" -aoa || goto error
|
||||
cd "lpng%LIBPNG%" || goto error
|
||||
%PATCH% -p1 < "../libpng-%LIBPNGLONG%-apng.patch" || goto error
|
||||
cmake %ARM64TOOLCHAIN% -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DBUILD_SHARED_LIBS=ON -DBUILD_SHARED_LIBS=ON -DPNG_TESTS=OFF -DPNG_STATIC=OFF -DPNG_SHARED=ON -DPNG_TOOLS=OFF -B build -G Ninja || goto error
|
||||
cmake --build build --parallel || goto error
|
||||
ninja -C build install || goto error
|
||||
@@ -186,7 +197,7 @@ cd .. || goto error
|
||||
if %DEBUG%==1 (
|
||||
set QTBUILDSPEC=-DCMAKE_CONFIGURATION_TYPES="Release;Debug" -G "Ninja Multi-Config"
|
||||
) else (
|
||||
set QTBUILDSPEC=-DCMAKE_BUILD_TYPE=Release -G Ninja
|
||||
set QTBUILDSPEC=-DCMAKE_BUILD_TYPE=MinSizeRel -G Ninja
|
||||
)
|
||||
|
||||
echo Building Qt base...
|
||||
@@ -242,12 +253,54 @@ cmake --build . --parallel || goto error
|
||||
ninja install || goto error
|
||||
cd ..\.. || goto error
|
||||
|
||||
if %DEBUG%==1 (
|
||||
set QTAPNGBUILDSPEC=-DCMAKE_CONFIGURATION_TYPES="Release;Debug" -DCMAKE_CROSS_CONFIGS=all -DCMAKE_DEFAULT_BUILD_TYPE=Release -DCMAKE_DEFAULT_CONFIGS=all -G "Ninja Multi-Config"
|
||||
) else (
|
||||
set QTAPNGBUILDSPEC=-DCMAKE_BUILD_TYPE=Release -G Ninja
|
||||
)
|
||||
|
||||
echo Building Qt APNG...
|
||||
rmdir /S /Q "QtApng-%QTAPNG%"
|
||||
%SEVENZIP% x "QtApng-%QTAPNG%.zip" || goto error
|
||||
cd "QtApng-%QTAPNG%" || goto error
|
||||
%PATCH% -p1 < "%SCRIPTDIR%\..\common\qtapng-cmake.patch" || goto error
|
||||
cmake -B build %ARM64TOOLCHAIN% -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" %FORCEPDB% %QTAPNGBUILDSPEC% || goto error
|
||||
cmake --build build --parallel || goto error
|
||||
ninja -C build install || goto error
|
||||
cd .. || goto error
|
||||
|
||||
if %DEBUG%==1 (
|
||||
set KDDOCKWIDGETSBUILDSPEC=-DCMAKE_CONFIGURATION_TYPES="Release;Debug" -DCMAKE_CROSS_CONFIGS=all -DCMAKE_DEFAULT_BUILD_TYPE=Release -DCMAKE_DEFAULT_CONFIGS=all -G "Ninja Multi-Config"
|
||||
) else (
|
||||
rem kddockwidgets slightly changes the name of the dll depending on if CMAKE_BUILD_TYPE or CMAKE_CONFIGURATION_TYPES is used
|
||||
rem The dll name being kddockwidgets-qt62.dll or kddockwidgets-qt62.dll respectively
|
||||
rem Always use CMAKE_CONFIGURATION_TYPES to give consistant naming
|
||||
set KDDOCKWIDGETSBUILDSPEC=-DCMAKE_CONFIGURATION_TYPES=Release -DCMAKE_CROSS_CONFIGS=all -DCMAKE_DEFAULT_BUILD_TYPE=Release -DCMAKE_DEFAULT_CONFIGS=Release -G "Ninja Multi-Config"
|
||||
)
|
||||
|
||||
echo "Building KDDockWidgets..."
|
||||
rmdir /S /Q "KDDockWidgets-%KDDOCKWIDGETS%"
|
||||
%SEVENZIP% x "KDDockWidgets-%KDDOCKWIDGETS%.zip" || goto error
|
||||
cd "KDDockWidgets-%KDDOCKWIDGETS%" || goto error
|
||||
%PATCH% -p1 < "%SCRIPTDIR%\..\common\kddockwidgets-dodgy-include.patch" || goto error
|
||||
cmake %ARM64TOOLCHAIN% -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DKDDockWidgets_QT6=true -DKDDockWidgets_EXAMPLES=false -DKDDockWidgets_FRONTENDS=qtwidgets -B build -G Ninja || goto error
|
||||
cmake -B build %ARM64TOOLCHAIN% -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DKDDockWidgets_QT6=true -DKDDockWidgets_EXAMPLES=false -DKDDockWidgets_FRONTENDS=qtwidgets %KDDOCKWIDGETSBUILDSPEC% || goto error
|
||||
cmake --build build --parallel || goto error
|
||||
ninja -C build install || goto error
|
||||
cd .. || goto error
|
||||
|
||||
echo "Building PlutoVG..."
|
||||
rmdir /S /Q "plutovg-%PLUTOVG%"
|
||||
%SEVENZIP% x "plutovg-%PLUTOVG%.zip" || goto error
|
||||
cd "plutovg-%PLUTOVG%" || goto error
|
||||
cmake %ARM64TOOLCHAIN% -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DBUILD_SHARED_LIBS=ON -DPLUTOVG_BUILD_EXAMPLES=OFF -B build -G Ninja || goto error
|
||||
cmake --build build --parallel || goto error
|
||||
ninja -C build install || goto error
|
||||
cd .. || goto error
|
||||
|
||||
echo "Building PlutoSVG..."
|
||||
rmdir /S /Q "plutosvg-%PLUTOSVG%"
|
||||
%SEVENZIP% x "plutosvg-%PLUTOSVG%.zip" || goto error
|
||||
cd "plutosvg-%PLUTOSVG%" || goto error
|
||||
cmake %ARM64TOOLCHAIN% -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DBUILD_SHARED_LIBS=ON -DPLUTOSVG_ENABLE_FREETYPE=ON -DPLUTOSVG_BUILD_EXAMPLES=OFF -B build -G Ninja || goto error
|
||||
cmake --build build --parallel || goto error
|
||||
ninja -C build install || goto error
|
||||
cd .. || goto error
|
||||
|
||||
@@ -40,45 +40,53 @@ set "PATH=%PATH%;%INSTALLDIR%\bin"
|
||||
|
||||
cd "%BUILDDIR%"
|
||||
|
||||
set FREETYPE=2.13.3
|
||||
set HARFBUZZ=10.0.1
|
||||
set LIBJPEGTURBO=3.1.0
|
||||
set LIBPNG=1645
|
||||
set LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
|
||||
set QT=6.8.2
|
||||
set QTMINOR=6.8
|
||||
set SDL=SDL3-3.2.8
|
||||
set WEBP=1.5.0
|
||||
set FREETYPE=2.14.1
|
||||
set HARFBUZZ=12.2.0
|
||||
set LIBJPEGTURBO=3.1.2
|
||||
set LIBPNG=1653
|
||||
set LIBPNGLONG=1.6.53
|
||||
set SDL=SDL3-3.2.26
|
||||
set QT=6.10.1
|
||||
set QTMINOR=6.10
|
||||
set QTAPNG=1.3.0
|
||||
set LZ4=1.10.0
|
||||
set WEBP=1.6.0
|
||||
set ZLIB=1.3.1
|
||||
set ZLIBSHORT=131
|
||||
set ZSTD=1.5.7
|
||||
set KDDOCKWIDGETS=2.2.1
|
||||
set KDDOCKWIDGETS=2.4.0
|
||||
set PLUTOVG=1.3.2
|
||||
set PLUTOSVG=0.0.7
|
||||
|
||||
set SHADERC=2024.1
|
||||
set SHADERC_GLSLANG=142052fa30f9eca191aa9dcf65359fcaed09eeec
|
||||
set SHADERC_SPIRVHEADERS=5e3ad389ee56fca27c9705d093ae5387ce404df4
|
||||
set SHADERC_SPIRVTOOLS=dd4b663e13c07fea4fbb3f70c1c91c86731099f7
|
||||
set SHADERC=2025.4
|
||||
set SHADERC_GLSLANG=7a47e2531cb334982b2a2dd8513dca0a3de4373d
|
||||
set SHADERC_SPIRVHEADERS=b824a462d4256d720bebb40e78b9eb8f78bbb305
|
||||
set SHADERC_SPIRVTOOLS=971a7b6e8d7740035bbff089bbbf9f42951ecfd5
|
||||
|
||||
call :downloadfile "freetype-%FREETYPE%.tar.gz" https://sourceforge.net/projects/freetype/files/freetype2/%FREETYPE%/freetype-%FREETYPE%.tar.gz/download 5c3a8e78f7b24c20b25b54ee575d6daa40007a5f4eea2845861c3409b3021747 || goto error
|
||||
call :downloadfile "harfbuzz-%HARFBUZZ%.zip" https://github.com/harfbuzz/harfbuzz/archive/refs/tags/%HARFBUZZ%.zip 8adf9f5a4b6022aa2744f45c89ce347df46fea8403e99f01d650b11c417d0aa8 || goto error
|
||||
call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lpng1645.zip a66c4b1350b67776e90263e2550933067cd9ccbd318db489f84dcc0d2b033249 || goto error
|
||||
call :downloadfile "libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/%LIBJPEGTURBO%/libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" 9564c72b1dfd1d6fe6274c5f95a8d989b59854575d4bbee44ade7bc17aa9bc93 || goto error
|
||||
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" 7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c || goto error
|
||||
call :downloadfile "lz4-%LZ4%.zip" "https://github.com/lz4/lz4/archive/%LZ4%.zip" 0c33119688d6b180c7e760b0acd70059222389cfd581632623784bee27e51a31 || goto error
|
||||
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 7f8ff5c8246db4145301bc122601a5f8cef25ee2c326eddb3e88668849c61ddf || goto error
|
||||
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" 44087aec0caa4aa81437e787917d29d97536484a682a5d51ec035878e57c0b5c || goto error
|
||||
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 83c72b5dfad04854acf61d592e3f9cdc2ed894779aab8d0470d966715266caaf || goto error
|
||||
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 144d55e4d199793a76c53f19872633a79aec0314039f6f99b6a10b5be7a78fbf || goto error
|
||||
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" 102539447c1c76d206f24bcca2c911270cf53991548d9c3d7d0d01855f651e3b || goto error
|
||||
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 33ccac9f99a357ffd83cb2d7179a0c0ffcba85a14d23d86619d5dc9721ded42f || goto error
|
||||
call :downloadfile "zlib%ZLIBSHORT%.zip" "https://zlib.net/zlib%ZLIBSHORT%.zip" 72af66d44fcc14c22013b46b814d5d2514673dda3d115e64b690c1ad636e7b17 || goto error
|
||||
call :downloadfile "freetype-%FREETYPE%.tar.gz" https://sourceforge.net/projects/freetype/files/freetype2/%FREETYPE%/freetype-%FREETYPE%.tar.gz/download 174d9e53402e1bf9ec7277e22ec199ba3e55a6be2c0740cb18c0ee9850fc8c34 || goto error
|
||||
call :downloadfile "harfbuzz-%HARFBUZZ%.zip" https://github.com/harfbuzz/harfbuzz/archive/refs/tags/%HARFBUZZ%.zip 31490c781bacd2ce56862555b11c51c964977c39f14f51b817dfaecf0be089fe || goto error
|
||||
call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lpng1653.zip 140566abc64bb2320cb35f1d154d1cb3eb7174a12234d33bfdffb446bdc0a1d2 || goto error
|
||||
call :downloadfile "lpng%LIBPNG%-apng.patch.gz" https://download.sourceforge.net/libpng-apng/libpng-%LIBPNGLONG%-apng.patch.gz 452a1a290bd0cf18737fad0057dc17b7fdf10a73eda2d6d4f31ba04fda25ef2c || goto error
|
||||
call :downloadfile "libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/%LIBJPEGTURBO%/libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" 8f0012234b464ce50890c490f18194f913a7b1f4e6a03d6644179fa0f867d0cf || goto error
|
||||
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" e4ab7009bf0629fd11982d4c2aa83964cf244cffba7347ecd39019a9e38c4564 || goto error
|
||||
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 739356eef1192fff9d641c320a8f5ef4a10506b8927def4b9ceb764c7e947369 || goto error
|
||||
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" c43f471a808b07fc541528410e94ce89c6745bdc1d744492e19911d35fbf7d33 || goto error
|
||||
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 2d828d8c999fdd18167937c071781c22321c643b04a106c714411c2356cdb26d || goto error
|
||||
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" ddd74a417d2397eb085d047a9b6ba52b76e748055817f728fe691f8456035d23 || goto error
|
||||
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" db8e49ed50912c3c064a4f9ada7791c09eccec5a8d53463a19608eaab17679f0 || goto error
|
||||
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 868eb651e395d48ade5932ef2c386e606e054eb5888ebe5284fbd8cb63ed935a || goto error
|
||||
call :downloadfile "QtApng-%QTAPNG%.zip" "https://github.com/jurplel/QtApng/archive/refs/tags/%QTAPNG%.zip" 5176082cdd468047a7eb1ec1f106b032f57df207aa318d559b29606b00d159ac || goto error
|
||||
call :downloadfile "lz4-%LZ4%.zip" "https://github.com/lz4/lz4/archive/refs/tags/v%LZ4%.zip" 3224b4c80f351f194984526ef396f6079bd6332dd9825c72ac0d7a37b3cdc565 || goto error
|
||||
call :downloadfile "zlib%ZLIBSHORT%.zip" "https://github.com/madler/zlib/releases/download/v%ZLIB%/zlib%ZLIBSHORT%.zip" 72af66d44fcc14c22013b46b814d5d2514673dda3d115e64b690c1ad636e7b17 || goto error
|
||||
call :downloadfile "zstd-%ZSTD%.zip" "https://github.com/facebook/zstd/archive/refs/tags/v%ZSTD%.zip" 7897bc5d620580d9b7cd3539c44b59d78f3657d33663fe97a145e07b4ebd69a4 || goto error
|
||||
call :downloadfile "KDDockWidgets-%KDDOCKWIDGETS%.zip" "https://github.com/KDAB/KDDockWidgets/archive/v2.2.1.zip" 78b5e242bf47476e150175b7de934ab84069459e151beb2d5ce84fd067138aa5 || goto error
|
||||
call :downloadfile "KDDockWidgets-%KDDOCKWIDGETS%.zip" "https://github.com/KDAB/KDDockWidgets/archive/v%KDDOCKWIDGETS%.zip" 47ddb48197872055f0adf8e90a7235f8a3b795ca1ee3a28ac2c504c673ae3806 || goto error
|
||||
call :downloadfile "plutovg-%PLUTOVG%.zip" "https://github.com/sammycage/plutovg/archive/v%PLUTOVG%.zip" 4fe4e48f28aa80171b2166d45c0976ab0f21eecedb52cd4c3ef73b5afb48fac9 || goto error
|
||||
call :downloadfile "plutosvg-%PLUTOSVG%.zip" "https://github.com/sammycage/plutosvg/archive/v%PLUTOSVG%.zip" 82dee2c57ad712bdd6d6d81d3e76249d89caa4b5a4214353660fd5adff12201a || goto error
|
||||
|
||||
call :downloadfile "shaderc-%SHADERC%.zip" "https://github.com/google/shaderc/archive/refs/tags/v%SHADERC%.zip" 6c9f42ed6bf42750f5369b089909abfdcf0101488b4a1f41116d5159d00af8e7 || goto error
|
||||
call :downloadfile "shaderc-glslang-%SHADERC_GLSLANG%.zip" "https://github.com/KhronosGroup/glslang/archive/%SHADERC_GLSLANG%.zip" 03ad8a6fa987af4653d0cfe6bdaed41bcf617f1366a151fb1574da75950cd3e8 || goto error
|
||||
call :downloadfile "shaderc-spirv-headers-%SHADERC_SPIRVHEADERS%.zip" "https://github.com/KhronosGroup/SPIRV-Headers/archive/%SHADERC_SPIRVHEADERS%.zip" fa59a54334feaba5702b9c25724c3f4746123865769b36dd5a28d9ef5e9d39ab || goto error
|
||||
call :downloadfile "shaderc-spirv-tools-%SHADERC_SPIRVTOOLS%.zip" "https://github.com/KhronosGroup/SPIRV-Tools/archive/%SHADERC_SPIRVTOOLS%.zip" bf385994c20293485b378c27dfdbd77a31b949deabccd9218a977f173eda9f6f || goto error
|
||||
call :downloadfile "shaderc-%SHADERC%.zip" "https://github.com/google/shaderc/archive/refs/tags/v%SHADERC%.zip" fab72d1a38eacea52710d18edb95dfd75db894ad869675d07a1eb26827da9b15 || goto error
|
||||
call :downloadfile "shaderc-glslang-%SHADERC_GLSLANG%.zip" "https://github.com/KhronosGroup/glslang/archive/%SHADERC_GLSLANG%.zip" 4a118247386ffba9160113f146f2189ba5abe3995db357114d7112ede6bd3cd1 || goto error
|
||||
call :downloadfile "shaderc-spirv-headers-%SHADERC_SPIRVHEADERS%.zip" "https://github.com/KhronosGroup/SPIRV-Headers/archive/%SHADERC_SPIRVHEADERS%.zip" 9a38cb3b14484f5038d78cd5df89404f2f5b389a6ad91f9f1df4ae71bb9490dc || goto error
|
||||
call :downloadfile "shaderc-spirv-tools-%SHADERC_SPIRVTOOLS%.zip" "https://github.com/KhronosGroup/SPIRV-Tools/archive/%SHADERC_SPIRVTOOLS%.zip" a26383c836a84fab5b03aed5d98e8e27d6c0a9cdbc3b0f462ccfe0a11a3d91ea || goto error
|
||||
|
||||
if %DEBUG%==1 (
|
||||
echo Building debug and release libraries...
|
||||
@@ -86,7 +94,7 @@ if %DEBUG%==1 (
|
||||
echo Building release libraries...
|
||||
)
|
||||
|
||||
set FORCEPDB=-DCMAKE_SHARED_LINKER_FLAGS_RELEASE="/DEBUG"
|
||||
set FORCEPDB=-DCMAKE_SHARED_LINKER_FLAGS_RELEASE="/DEBUG" -DCMAKE_MODULE_LINKER_FLAGS_RELEASE="/DEBUG" -DCMAKE_SHARED_LINKER_FLAGS_MINSIZEREL="/DEBUG" -DCMAKE_MODULE_LINKER_FLAGS_MINSIZEREL="/DEBUG"
|
||||
|
||||
echo Building Zlib...
|
||||
rmdir /S /Q "zlib-%ZLIB%"
|
||||
@@ -100,7 +108,10 @@ cd .. || goto error
|
||||
echo Building libpng...
|
||||
rmdir /S /Q "lpng%LIBPNG%"
|
||||
%SEVENZIP% x "lpng%LIBPNG%.zip" || goto error
|
||||
rem apng not in released libpng yet
|
||||
%SEVENZIP% x "lpng%LIBPNG%-apng.patch.gz" -aoa || goto error
|
||||
cd "lpng%LIBPNG%" || goto error
|
||||
%PATCH% -p1 < "../libpng-%LIBPNGLONG%-apng.patch" || goto error
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DBUILD_SHARED_LIBS=ON -DBUILD_SHARED_LIBS=ON -DPNG_TESTS=OFF -DPNG_STATIC=OFF -DPNG_SHARED=ON -DPNG_TOOLS=OFF -B build -G Ninja || goto error
|
||||
cmake --build build --parallel || goto error
|
||||
ninja -C build install || goto error
|
||||
@@ -183,7 +194,7 @@ cd .. || goto error
|
||||
if %DEBUG%==1 (
|
||||
set QTBUILDSPEC=-DCMAKE_CONFIGURATION_TYPES="Release;Debug" -G "Ninja Multi-Config"
|
||||
) else (
|
||||
set QTBUILDSPEC=-DCMAKE_BUILD_TYPE=Release -G Ninja
|
||||
set QTBUILDSPEC=-DCMAKE_BUILD_TYPE=MinSizeRel -G Ninja
|
||||
)
|
||||
|
||||
echo Building Qt base...
|
||||
@@ -194,9 +205,6 @@ cd "qtbase-everywhere-src-%QT%" || goto error
|
||||
rem Disable the PCRE2 JIT, it doesn't properly verify AVX2 support.
|
||||
%PATCH% -p1 < "%SCRIPTDIR%\qtbase-disable-pcre2-jit.patch" || goto error
|
||||
|
||||
rem Hackfix settings icon stretching
|
||||
%PATCH% -p1 < "%SCRIPTDIR%\qtbase-fix-icon-stretch.patch" || goto error
|
||||
|
||||
cmake -B build -DFEATURE_sql=OFF -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" %FORCEPDB% -DINPUT_gui=yes -DINPUT_widgets=yes -DINPUT_ssl=yes -DINPUT_openssl=no -DINPUT_schannel=yes -DFEATURE_system_png=ON -DFEATURE_system_jpeg=ON -DFEATURE_system_zlib=ON -DFEATURE_system_freetype=ON -DFEATURE_system_harfbuzz=ON %QTBUILDSPEC% || goto error
|
||||
cmake --build build --parallel || goto error
|
||||
ninja -C build install || goto error
|
||||
@@ -225,7 +233,7 @@ ninja install || goto error
|
||||
cd ..\.. || goto error
|
||||
|
||||
echo Building Qt Tools...
|
||||
rmdir /S /Q "qtimageformats-everywhere-src-%QT%"
|
||||
rmdir /S /Q "qttools-everywhere-src-%QT%"
|
||||
%SEVENZIP% x "qttools-everywhere-src-%QT%.zip" || goto error
|
||||
cd "qttools-everywhere-src-%QT%" || goto error
|
||||
mkdir build || goto error
|
||||
@@ -246,12 +254,54 @@ cmake --build . --parallel || goto error
|
||||
ninja install || goto error
|
||||
cd ..\.. || goto error
|
||||
|
||||
if %DEBUG%==1 (
|
||||
set QTAPNGBUILDSPEC=-DCMAKE_CONFIGURATION_TYPES="Release;Debug" -DCMAKE_CROSS_CONFIGS=all -DCMAKE_DEFAULT_BUILD_TYPE=Release -DCMAKE_DEFAULT_CONFIGS=all -G "Ninja Multi-Config"
|
||||
) else (
|
||||
set QTAPNGBUILDSPEC=-DCMAKE_BUILD_TYPE=Release -G Ninja
|
||||
)
|
||||
|
||||
echo Building Qt APNG...
|
||||
rmdir /S /Q "QtApng-%QTAPNG%"
|
||||
%SEVENZIP% x "QtApng-%QTAPNG%.zip" || goto error
|
||||
cd "QtApng-%QTAPNG%" || goto error
|
||||
%PATCH% -p1 < "%SCRIPTDIR%\..\common\qtapng-cmake.patch" || goto error
|
||||
cmake -B build -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" %FORCEPDB% %QTAPNGBUILDSPEC% || goto error
|
||||
cmake --build build --parallel || goto error
|
||||
ninja -C build install || goto error
|
||||
cd .. || goto error
|
||||
|
||||
if %DEBUG%==1 (
|
||||
set KDDOCKWIDGETSBUILDSPEC=-DCMAKE_CONFIGURATION_TYPES="Release;Debug" -DCMAKE_CROSS_CONFIGS=all -DCMAKE_DEFAULT_BUILD_TYPE=Release -DCMAKE_DEFAULT_CONFIGS=all -G "Ninja Multi-Config"
|
||||
) else (
|
||||
rem kddockwidgets slightly changes the name of the dll depending on if CMAKE_BUILD_TYPE or CMAKE_CONFIGURATION_TYPES is used
|
||||
rem The dll name being kddockwidgets-qt62.dll or kddockwidgets-qt6.dll respectively
|
||||
rem Always use CMAKE_CONFIGURATION_TYPES to give consistent naming
|
||||
set KDDOCKWIDGETSBUILDSPEC=-DCMAKE_CONFIGURATION_TYPES=Release -DCMAKE_CROSS_CONFIGS=all -DCMAKE_DEFAULT_BUILD_TYPE=Release -DCMAKE_DEFAULT_CONFIGS=Release -G "Ninja Multi-Config"
|
||||
)
|
||||
|
||||
echo "Building KDDockWidgets..."
|
||||
rmdir /S /Q "KDDockWidgets-%KDDOCKWIDGETS%"
|
||||
%SEVENZIP% x "KDDockWidgets-%KDDOCKWIDGETS%.zip" || goto error
|
||||
cd "KDDockWidgets-%KDDOCKWIDGETS%" || goto error
|
||||
%PATCH% -p1 < "%SCRIPTDIR%\..\common\kddockwidgets-dodgy-include.patch" || goto error
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DKDDockWidgets_QT6=true -DKDDockWidgets_EXAMPLES=false -DKDDockWidgets_FRONTENDS=qtwidgets -B build -G Ninja || goto error
|
||||
cmake -B build -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DKDDockWidgets_QT6=true -DKDDockWidgets_EXAMPLES=false -DKDDockWidgets_FRONTENDS=qtwidgets %KDDOCKWIDGETSBUILDSPEC% || goto error
|
||||
cmake --build build --parallel || goto error
|
||||
ninja -C build install || goto error
|
||||
cd .. || goto error
|
||||
|
||||
echo "Building PlutoVG..."
|
||||
rmdir /S /Q "plutovg-%PLUTOVG%"
|
||||
%SEVENZIP% x "plutovg-%PLUTOVG%.zip" || goto error
|
||||
cd "plutovg-%PLUTOVG%" || goto error
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DBUILD_SHARED_LIBS=ON -DPLUTOVG_BUILD_EXAMPLES=OFF -B build -G Ninja || goto error
|
||||
cmake --build build --parallel || goto error
|
||||
ninja -C build install || goto error
|
||||
cd .. || goto error
|
||||
|
||||
echo "Building PlutoSVG..."
|
||||
rmdir /S /Q "plutosvg-%PLUTOSVG%"
|
||||
%SEVENZIP% x "plutosvg-%PLUTOSVG%.zip" || goto error
|
||||
cd "plutosvg-%PLUTOSVG%" || goto error
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DBUILD_SHARED_LIBS=ON -DPLUTOSVG_ENABLE_FREETYPE=ON -DPLUTOSVG_BUILD_EXAMPLES=OFF -B build -G Ninja || goto error
|
||||
cmake --build build --parallel || goto error
|
||||
ninja -C build install || goto error
|
||||
cd .. || goto error
|
||||
|
||||
68
.github/workflows/scripts/windows/build-gammaray.bat
vendored
Normal file
68
.github/workflows/scripts/windows/build-gammaray.bat
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
@echo off
|
||||
setlocal enabledelayedexpansion
|
||||
|
||||
echo Setting environment...
|
||||
if exist "%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" (
|
||||
call "%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
|
||||
) else if exist "%ProgramFiles%\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat" (
|
||||
call "%ProgramFiles%\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat"
|
||||
) else (
|
||||
echo Visual Studio 2022 not found.
|
||||
goto error
|
||||
)
|
||||
|
||||
pushd %~dp0
|
||||
|
||||
cd ..\..\..\..
|
||||
cd deps || goto error
|
||||
set "DEPSDIR=%CD%"
|
||||
cd ..
|
||||
mkdir gammaray
|
||||
cd gammaray || goto error
|
||||
set "INSTALLDIR=%CD%"
|
||||
cd ..
|
||||
mkdir gammaray-build
|
||||
cd gammaray-build || goto error
|
||||
set "BUILDDIR=%CD%"
|
||||
|
||||
echo DEPSDIR=%DEPSDIR%
|
||||
echo BUILDDIR=%BUILDDIR%
|
||||
echo INSTALLDIR=%INSTALLDIR%
|
||||
|
||||
set GAMMARAY="master"
|
||||
|
||||
echo Downloading...
|
||||
curl -L -o "GammaRay-%GAMMARAY%.tar.gz" "https://github.com/KDAB/GammaRay/archive/%GAMMARAY%.tar.gz" || goto error
|
||||
|
||||
rmdir /s /q "GammaRay-%GAMMARAY%"
|
||||
|
||||
echo Extracting...
|
||||
tar -xf "GammaRay-%GAMMARAY%.tar.gz" || goto error
|
||||
|
||||
echo Configuring...
|
||||
cmake "GammaRay-%GAMMARAY%" -B build -DCMAKE_PREFIX_PATH="%DEPSDIR%" -G Ninja -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DGAMMARAY_BUILD_DOCS=false || goto error
|
||||
|
||||
echo Building...
|
||||
cmake --build build --parallel || goto error
|
||||
|
||||
echo Installing...
|
||||
cmake --build build --target install || goto errorlevel
|
||||
|
||||
echo Copying DLLs...
|
||||
xcopy /y "%DEPSDIR%\bin\*.dll" "%INSTALLDIR%\bin\"
|
||||
xcopy /y /e /s "%DEPSDIR%\plugins" "%INSTALLDIR%\bin\"
|
||||
|
||||
echo Cleaning up...
|
||||
cd ..
|
||||
rd /s /q gammaray-build
|
||||
|
||||
echo Exiting with success.
|
||||
popd
|
||||
pause
|
||||
exit 0
|
||||
|
||||
:error
|
||||
echo Failed with error #%errorlevel%.
|
||||
popd
|
||||
pause
|
||||
exit %errorlevel%
|
||||
@@ -1,13 +0,0 @@
|
||||
diff --git a/src/plugins/styles/modernwindows/qwindowsvistastyle.cpp b/src/plugins/styles/modernwindows/qwindowsvistastyle.cpp
|
||||
index 208420d7e8..26ef6f31ef 100644
|
||||
--- a/src/plugins/styles/modernwindows/qwindowsvistastyle.cpp
|
||||
+++ b/src/plugins/styles/modernwindows/qwindowsvistastyle.cpp
|
||||
@@ -4232,8 +4232,6 @@ QRect QWindowsVistaStyle::subElementRect(SubElement element, const QStyleOption
|
||||
|
||||
case SE_ItemViewItemDecoration:
|
||||
rect = QWindowsStyle::subElementRect(element, option, widget);
|
||||
- if (qstyleoption_cast<const QStyleOptionViewItem *>(option))
|
||||
- rect.adjust(-2, 0, 2, 0);
|
||||
break;
|
||||
|
||||
case SE_ItemViewItemFocusRect:
|
||||
4
.github/workflows/triage_pr.yml
vendored
4
.github/workflows/triage_pr.yml
vendored
@@ -8,7 +8,7 @@ jobs:
|
||||
if: github.repository == 'PCSX2/pcsx2'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/labeler@v5
|
||||
- uses: actions/labeler@v6
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -19,7 +19,7 @@ jobs:
|
||||
pr-message: |-
|
||||
## Thank you for submitting a contribution to PCSX2
|
||||
|
||||
As this is your first pull request, [please be aware of the contributing guidelines](https://github.com/PCSX2/pcsx2/blob/master/.github/CONTRIBUTING.md).
|
||||
As this is your first pull request, [please be aware of the contributing guidelines](https://pcsx2.net/docs/contributing/).
|
||||
|
||||
Additionally, as per recent changes in GitHub Actions, your pull request will need to be approved by a maintainer before GitHub Actions can run against it. [You can find more information about this change here.](https://github.blog/2021-04-22-github-actions-update-helping-maintainers-combat-bad-actors/)
|
||||
|
||||
|
||||
2
.github/workflows/windows_build_matrix.yml
vendored
2
.github/workflows/windows_build_matrix.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
||||
runs-on: windows-2025
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
- name: Verify VS Project Files
|
||||
run: .github\workflows\scripts\windows\validate-vs-filters.ps1
|
||||
|
||||
|
||||
10
.github/workflows/windows_build_qt.yml
vendored
10
.github/workflows/windows_build_qt.yml
vendored
@@ -56,7 +56,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Configure MSBuild Clang Version
|
||||
if: inputs.configuration != 'CMake'
|
||||
@@ -115,7 +115,7 @@ jobs:
|
||||
|
||||
- name: Cache Dependencies
|
||||
id: cache-deps
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: deps
|
||||
key: ${{ inputs.os }} ${{ inputs.platform }} deps ${{ hashFiles('.github/workflows/scripts/windows/build-dependencies.bat', '.github/workflows/scripts/common/*.patch') }}
|
||||
@@ -154,7 +154,7 @@ jobs:
|
||||
cmake --build build --config Release --target unittests
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: ${{ steps.artifact-metadata.outputs.artifact-name }}
|
||||
path: |
|
||||
@@ -168,7 +168,7 @@ jobs:
|
||||
!./bin/**/*.lib
|
||||
|
||||
- name: Install the Breakpad Symbol Generator
|
||||
uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3
|
||||
uses: baptiste0928/cargo-install@b687c656bda5733207e629b50a22bf68974a0305
|
||||
with:
|
||||
crate: dump_syms
|
||||
|
||||
@@ -186,7 +186,7 @@ jobs:
|
||||
}
|
||||
|
||||
- name: Upload artifact - with symbols
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: ${{ steps.artifact-metadata.outputs.artifact-name }}-symbols
|
||||
path: |
|
||||
|
||||
17
.github/workflows/windows_deps_dispatch.yml
vendored
Normal file
17
.github/workflows/windows_deps_dispatch.yml
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
name: 🖥️ 📦 Dispatch Windows Deps Build
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [closed]
|
||||
|
||||
jobs:
|
||||
trigger:
|
||||
if: github.event.pull_request.merged == true && contains(github.event.pull_request.labels.*.name, 'requires-win-deps-build')
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Dispatch to windows-dependencies repo
|
||||
uses: peter-evans/repository-dispatch@v4
|
||||
with:
|
||||
token: ${{ secrets.DEPS_REPO_DISPATCH_ACCESS_TOKEN }}
|
||||
repository: pcsx2/pcsx2-windows-dependencies
|
||||
event-type: deps-update
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -109,6 +109,8 @@ oprofile_data/
|
||||
/deps-build
|
||||
/deps
|
||||
/deps-arm64
|
||||
/gammaray-build
|
||||
/gammaray
|
||||
/ipch
|
||||
|
||||
!/3rdparty/libjpeg/change.log
|
||||
|
||||
24
3rdparty/ccc/src/ccc/symbol_database.cpp
vendored
24
3rdparty/ccc/src/ccc/symbol_database.cpp
vendored
@@ -113,13 +113,27 @@ typename SymbolList<SymbolType>::AddressToHandleMapIterators SymbolList<SymbolTy
|
||||
template <typename SymbolType>
|
||||
typename SymbolList<SymbolType>::AddressToHandleMapIterators SymbolList<SymbolType>::handles_from_address_range(AddressRange range) const
|
||||
{
|
||||
if(range.low.valid()) {
|
||||
return {m_address_to_handle.lower_bound(range.low.value), m_address_to_handle.lower_bound(range.high.value)};
|
||||
} else if(range.high.valid()) {
|
||||
return {m_address_to_handle.begin(), m_address_to_handle.lower_bound(range.high.value)};
|
||||
typename AddressToHandleMap::const_iterator begin, end;
|
||||
if (range.low.valid() && range.high.valid()) {
|
||||
if (range.low.value < range.high.value) {
|
||||
begin = m_address_to_handle.lower_bound(range.low.value);
|
||||
end = m_address_to_handle.lower_bound(range.high.value);
|
||||
} else {
|
||||
begin = m_address_to_handle.end();
|
||||
end = m_address_to_handle.end();
|
||||
}
|
||||
} else if (range.low.valid()) {
|
||||
begin = m_address_to_handle.lower_bound(range.low.value);
|
||||
end = m_address_to_handle.end();
|
||||
} else if (range.high.valid()) {
|
||||
begin = m_address_to_handle.begin();
|
||||
end = m_address_to_handle.lower_bound(range.high.value);
|
||||
} else {
|
||||
return {m_address_to_handle.end(), m_address_to_handle.end()};
|
||||
begin = m_address_to_handle.end();
|
||||
end = m_address_to_handle.end();
|
||||
}
|
||||
|
||||
return {begin, end};
|
||||
}
|
||||
|
||||
template <typename SymbolType>
|
||||
|
||||
16
3rdparty/cpuinfo/CMakeLists.txt
vendored
16
3rdparty/cpuinfo/CMakeLists.txt
vendored
@@ -1,4 +1,4 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.5 FATAL_ERROR)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.18 FATAL_ERROR)
|
||||
|
||||
# ---[ Setup project
|
||||
PROJECT(
|
||||
@@ -108,7 +108,7 @@ IF(NOT CMAKE_SYSTEM_NAME)
|
||||
"Target operating system is not specified. "
|
||||
"cpuinfo will compile, but cpuinfo_initialize() will always fail.")
|
||||
SET(CPUINFO_SUPPORTED_PLATFORM FALSE)
|
||||
ELSEIF(NOT CMAKE_SYSTEM_NAME MATCHES "^(Windows|WindowsStore|CYGWIN|MSYS|Darwin|Linux|Android|FreeBSD)$")
|
||||
ELSEIF(NOT CMAKE_SYSTEM_NAME MATCHES "^(Windows|WindowsStore|CYGWIN|MSYS|Darwin|Linux|Android|FreeBSD|Emscripten)$")
|
||||
IF(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.14" AND NOT IS_APPLE_OS)
|
||||
MESSAGE(WARNING
|
||||
"Target operating system \"${CMAKE_SYSTEM_NAME}\" is not supported in cpuinfo. "
|
||||
@@ -184,10 +184,11 @@ IF(CPUINFO_SUPPORTED_PLATFORM)
|
||||
ELSEIF(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
|
||||
LIST(APPEND CPUINFO_SRCS src/x86/freebsd/init.c)
|
||||
ENDIF()
|
||||
ELSEIF(CMAKE_SYSTEM_NAME MATCHES "^Windows" AND CPUINFO_TARGET_PROCESSOR MATCHES "^(ARM64|arm64)$")
|
||||
ELSEIF(CMAKE_SYSTEM_NAME MATCHES "^Windows" AND CPUINFO_TARGET_PROCESSOR MATCHES "^(ARM64|arm64|aarch64)$")
|
||||
LIST(APPEND CPUINFO_SRCS
|
||||
src/arm/windows/init-by-logical-sys-info.c
|
||||
src/arm/windows/init.c)
|
||||
src/arm/windows/init.c
|
||||
src/arm/uarch.c)
|
||||
ELSEIF(CPUINFO_TARGET_PROCESSOR MATCHES "^(armv[5-8].*|aarch64|arm64.*)$" OR IOS_ARCH MATCHES "^(armv7.*|arm64.*)$")
|
||||
LIST(APPEND CPUINFO_SRCS
|
||||
src/arm/uarch.c
|
||||
@@ -218,7 +219,7 @@ IF(CPUINFO_SUPPORTED_PLATFORM)
|
||||
ELSEIF(CPUINFO_TARGET_PROCESSOR MATCHES "^(riscv(32|64))$")
|
||||
LIST(APPEND CPUINFO_SRCS
|
||||
src/riscv/uarch.c)
|
||||
IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
IF(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Android")
|
||||
LIST(APPEND CPUINFO_SRCS
|
||||
src/riscv/linux/init.c
|
||||
src/riscv/linux/riscv-hw.c
|
||||
@@ -747,6 +748,11 @@ IF(CPUINFO_SUPPORTED_PLATFORM AND CPUINFO_BUILD_MOCK_TESTS)
|
||||
TARGET_LINK_LIBRARIES(pixel-2-xl-test PRIVATE cpuinfo_mock gtest)
|
||||
ADD_TEST(NAME pixel-2-xl-test COMMAND pixel-2-xl-test)
|
||||
|
||||
ADD_EXECUTABLE(pixel-8-test test/mock/pixel-8.cc)
|
||||
TARGET_INCLUDE_DIRECTORIES(pixel-8-test BEFORE PRIVATE test/mock)
|
||||
TARGET_LINK_LIBRARIES(pixel-8-test PRIVATE cpuinfo_mock gtest)
|
||||
ADD_TEST(NAME pixel-8-test COMMAND pixel-8-test)
|
||||
|
||||
ADD_EXECUTABLE(xiaomi-mi-5c-test test/mock/xiaomi-mi-5c.cc)
|
||||
TARGET_INCLUDE_DIRECTORIES(xiaomi-mi-5c-test BEFORE PRIVATE test/mock)
|
||||
TARGET_LINK_LIBRARIES(xiaomi-mi-5c-test PRIVATE cpuinfo_mock gtest)
|
||||
|
||||
4
3rdparty/cpuinfo/README.md
vendored
4
3rdparty/cpuinfo/README.md
vendored
@@ -9,7 +9,7 @@ cpuinfo is a library to detect essential for performance optimization informatio
|
||||
## Features
|
||||
|
||||
- **Cross-platform** availability:
|
||||
- Linux, Windows, macOS, Android, and iOS operating systems
|
||||
- Linux, Windows, macOS, Android, iOS and FreeBSD operating systems
|
||||
- x86, x86-64, ARM, and ARM64 architectures
|
||||
- Modern **C/C++ interface**
|
||||
- Thread-safe
|
||||
@@ -258,6 +258,8 @@ LDFLAGS+= $(pkg-config --libs libcpuinfo)
|
||||
- [x] x86
|
||||
- [x] x86-64
|
||||
- [x] arm64
|
||||
- [x] FreeBSD
|
||||
- [x] x86-64
|
||||
|
||||
## Methods
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12 FATAL_ERROR)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.18 FATAL_ERROR)
|
||||
|
||||
PROJECT(googlebenchmark-download NONE)
|
||||
|
||||
INCLUDE(ExternalProject)
|
||||
ExternalProject_Add(googlebenchmark
|
||||
URL https://github.com/google/benchmark/archive/v1.6.1.zip
|
||||
URL_HASH SHA256=367e963b8620080aff8c831e24751852cffd1f74ea40f25d9cc1b667a9dd5e45
|
||||
URL https://github.com/google/benchmark/archive/refs/tags/v1.9.4.tar.gz
|
||||
URL_HASH SHA256=b334658edd35efcf06a99d9be21e4e93e092bd5f95074c1673d5c8705d95c104
|
||||
SOURCE_DIR "${CONFU_DEPENDENCIES_SOURCE_DIR}/googlebenchmark"
|
||||
BINARY_DIR "${CONFU_DEPENDENCIES_BINARY_DIR}/googlebenchmark"
|
||||
CONFIGURE_COMMAND ""
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12 FATAL_ERROR)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.18 FATAL_ERROR)
|
||||
|
||||
PROJECT(googletest-download NONE)
|
||||
|
||||
INCLUDE(ExternalProject)
|
||||
ExternalProject_Add(googletest
|
||||
URL https://github.com/google/googletest/archive/release-1.11.0.zip
|
||||
URL_HASH SHA256=353571c2440176ded91c2de6d6cd88ddd41401d14692ec1f99e35d013feda55a
|
||||
URL https://github.com/google/googletest/archive/refs/tags/v1.17.0.zip
|
||||
URL_HASH SHA256=40d4ec942217dcc84a9ebe2a68584ada7d4a33a8ee958755763278ea1c5e18ff
|
||||
SOURCE_DIR "${CONFU_DEPENDENCIES_SOURCE_DIR}/googletest"
|
||||
BINARY_DIR "${CONFU_DEPENDENCIES_BINARY_DIR}/googletest"
|
||||
CONFIGURE_COMMAND ""
|
||||
|
||||
53
3rdparty/cpuinfo/include/cpuinfo.h
vendored
53
3rdparty/cpuinfo/include/cpuinfo.h
vendored
@@ -353,6 +353,8 @@ enum cpuinfo_uarch {
|
||||
cpuinfo_uarch_palm_cove = 0x0010020B,
|
||||
/** Intel Sunny Cove microarchitecture (10 nm, Ice Lake). */
|
||||
cpuinfo_uarch_sunny_cove = 0x0010020C,
|
||||
/** Intel Willow Cove microarchitecture (10 nm, Tiger Lake). */
|
||||
cpuinfo_uarch_willow_cove = 0x0010020D,
|
||||
|
||||
/** Pentium 4 with Willamette, Northwood, or Foster cores. */
|
||||
cpuinfo_uarch_willamette = 0x00100300,
|
||||
@@ -371,6 +373,14 @@ enum cpuinfo_uarch {
|
||||
cpuinfo_uarch_goldmont = 0x00100404,
|
||||
/** Intel Goldmont Plus microarchitecture (Gemini Lake). */
|
||||
cpuinfo_uarch_goldmont_plus = 0x00100405,
|
||||
/** Intel Airmont microarchitecture (10 nm out-of-order Atom). */
|
||||
cpuinfo_uarch_tremont = 0x00100406,
|
||||
/** Intel Gracemont microarchitecture (AlderLake N). */
|
||||
cpuinfo_uarch_gracemont = 0x00100407,
|
||||
/** Intel Crestmont microarchitecture (Sierra Forest). */
|
||||
cpuinfo_uarch_crestmont = 0x00100408,
|
||||
/** Intel Darkmont microarchitecture (e-core used in Clearwater Forest). */
|
||||
cpuinfo_uarch_darkmont = 0x00100409,
|
||||
|
||||
/** Intel Knights Ferry HPC boards. */
|
||||
cpuinfo_uarch_knights_ferry = 0x00100500,
|
||||
@@ -500,6 +510,8 @@ enum cpuinfo_uarch {
|
||||
cpuinfo_uarch_cortex_x3 = 0x00300503,
|
||||
/** ARM Cortex-X4. */
|
||||
cpuinfo_uarch_cortex_x4 = 0x00300504,
|
||||
/** ARM Cortex-X925. */
|
||||
cpuinfo_uarch_cortex_x925 = 0x00300505,
|
||||
|
||||
/** ARM Cortex-A510. */
|
||||
cpuinfo_uarch_cortex_a510 = 0x00300551,
|
||||
@@ -511,6 +523,8 @@ enum cpuinfo_uarch {
|
||||
cpuinfo_uarch_cortex_a715 = 0x00300572,
|
||||
/** ARM Cortex-A720. */
|
||||
cpuinfo_uarch_cortex_a720 = 0x00300573,
|
||||
/** ARM Cortex-A725. */
|
||||
cpuinfo_uarch_cortex_a725 = 0x00300574,
|
||||
|
||||
/** Qualcomm Scorpion. */
|
||||
cpuinfo_uarch_scorpion = 0x00400100,
|
||||
@@ -522,6 +536,8 @@ enum cpuinfo_uarch {
|
||||
cpuinfo_uarch_falkor = 0x00400103,
|
||||
/** Qualcomm Saphira. */
|
||||
cpuinfo_uarch_saphira = 0x00400104,
|
||||
/** Qualcomm Oryon. */
|
||||
cpuinfo_uarch_oryon = 0x00400105,
|
||||
|
||||
/** Nvidia Denver. */
|
||||
cpuinfo_uarch_denver = 0x00500100,
|
||||
@@ -579,6 +595,22 @@ enum cpuinfo_uarch {
|
||||
cpuinfo_uarch_avalanche = 0x0070010D,
|
||||
/** Apple A15 / M2 processor (little cores). */
|
||||
cpuinfo_uarch_blizzard = 0x0070010E,
|
||||
/** Apple A16 processor (big cores). */
|
||||
cpuinfo_uarch_everest = 0x00700200,
|
||||
/** Apple A16 processor (little cores). */
|
||||
cpuinfo_uarch_sawtooth = 0x00700201,
|
||||
/** Apple A17 processor (big cores). */
|
||||
cpuinfo_uarch_coll_everest = 0x00700202,
|
||||
/** Apple A17 processor (little cores). */
|
||||
cpuinfo_uarch_coll_sawtooth = 0x00700203,
|
||||
/** Apple A18 processor (big cores). */
|
||||
cpuinfo_uarch_tupai_everest = 0x00700204,
|
||||
/** Apple A18 processor (little cores). */
|
||||
cpuinfo_uarch_tupai_sawtooth = 0x00700205,
|
||||
/** Apple A18 pro processor (big cores). */
|
||||
cpuinfo_uarch_tahiti_everest = 0x00700206,
|
||||
/** Apple A18 pro processor (little cores). */
|
||||
cpuinfo_uarch_tahiti_sawtooth = 0x00700207,
|
||||
|
||||
/** Cavium ThunderX. */
|
||||
cpuinfo_uarch_thunderx = 0x00800100,
|
||||
@@ -704,7 +736,7 @@ struct cpuinfo_cluster {
|
||||
uint64_t frequency;
|
||||
};
|
||||
|
||||
#define CPUINFO_PACKAGE_NAME_MAX 48
|
||||
#define CPUINFO_PACKAGE_NAME_MAX 64
|
||||
|
||||
struct cpuinfo_package {
|
||||
/** SoC or processor chip model name */
|
||||
@@ -821,6 +853,7 @@ struct cpuinfo_x86_isa {
|
||||
bool avx512_4vnniw;
|
||||
bool avx512_4fmaps;
|
||||
bool avx10_1;
|
||||
bool avx10_2;
|
||||
bool amx_bf16;
|
||||
bool amx_tile;
|
||||
bool amx_int8;
|
||||
@@ -1444,6 +1477,14 @@ static inline bool cpuinfo_has_x86_avx10_1(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline bool cpuinfo_has_x86_avx10_2(void) {
|
||||
#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
|
||||
return cpuinfo_isa.avx10_2;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline bool cpuinfo_has_x86_hle(void) {
|
||||
#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
|
||||
return cpuinfo_isa.hle;
|
||||
@@ -1689,6 +1730,7 @@ struct cpuinfo_arm_isa {
|
||||
bool sme_b16b16;
|
||||
bool sme_f16f16;
|
||||
uint32_t svelen;
|
||||
uint32_t smelen;
|
||||
#endif
|
||||
bool rdm;
|
||||
bool fp16arith;
|
||||
@@ -2070,6 +2112,15 @@ static inline uint32_t cpuinfo_get_max_arm_sve_length(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
// Function to get the max SME vector length on ARM CPU's which support SME.
|
||||
static inline uint32_t cpuinfo_get_max_arm_sme_length(void) {
|
||||
#if CPUINFO_ARCH_ARM64
|
||||
return cpuinfo_isa.smelen * 8; // bytes * 8 = bit length(vector length)
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline bool cpuinfo_has_arm_sme(void) {
|
||||
#if CPUINFO_ARCH_ARM64
|
||||
return cpuinfo_isa.sme;
|
||||
|
||||
28
3rdparty/cpuinfo/src/arm/api.h
vendored
28
3rdparty/cpuinfo/src/arm/api.h
vendored
@@ -1,5 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define RESTRICT_STATIC /* nothing for MSVC */
|
||||
#else
|
||||
#define RESTRICT_STATIC restrict static
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -82,11 +88,11 @@ struct cpuinfo_arm_chipset {
|
||||
|
||||
#ifndef __cplusplus
|
||||
CPUINFO_INTERNAL void cpuinfo_arm_chipset_to_string(
|
||||
const struct cpuinfo_arm_chipset chipset[restrict static 1],
|
||||
char name[restrict static CPUINFO_ARM_CHIPSET_NAME_MAX]);
|
||||
const struct cpuinfo_arm_chipset chipset[RESTRICT_STATIC 1],
|
||||
char name[RESTRICT_STATIC CPUINFO_ARM_CHIPSET_NAME_MAX]);
|
||||
|
||||
CPUINFO_INTERNAL void cpuinfo_arm_fixup_chipset(
|
||||
struct cpuinfo_arm_chipset chipset[restrict static 1],
|
||||
struct cpuinfo_arm_chipset chipset[RESTRICT_STATIC 1],
|
||||
uint32_t cores,
|
||||
uint32_t max_cpu_freq_max);
|
||||
|
||||
@@ -95,23 +101,23 @@ CPUINFO_INTERNAL void cpuinfo_arm_decode_vendor_uarch(
|
||||
#if CPUINFO_ARCH_ARM
|
||||
bool has_vfpv4,
|
||||
#endif
|
||||
enum cpuinfo_vendor vendor[restrict static 1],
|
||||
enum cpuinfo_uarch uarch[restrict static 1]);
|
||||
enum cpuinfo_vendor vendor[RESTRICT_STATIC 1],
|
||||
enum cpuinfo_uarch uarch[RESTRICT_STATIC 1]);
|
||||
|
||||
CPUINFO_INTERNAL void cpuinfo_arm_decode_cache(
|
||||
enum cpuinfo_uarch uarch,
|
||||
uint32_t cluster_cores,
|
||||
uint32_t midr,
|
||||
const struct cpuinfo_arm_chipset chipset[restrict static 1],
|
||||
const struct cpuinfo_arm_chipset chipset[RESTRICT_STATIC 1],
|
||||
uint32_t cluster_id,
|
||||
uint32_t arch_version,
|
||||
struct cpuinfo_cache l1i[restrict static 1],
|
||||
struct cpuinfo_cache l1d[restrict static 1],
|
||||
struct cpuinfo_cache l2[restrict static 1],
|
||||
struct cpuinfo_cache l3[restrict static 1]);
|
||||
struct cpuinfo_cache l1i[RESTRICT_STATIC 1],
|
||||
struct cpuinfo_cache l1d[RESTRICT_STATIC 1],
|
||||
struct cpuinfo_cache l2[RESTRICT_STATIC 1],
|
||||
struct cpuinfo_cache l3[RESTRICT_STATIC 1]);
|
||||
|
||||
CPUINFO_INTERNAL uint32_t
|
||||
cpuinfo_arm_compute_max_cache_size(const struct cpuinfo_processor processor[restrict static 1]);
|
||||
cpuinfo_arm_compute_max_cache_size(const struct cpuinfo_processor processor[RESTRICT_STATIC 1]);
|
||||
#else /* defined(__cplusplus) */
|
||||
CPUINFO_INTERNAL void cpuinfo_arm_decode_cache(
|
||||
enum cpuinfo_uarch uarch,
|
||||
|
||||
17
3rdparty/cpuinfo/src/arm/linux/aarch64-isa.c
vendored
17
3rdparty/cpuinfo/src/arm/linux/aarch64-isa.c
vendored
@@ -191,4 +191,21 @@ void cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo(
|
||||
// Mask out the SVE vector length bits
|
||||
isa->svelen = ret & PR_SVE_VL_LEN_MASK;
|
||||
}
|
||||
|
||||
#ifndef PR_SME_GET_VL
|
||||
#define PR_SME_GET_VL 64
|
||||
#endif
|
||||
|
||||
#ifndef PR_SME_VL_LEN_MASK
|
||||
#define PR_SME_VL_LEN_MASK 0xffff
|
||||
#endif
|
||||
|
||||
ret = prctl(PR_SME_GET_VL);
|
||||
if (ret < 0) {
|
||||
cpuinfo_log_warning("No SME support on this machine");
|
||||
isa->smelen = 0; // Assume no SME support if the call fails
|
||||
} else {
|
||||
// Mask out the SME vector length bits
|
||||
isa->smelen = ret & PR_SME_VL_LEN_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
102
3rdparty/cpuinfo/src/arm/linux/chipset.c
vendored
102
3rdparty/cpuinfo/src/arm/linux/chipset.c
vendored
@@ -468,6 +468,56 @@ static bool match_universal(const char* start, const char* end, struct cpuinfo_a
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to match /s5e\d{4}$/ signature for Samsung Exynos chipsets.
|
||||
* If match successful, extracts model information into \p chipset argument.
|
||||
*
|
||||
* @param start - start of the platform identifier (ro.product.board or
|
||||
* ro.board.platform) to match.
|
||||
* @param end - end of the platform identifier (ro.product.board or
|
||||
* ro.board.platform) to match.
|
||||
* @param[out] chipset - location where chipset information will be stored upon
|
||||
* a successful match.
|
||||
*
|
||||
* @returns true if signature matched, false otherwise.
|
||||
*/
|
||||
static bool match_s5e(const char* start, const char* end, struct cpuinfo_arm_chipset chipset[restrict static 1]) {
|
||||
/* Expect exactly 7 symbols: "s5e" (3 symbols) + 4-digit model number */
|
||||
if (start + 7 != end) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check that string starts with "s5e" */
|
||||
if (start[0] != 's') {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Load next 2 bytes as little endian 16-bit word */
|
||||
const uint16_t expected_5e = load_u16le(start + 1);
|
||||
if (expected_5e != UINT16_C(0x6535) /* "e5" = reverse("5e") */) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check and parse 4-digit model number */
|
||||
uint32_t model = 0;
|
||||
for (uint32_t i = 3; i < 7; i++) {
|
||||
const uint32_t digit = (uint32_t)(uint8_t)start[i] - '0';
|
||||
if (digit >= 10) {
|
||||
/* Not really a digit */
|
||||
return false;
|
||||
}
|
||||
model = model * 10 + digit;
|
||||
}
|
||||
|
||||
/* Return parsed chipset. */
|
||||
*chipset = (struct cpuinfo_arm_chipset){
|
||||
.vendor = cpuinfo_arm_chipset_vendor_samsung,
|
||||
.series = cpuinfo_arm_chipset_series_samsung_exynos,
|
||||
.model = model,
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares, case insensitively, a string to known values "SMDK4210" and
|
||||
* "SMDK4x12" for Samsung Exynos chipsets. If platform identifier matches one of
|
||||
@@ -903,7 +953,7 @@ static bool match_sc(const char* start, const char* end, struct cpuinfo_arm_chip
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to match, case-sentitively, /Unisoc T\d{3,4}/ signature for Unisoc T
|
||||
* Tries to match, case-sentitively, /Unisoc T\d{3,4}/ or /UNISOC T\d{3,4}/ signature for Unisoc T
|
||||
* chipset. If match successful, extracts model information into \p chipset
|
||||
* argument.
|
||||
*
|
||||
@@ -917,7 +967,7 @@ static bool match_sc(const char* start, const char* end, struct cpuinfo_arm_chip
|
||||
* @returns true if signature matched, false otherwise.
|
||||
*/
|
||||
static bool match_t(const char* start, const char* end, struct cpuinfo_arm_chipset chipset[restrict static 1]) {
|
||||
/* Expect 11-12 symbols: "Unisoc T" (8 symbols) + 3-4-digit model number
|
||||
/* Expect 11-12 symbols: "Unisoc T" / "UNISOC T" (8 symbols) + 3-4-digit model number
|
||||
*/
|
||||
const size_t length = end - start;
|
||||
switch (length) {
|
||||
@@ -928,16 +978,18 @@ static bool match_t(const char* start, const char* end, struct cpuinfo_arm_chips
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check that string starts with "Unisoc T". The first four characters
|
||||
/* Check that string starts with "Unisoc T" or "UNISOC T". The first four characters
|
||||
* are loaded as 32-bit little endian word */
|
||||
const uint32_t expected_unis = load_u32le(start);
|
||||
if (expected_unis != UINT32_C(0x73696E55) /* "sinU" = reverse("Unis") */) {
|
||||
if (expected_unis != UINT32_C(0x73696E55) /* "sinU" = reverse("Unis") */ &&
|
||||
expected_unis != UINT32_C(0x53494E55) /* "SINU" = reverse("UNIS") */) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* The next four characters are loaded as 32-bit little endian word */
|
||||
const uint32_t expected_oc_t = load_u32le(start + 4);
|
||||
if (expected_oc_t != UINT32_C(0x5420636F) /* "T co" = reverse("oc T") */) {
|
||||
if (expected_oc_t != UINT32_C(0x5420636F) /* "T co" = reverse("oc T") */ &&
|
||||
expected_oc_t != UINT32_C(0x5420434F) /* "T CO" = reverse("OC T") */) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2837,6 +2889,15 @@ struct cpuinfo_arm_chipset cpuinfo_arm_android_decode_chipset_from_ro_product_bo
|
||||
return chipset;
|
||||
}
|
||||
|
||||
/* Check s5eXXXX (Samsung Exynos) signature */
|
||||
if (match_s5e(board, board_end, &chipset)) {
|
||||
cpuinfo_log_debug(
|
||||
"matched S5E (Samsung Exynos) signature in ro.product.board string \"%.*s\"",
|
||||
(int)board_length,
|
||||
board);
|
||||
return chipset;
|
||||
}
|
||||
|
||||
#if CPUINFO_ARCH_ARM
|
||||
/* Check SMDK (Samsung Exynos) signature */
|
||||
if (match_and_parse_smdk(board, board_end, cores, &chipset)) {
|
||||
@@ -3949,6 +4010,20 @@ static inline struct cpuinfo_arm_chipset disambiguate_spreadtrum_chipset(
|
||||
return *ro_board_platform_chipset;
|
||||
}
|
||||
|
||||
static enum cpuinfo_arm_chipset_vendor disambiguate_chipset_vendor(
|
||||
enum cpuinfo_arm_chipset_vendor vendor_a,
|
||||
enum cpuinfo_arm_chipset_vendor vendor_b) {
|
||||
/* Some UNISOC-based platforms reporting conflicting vendor names depending
|
||||
* on the source. For phones that report both UNISOC and Spreadtrum, treat it
|
||||
* as UNISOC. */
|
||||
if ((vendor_a == cpuinfo_arm_chipset_vendor_unisoc && vendor_b == cpuinfo_arm_chipset_vendor_spreadtrum) ||
|
||||
(vendor_a == cpuinfo_arm_chipset_vendor_spreadtrum && vendor_b == cpuinfo_arm_chipset_vendor_unisoc)) {
|
||||
return cpuinfo_arm_chipset_vendor_unisoc;
|
||||
}
|
||||
|
||||
return cpuinfo_arm_chipset_vendor_unknown;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decodes chipset name from Android system properties:
|
||||
* - /proc/cpuinfo Hardware string
|
||||
@@ -4009,10 +4084,19 @@ struct cpuinfo_arm_chipset cpuinfo_arm_android_decode_chipset(
|
||||
} else if (vendor != decoded_vendor) {
|
||||
/* Parsing different system properties produces
|
||||
* different chipset vendors. This situation is
|
||||
* rare. */
|
||||
cpuinfo_log_error(
|
||||
"chipset detection failed: different chipset vendors reported in different system properties");
|
||||
goto finish;
|
||||
* rare. Try to disambiguate for known cases,
|
||||
* otherwise treat as unknown. */
|
||||
|
||||
enum cpuinfo_arm_chipset_vendor disambiguated_vendor =
|
||||
disambiguate_chipset_vendor(vendor, decoded_vendor);
|
||||
|
||||
if (disambiguated_vendor != cpuinfo_arm_chipset_vendor_unknown) {
|
||||
vendor = disambiguated_vendor;
|
||||
} else {
|
||||
cpuinfo_log_error(
|
||||
"chipset detection failed: different chipset vendors reported in different system properties");
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
57
3rdparty/cpuinfo/src/arm/mach/init.c
vendored
57
3rdparty/cpuinfo/src/arm/mach/init.c
vendored
@@ -27,6 +27,45 @@
|
||||
#ifndef CPUFAMILY_ARM_AVALANCHE_BLIZZARD
|
||||
#define CPUFAMILY_ARM_AVALANCHE_BLIZZARD 0xDA33D83D
|
||||
#endif
|
||||
// Following are copied over from ncnn/src/cpu.cpp
|
||||
// A16
|
||||
#ifndef CPUFAMILY_ARM_EVEREST_SAWTOOTH
|
||||
#define CPUFAMILY_ARM_EVEREST_SAWTOOTH 0x8765edea
|
||||
#endif
|
||||
// A17
|
||||
#ifndef CPUFAMILY_ARM_COLL
|
||||
#define CPUFAMILY_ARM_COLL 0x2876f5b5
|
||||
#endif
|
||||
// A18
|
||||
#ifndef CPUFAMILY_ARM_TUPAI
|
||||
#define CPUFAMILY_ARM_TUPAI 0x204526d0
|
||||
#endif
|
||||
// A18 Pro
|
||||
#ifndef CPUFAMILY_ARM_TAHITI
|
||||
#define CPUFAMILY_ARM_TAHITI 0x75d4acb9
|
||||
#endif
|
||||
// For M3/M4 we need to populate more information about
|
||||
// efficiency and perf cores.
|
||||
// M3
|
||||
#ifndef CPUFAMILY_ARM_IBIZA
|
||||
#define CPUFAMILY_ARM_IBIZA 0xfa33415e
|
||||
#endif
|
||||
// M3 Pro
|
||||
#ifndef CPUFAMILY_ARM_LOBOS
|
||||
#define CPUFAMILY_ARM_LOBOS 0x5f4dea93
|
||||
#endif
|
||||
// M3 Max
|
||||
#ifndef CPUFAMILY_ARM_PALMA
|
||||
#define CPUFAMILY_ARM_PALMA 0x72015832
|
||||
#endif
|
||||
// M4
|
||||
#ifndef CPUFAMILY_ARM_DONAN
|
||||
#define CPUFAMILY_ARM_DONAN 0x6f5129ac
|
||||
#endif
|
||||
// M4 Pro / M4 Max
|
||||
#ifndef CPUFAMILY_ARM_BRAVA
|
||||
#define CPUFAMILY_ARM_BRAVA 0x17d5b93a
|
||||
#endif
|
||||
|
||||
struct cpuinfo_arm_isa cpuinfo_isa = {
|
||||
.aes = true,
|
||||
@@ -93,6 +132,23 @@ static enum cpuinfo_uarch decode_uarch(uint32_t cpu_family, uint32_t core_index,
|
||||
case CPUFAMILY_ARM_AVALANCHE_BLIZZARD:
|
||||
/* Hexa-core: 2x Avalanche + 4x Blizzard */
|
||||
return core_index + 4 < core_count ? cpuinfo_uarch_avalanche : cpuinfo_uarch_blizzard;
|
||||
case CPUFAMILY_ARM_EVEREST_SAWTOOTH:
|
||||
/* Hexa-core: 2x Avalanche + 4x Blizzard */
|
||||
return core_index + 4 < core_count ? cpuinfo_uarch_everest : cpuinfo_uarch_sawtooth;
|
||||
return core_index + 4 < core_count ? cpuinfo_uarch_avalanche : cpuinfo_uarch_blizzard;
|
||||
case CPUFAMILY_ARM_COLL:
|
||||
/* Hexa-core: 2x Avalanche + 4x Blizzard */
|
||||
return core_index + 4 < core_count ? cpuinfo_uarch_coll_everest : cpuinfo_uarch_coll_sawtooth;
|
||||
|
||||
case CPUFAMILY_ARM_TUPAI:
|
||||
/* Hexa-core: 2x Avalanche + 4x Blizzard */
|
||||
return core_index + 4 < core_count ? cpuinfo_uarch_tupai_everest : cpuinfo_uarch_tupai_sawtooth;
|
||||
|
||||
case CPUFAMILY_ARM_TAHITI:
|
||||
/* Hexa-core: 2x Avalanche + 4x Blizzard */
|
||||
return core_index + 4 < core_count ? cpuinfo_uarch_tahiti_everest
|
||||
: cpuinfo_uarch_tahiti_sawtooth;
|
||||
|
||||
default:
|
||||
/* Use hw.cpusubtype for detection */
|
||||
break;
|
||||
@@ -101,7 +157,6 @@ static enum cpuinfo_uarch decode_uarch(uint32_t cpu_family, uint32_t core_index,
|
||||
return cpuinfo_uarch_unknown;
|
||||
}
|
||||
|
||||
/* Small bodge until cpuinfo merges PR #246 */
|
||||
static int read_package_name_from_brand_string(char* package_name) {
|
||||
size_t size;
|
||||
if (sysctlbyname("machdep.cpu.brand_string", NULL, &size, NULL, 0) != 0) {
|
||||
|
||||
19
3rdparty/cpuinfo/src/arm/uarch.c
vendored
19
3rdparty/cpuinfo/src/arm/uarch.c
vendored
@@ -9,8 +9,8 @@ void cpuinfo_arm_decode_vendor_uarch(
|
||||
#if CPUINFO_ARCH_ARM
|
||||
bool has_vfpv4,
|
||||
#endif /* CPUINFO_ARCH_ARM */
|
||||
enum cpuinfo_vendor vendor[restrict static 1],
|
||||
enum cpuinfo_uarch uarch[restrict static 1]) {
|
||||
enum cpuinfo_vendor vendor[RESTRICT_STATIC 1],
|
||||
enum cpuinfo_uarch uarch[RESTRICT_STATIC 1]) {
|
||||
switch (midr_get_implementer(midr)) {
|
||||
case 'A':
|
||||
*vendor = cpuinfo_vendor_arm;
|
||||
@@ -125,6 +125,18 @@ void cpuinfo_arm_decode_vendor_uarch(
|
||||
case 0xD4F: /* Neoverse V2 */
|
||||
*uarch = cpuinfo_uarch_neoverse_v2;
|
||||
break;
|
||||
case 0xD81: /* Cortex-A720 */
|
||||
*uarch = cpuinfo_uarch_cortex_a720;
|
||||
break;
|
||||
case 0xD82: /* Cortex-X4 */
|
||||
*uarch = cpuinfo_uarch_cortex_x4;
|
||||
break;
|
||||
case 0xD85: /* Cortex-X925 */
|
||||
*uarch = cpuinfo_uarch_cortex_x925;
|
||||
break;
|
||||
case 0xD87: /* Cortex-A725 */
|
||||
*uarch = cpuinfo_uarch_cortex_a725;
|
||||
break;
|
||||
default:
|
||||
switch (midr_get_part(midr) >> 8) {
|
||||
#if CPUINFO_ARCH_ARM
|
||||
@@ -332,6 +344,9 @@ void cpuinfo_arm_decode_vendor_uarch(
|
||||
*uarch = cpuinfo_uarch_cortex_a55;
|
||||
break;
|
||||
#if CPUINFO_ARCH_ARM64
|
||||
case 0x001:
|
||||
*uarch = cpuinfo_uarch_oryon;
|
||||
break;
|
||||
case 0xC00:
|
||||
*uarch = cpuinfo_uarch_falkor;
|
||||
break;
|
||||
|
||||
@@ -750,11 +750,8 @@ void store_core_info_per_processor(
|
||||
if (cores) {
|
||||
processors[processor_global_index].core = cores + core_id;
|
||||
cores[core_id].core_id = core_id;
|
||||
get_core_uarch_for_efficiency(
|
||||
chip_info->chip_name,
|
||||
core_info->Processor.EfficiencyClass,
|
||||
&(cores[core_id].uarch),
|
||||
&(cores[core_id].frequency));
|
||||
cores[core_id].uarch = chip_info->uarchs[0].uarch;
|
||||
cores[core_id].frequency = chip_info->uarchs[0].frequency;
|
||||
|
||||
/* We don't have cluster information, so we handle it as
|
||||
* fixed 1 to (cluster / cores).
|
||||
@@ -839,7 +836,6 @@ static bool connect_packages_cores_clusters_by_processors(
|
||||
processor->cluster = cluster;
|
||||
|
||||
if (chip_info) {
|
||||
size_t converted_chars = 0;
|
||||
if (!WideCharToMultiByte(
|
||||
CP_UTF8,
|
||||
WC_ERR_INVALID_CHARS,
|
||||
|
||||
255
3rdparty/cpuinfo/src/arm/windows/init.c
vendored
255
3rdparty/cpuinfo/src/arm/windows/init.c
vendored
@@ -7,6 +7,9 @@
|
||||
#include <cpuinfo/internal-api.h>
|
||||
#include <cpuinfo/log.h>
|
||||
|
||||
#include <arm/api.h>
|
||||
#include <arm/midr.h>
|
||||
|
||||
#include "windows-arm-init.h"
|
||||
|
||||
struct cpuinfo_arm_isa cpuinfo_isa;
|
||||
@@ -14,66 +17,10 @@ struct cpuinfo_arm_isa cpuinfo_isa;
|
||||
static void set_cpuinfo_isa_fields(void);
|
||||
static struct woa_chip_info* get_system_info_from_registry(void);
|
||||
|
||||
static struct woa_chip_info woa_chip_unknown = {
|
||||
L"Unknown",
|
||||
woa_chip_name_unknown,
|
||||
{{cpuinfo_vendor_unknown, cpuinfo_uarch_unknown, 0}}};
|
||||
|
||||
/* Please add new SoC/chip info here! */
|
||||
static struct woa_chip_info woa_chips[woa_chip_name_last] = {
|
||||
/* Microsoft SQ1 Kryo 495 4 + 4 cores (3 GHz + 1.80 GHz) */
|
||||
[woa_chip_name_microsoft_sq_1] =
|
||||
{L"Microsoft SQ1",
|
||||
woa_chip_name_microsoft_sq_1,
|
||||
{{
|
||||
cpuinfo_vendor_arm,
|
||||
cpuinfo_uarch_cortex_a55,
|
||||
1800000000,
|
||||
},
|
||||
{
|
||||
cpuinfo_vendor_arm,
|
||||
cpuinfo_uarch_cortex_a76,
|
||||
3000000000,
|
||||
}}},
|
||||
/* Microsoft SQ2 Kryo 495 4 + 4 cores (3.15 GHz + 2.42 GHz) */
|
||||
[woa_chip_name_microsoft_sq_2] =
|
||||
{L"Microsoft SQ2",
|
||||
woa_chip_name_microsoft_sq_2,
|
||||
{{
|
||||
cpuinfo_vendor_arm,
|
||||
cpuinfo_uarch_cortex_a55,
|
||||
2420000000,
|
||||
},
|
||||
{cpuinfo_vendor_arm, cpuinfo_uarch_cortex_a76, 3150000000}}},
|
||||
/* Snapdragon (TM) 8cx Gen 3 @ 3.0 GHz */
|
||||
[woa_chip_name_microsoft_sq_3] =
|
||||
{L"Snapdragon (TM) 8cx Gen 3",
|
||||
woa_chip_name_microsoft_sq_3,
|
||||
{{
|
||||
cpuinfo_vendor_arm,
|
||||
cpuinfo_uarch_cortex_a78,
|
||||
2420000000,
|
||||
},
|
||||
{cpuinfo_vendor_arm, cpuinfo_uarch_cortex_x1, 3000000000}}},
|
||||
/* Microsoft Windows Dev Kit 2023 */
|
||||
[woa_chip_name_microsoft_sq_3_devkit] =
|
||||
{L"Snapdragon Compute Platform",
|
||||
woa_chip_name_microsoft_sq_3_devkit,
|
||||
{{
|
||||
cpuinfo_vendor_arm,
|
||||
cpuinfo_uarch_cortex_a78,
|
||||
2420000000,
|
||||
},
|
||||
{cpuinfo_vendor_arm, cpuinfo_uarch_cortex_x1, 3000000000}}},
|
||||
/* Ampere Altra */
|
||||
[woa_chip_name_ampere_altra] = {
|
||||
L"Ampere(R) Altra(R) Processor",
|
||||
woa_chip_name_ampere_altra,
|
||||
{{cpuinfo_vendor_arm, cpuinfo_uarch_neoverse_n1, 3000000000}}}};
|
||||
static struct woa_chip_info woa_chip_unknown = {L"Unknown", {{cpuinfo_vendor_unknown, cpuinfo_uarch_unknown, 0}}};
|
||||
|
||||
BOOL CALLBACK cpuinfo_arm_windows_init(PINIT_ONCE init_once, PVOID parameter, PVOID* context) {
|
||||
struct woa_chip_info* chip_info = NULL;
|
||||
enum cpuinfo_vendor vendor = cpuinfo_vendor_unknown;
|
||||
|
||||
set_cpuinfo_isa_fields();
|
||||
|
||||
@@ -87,23 +34,6 @@ BOOL CALLBACK cpuinfo_arm_windows_init(PINIT_ONCE init_once, PVOID parameter, PV
|
||||
return true;
|
||||
}
|
||||
|
||||
bool get_core_uarch_for_efficiency(
|
||||
enum woa_chip_name chip,
|
||||
BYTE EfficiencyClass,
|
||||
enum cpuinfo_uarch* uarch,
|
||||
uint64_t* frequency) {
|
||||
/* For currently supported WoA chips, the Efficiency class selects
|
||||
* the pre-defined little and big core.
|
||||
* Any further supported SoC's logic should be implemented here.
|
||||
*/
|
||||
if (uarch && frequency && chip < woa_chip_name_last && EfficiencyClass < MAX_WOA_VALID_EFFICIENCY_CLASSES) {
|
||||
*uarch = woa_chips[chip].uarchs[EfficiencyClass].uarch;
|
||||
*frequency = woa_chips[chip].uarchs[EfficiencyClass].frequency;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Static helper functions */
|
||||
|
||||
static wchar_t* read_registry(LPCWSTR subkey, LPCWSTR value) {
|
||||
@@ -149,40 +79,132 @@ static wchar_t* read_registry(LPCWSTR subkey, LPCWSTR value) {
|
||||
return text_buffer;
|
||||
}
|
||||
|
||||
static uint64_t read_registry_qword(LPCWSTR subkey, LPCWSTR value) {
|
||||
DWORD key_type = 0;
|
||||
DWORD data_size = sizeof(uint64_t);
|
||||
const DWORD flags = RRF_RT_REG_QWORD; /* Only read QWORD (REG_QWORD) values */
|
||||
uint64_t qword_value = 0;
|
||||
LSTATUS result = RegGetValueW(HKEY_LOCAL_MACHINE, subkey, value, flags, &key_type, &qword_value, &data_size);
|
||||
if (result != ERROR_SUCCESS || data_size != sizeof(uint64_t)) {
|
||||
cpuinfo_log_error("Registry QWORD read error");
|
||||
return 0;
|
||||
}
|
||||
return qword_value;
|
||||
}
|
||||
|
||||
static uint64_t read_registry_dword(LPCWSTR subkey, LPCWSTR value) {
|
||||
DWORD key_type = 0;
|
||||
DWORD data_size = sizeof(DWORD);
|
||||
DWORD dword_value = 0;
|
||||
LSTATUS result =
|
||||
RegGetValueW(HKEY_LOCAL_MACHINE, subkey, value, RRF_RT_REG_DWORD, &key_type, &dword_value, &data_size);
|
||||
if (result != ERROR_SUCCESS || data_size != sizeof(DWORD)) {
|
||||
cpuinfo_log_error("Registry DWORD read error");
|
||||
return 0;
|
||||
}
|
||||
return (uint64_t)dword_value;
|
||||
}
|
||||
|
||||
static wchar_t* wcsndup(const wchar_t* src, size_t n) {
|
||||
size_t len = wcsnlen(src, n);
|
||||
wchar_t* dup = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (len + 1) * sizeof(wchar_t));
|
||||
if (dup) {
|
||||
wcsncpy_s(dup, len + 1, src, len);
|
||||
dup[len] = L'\0';
|
||||
}
|
||||
return dup;
|
||||
}
|
||||
|
||||
static struct core_info_by_chip_name get_core_info_from_midr(uint32_t midr, uint64_t frequency) {
|
||||
struct core_info_by_chip_name info;
|
||||
enum cpuinfo_vendor vendor;
|
||||
enum cpuinfo_uarch uarch;
|
||||
|
||||
#if CPUINFO_ARCH_ARM
|
||||
bool has_vfpv4 = false;
|
||||
cpuinfo_arm_decode_vendor_uarch(midr, has_vfpv4, &vendor, &uarch);
|
||||
#else
|
||||
cpuinfo_arm_decode_vendor_uarch(midr, &vendor, &uarch);
|
||||
#endif
|
||||
|
||||
info.vendor = vendor;
|
||||
info.uarch = uarch;
|
||||
info.frequency = frequency;
|
||||
return info;
|
||||
}
|
||||
|
||||
/* https://developer.arm.com/documentation/ddi0601/2024-06/AArch64-Registers
|
||||
CP 4000: MIDR_EL1
|
||||
CP 4020: ID_AA64PFR0_EL1
|
||||
CP 4021: ID_AA64PFR1_EL1
|
||||
CP 4028: ID_AA64DFR0_EL1
|
||||
CP 4029: ID_AA64DFR1_EL1
|
||||
CP 402C: ID_AA64AFR0_EL1
|
||||
CP 402D: ID_AA64AFR1_EL1
|
||||
CP 4030: ID_AA64ISAR0_EL1
|
||||
CP 4031: ID_AA64ISAR1_EL1
|
||||
CP 4038: ID_AA64MMFR0_EL1
|
||||
CP 4039: ID_AA64MMFR1_EL1
|
||||
CP 403A: ID_AA64MMFR2_EL1
|
||||
CP 4080: ?
|
||||
CP 4081: ?
|
||||
CP 4100: ?
|
||||
CP 4510: ?
|
||||
CP 5801: ?
|
||||
*/
|
||||
|
||||
static struct woa_chip_info* get_system_info_from_registry(void) {
|
||||
wchar_t* text_buffer = NULL;
|
||||
LPCWSTR cpu0_subkey = L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0";
|
||||
LPCWSTR chip_name_value = L"ProcessorNameString";
|
||||
LPCWSTR chip_midr_value = L"CP 4000";
|
||||
LPCWSTR chip_mhz_value = L"~MHz";
|
||||
struct woa_chip_info* chip_info = NULL;
|
||||
|
||||
HANDLE heap = GetProcessHeap();
|
||||
|
||||
/* Read processor model name from registry and find in the hard-coded
|
||||
* list. */
|
||||
text_buffer = read_registry(cpu0_subkey, chip_name_value);
|
||||
if (text_buffer == NULL) {
|
||||
cpuinfo_log_error("Registry read error");
|
||||
cpuinfo_log_error("Registry read error for processor name");
|
||||
return NULL;
|
||||
}
|
||||
for (uint32_t i = 0; i < (uint32_t)woa_chip_name_last; i++) {
|
||||
size_t compare_length = wcsnlen(woa_chips[i].chip_name_string, CPUINFO_PACKAGE_NAME_MAX);
|
||||
int compare_result = wcsncmp(text_buffer, woa_chips[i].chip_name_string, compare_length);
|
||||
if (compare_result == 0) {
|
||||
chip_info = woa_chips + i;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* https://developer.arm.com/documentation/100442/0100/register-descriptions/aarch32-system-registers/midr--main-id-register
|
||||
* Regedit for MIDR :
|
||||
*HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0\CP 4000
|
||||
*/
|
||||
uint64_t midr_qword = (uint32_t)read_registry_qword(cpu0_subkey, chip_midr_value);
|
||||
if (midr_qword == 0) {
|
||||
cpuinfo_log_error("Registry read error for MIDR value");
|
||||
return NULL;
|
||||
}
|
||||
// MIDR is only 32 bits, so we need to cast it to uint32_t
|
||||
uint32_t midr_value = (uint32_t)midr_qword;
|
||||
|
||||
/* Read the frequency from the registry
|
||||
* The value is in MHz, so we need to convert it to Hz */
|
||||
uint64_t frequency_mhz = read_registry_dword(cpu0_subkey, chip_mhz_value);
|
||||
if (frequency_mhz == 0) {
|
||||
cpuinfo_log_error("Registry read error for frequency value");
|
||||
return NULL;
|
||||
}
|
||||
// Convert MHz to Hz
|
||||
uint64_t frequency_hz = frequency_mhz * 1000000;
|
||||
|
||||
// Allocate chip_info before using it.
|
||||
chip_info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct woa_chip_info));
|
||||
if (chip_info == NULL) {
|
||||
/* No match was found, so print a warning and assign the unknown
|
||||
* case. */
|
||||
cpuinfo_log_error(
|
||||
"Unknown chip model name '%ls'.\nPlease add new Windows on Arm SoC/chip support to arm/windows/init.c!",
|
||||
text_buffer);
|
||||
} else {
|
||||
cpuinfo_log_debug("detected chip model name: %s", chip_info->chip_name_string);
|
||||
cpuinfo_log_error("Heap allocation error for chip_info");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HeapFree(heap, 0, text_buffer);
|
||||
// set chip_info fields
|
||||
chip_info->chip_name_string = wcsndup(text_buffer, CPUINFO_PACKAGE_NAME_MAX - 1);
|
||||
chip_info->uarchs[0] = get_core_info_from_midr(midr_value, frequency_hz);
|
||||
|
||||
cpuinfo_log_debug("detected chip model name: %ls", chip_info->chip_name_string);
|
||||
|
||||
return chip_info;
|
||||
}
|
||||
|
||||
@@ -192,21 +214,40 @@ static void set_cpuinfo_isa_fields(void) {
|
||||
const bool dotprod = IsProcessorFeaturePresent(PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE) != 0;
|
||||
cpuinfo_isa.dot = dotprod;
|
||||
|
||||
SYSTEM_INFO system_info;
|
||||
GetSystemInfo(&system_info);
|
||||
switch (system_info.wProcessorLevel) {
|
||||
case 0x803: // Kryo 385 Silver (Snapdragon 850)
|
||||
cpuinfo_isa.fp16arith = dotprod;
|
||||
cpuinfo_isa.rdm = dotprod;
|
||||
break;
|
||||
default:
|
||||
// Assume that Dot Product support implies FP16
|
||||
// arithmetics and RDM support. ARM manuals don't
|
||||
// guarantee that, but it holds in practice.
|
||||
cpuinfo_isa.fp16arith = dotprod;
|
||||
cpuinfo_isa.rdm = dotprod;
|
||||
break;
|
||||
}
|
||||
cpuinfo_isa.sve = IsProcessorFeaturePresent(PF_ARM_SVE_INSTRUCTIONS_AVAILABLE) != 0;
|
||||
cpuinfo_isa.sve2 = IsProcessorFeaturePresent(PF_ARM_SVE2_INSTRUCTIONS_AVAILABLE) != 0;
|
||||
cpuinfo_isa.i8mm = IsProcessorFeaturePresent(PF_ARM_V82_I8MM_INSTRUCTIONS_AVAILABLE) != 0;
|
||||
cpuinfo_isa.jscvt = IsProcessorFeaturePresent(PF_ARM_V83_JSCVT_INSTRUCTIONS_AVAILABLE) != 0;
|
||||
cpuinfo_isa.fcma = IsProcessorFeaturePresent(PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE) != 0;
|
||||
// FEAT_FP16 Implies FEAT_FHM in 8.4
|
||||
// https://developer.arm.com/documentation/109697/2025_09/Feature-descriptions/The-Armv8-4-architecture-extension?lang=en
|
||||
cpuinfo_isa.fhm = IsProcessorFeaturePresent(PF_ARM_V82_FP16_INSTRUCTIONS_AVAILABLE) != 0;
|
||||
cpuinfo_isa.fp16arith = cpuinfo_isa.fhm;
|
||||
|
||||
cpuinfo_isa.sme = IsProcessorFeaturePresent(PF_ARM_SME_INSTRUCTIONS_AVAILABLE) != 0;
|
||||
cpuinfo_isa.sme2 = IsProcessorFeaturePresent(PF_ARM_SME2_INSTRUCTIONS_AVAILABLE) != 0;
|
||||
cpuinfo_isa.sme2p1 = IsProcessorFeaturePresent(PF_ARM_SME2_1_INSTRUCTIONS_AVAILABLE) != 0;
|
||||
cpuinfo_isa.sme_b16b16 = IsProcessorFeaturePresent(PF_ARM_SME_B16B16_INSTRUCTIONS_AVAILABLE) != 0;
|
||||
cpuinfo_isa.sme_f16f16 = IsProcessorFeaturePresent(PF_ARM_SME_F16F16_INSTRUCTIONS_AVAILABLE) != 0;
|
||||
|
||||
// TODO: Add when available in Windows SDK
|
||||
// - sme_i16i32
|
||||
// - sme_bi32i32
|
||||
|
||||
cpuinfo_isa.bf16 = IsProcessorFeaturePresent(PF_ARM_V86_BF16_INSTRUCTIONS_AVAILABLE) != 0;
|
||||
|
||||
// TODO: This is not available in the Windows SDK yet , so conservatively go with the lowest value (128 bits)
|
||||
// https://developer.arm.com/documentation/101427/0102/Register-descriptions/Scalable-vector-extensions--SVE--registers/ZCR-EL1--SVE-Control-Register--EL1
|
||||
cpuinfo_isa.svelen =
|
||||
cpuinfo_isa.sve ? 128 / 8 : 0; // This value is in bytes, see cpuinfo_get_max_arm_sve_length
|
||||
|
||||
// TODO : Fetch from feature registers when available
|
||||
// cpuinfo_isa.smelen = 0;
|
||||
|
||||
// Assume that Dot Product support implies FP16
|
||||
// arithmetics and RDM support. ARM manuals don't
|
||||
// guarantee that, but it holds in practice.
|
||||
cpuinfo_isa.rdm = dotprod;
|
||||
|
||||
/* Windows API reports all or nothing for cryptographic instructions. */
|
||||
const bool crypto = IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) != 0;
|
||||
|
||||
@@ -3,17 +3,6 @@
|
||||
/* Efficiency class = 0 means little core, while 1 means big core for now. */
|
||||
#define MAX_WOA_VALID_EFFICIENCY_CLASSES 2
|
||||
|
||||
/* List of known and supported Windows on Arm SoCs/chips. */
|
||||
enum woa_chip_name {
|
||||
woa_chip_name_microsoft_sq_1 = 0,
|
||||
woa_chip_name_microsoft_sq_2 = 1,
|
||||
woa_chip_name_microsoft_sq_3 = 2,
|
||||
woa_chip_name_microsoft_sq_3_devkit = 3,
|
||||
woa_chip_name_ampere_altra = 4,
|
||||
woa_chip_name_unknown = 5,
|
||||
woa_chip_name_last = woa_chip_name_unknown
|
||||
};
|
||||
|
||||
/* Topology information hard-coded by SoC/chip name */
|
||||
struct core_info_by_chip_name {
|
||||
enum cpuinfo_vendor vendor;
|
||||
@@ -26,14 +15,67 @@ struct core_info_by_chip_name {
|
||||
*/
|
||||
struct woa_chip_info {
|
||||
wchar_t* chip_name_string;
|
||||
enum woa_chip_name chip_name;
|
||||
struct core_info_by_chip_name uarchs[MAX_WOA_VALID_EFFICIENCY_CLASSES];
|
||||
};
|
||||
|
||||
bool get_core_uarch_for_efficiency(
|
||||
enum woa_chip_name chip,
|
||||
BYTE EfficiencyClass,
|
||||
enum cpuinfo_uarch* uarch,
|
||||
uint64_t* frequency);
|
||||
|
||||
bool cpu_info_init_by_logical_sys_info(const struct woa_chip_info* chip_info, enum cpuinfo_vendor vendor);
|
||||
|
||||
#ifndef PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE
|
||||
#define PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE (27)
|
||||
#endif
|
||||
|
||||
#ifndef PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE
|
||||
#define PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE (34)
|
||||
#endif
|
||||
|
||||
#ifndef PF_ARM_V83_JSCVT_INSTRUCTIONS_AVAILABLE
|
||||
#define PF_ARM_V83_JSCVT_INSTRUCTIONS_AVAILABLE (44)
|
||||
#endif
|
||||
|
||||
#ifndef PF_ARM_SVE_INSTRUCTIONS_AVAILABLE
|
||||
#define PF_ARM_SVE_INSTRUCTIONS_AVAILABLE (46)
|
||||
#endif
|
||||
|
||||
#ifndef PF_ARM_SVE2_INSTRUCTIONS_AVAILABLE
|
||||
#define PF_ARM_SVE2_INSTRUCTIONS_AVAILABLE (47)
|
||||
#endif
|
||||
|
||||
#ifndef PF_ARM_SME_BI32I32_INSTRUCTIONS_AVAILABLE
|
||||
#define PF_ARM_SME_BI32I32_INSTRUCTIONS_AVAILABLE (55)
|
||||
#endif
|
||||
|
||||
#ifndef PF_ARM_V82_I8MM_INSTRUCTIONS_AVAILABLE
|
||||
#define PF_ARM_V82_I8MM_INSTRUCTIONS_AVAILABLE (66)
|
||||
#endif
|
||||
|
||||
#ifndef PF_ARM_V86_BF16_INSTRUCTIONS_AVAILABLE
|
||||
#define PF_ARM_V86_BF16_INSTRUCTIONS_AVAILABLE (68)
|
||||
#endif
|
||||
|
||||
#ifndef PF_ARM_SME_INSTRUCTIONS_AVAILABLE
|
||||
#define PF_ARM_SME_INSTRUCTIONS_AVAILABLE (70)
|
||||
#endif
|
||||
|
||||
#ifndef PF_ARM_SME2_INSTRUCTIONS_AVAILABLE
|
||||
#define PF_ARM_SME2_INSTRUCTIONS_AVAILABLE (71)
|
||||
#endif
|
||||
|
||||
#ifndef PF_ARM_SME2_1_INSTRUCTIONS_AVAILABLE
|
||||
#define PF_ARM_SME2_1_INSTRUCTIONS_AVAILABLE (72)
|
||||
#endif
|
||||
|
||||
#ifndef PF_ARM_SME2_2_INSTRUCTIONS_AVAILABLE
|
||||
#define PF_ARM_SME2_2_INSTRUCTIONS_AVAILABLE (73)
|
||||
#endif
|
||||
|
||||
#ifndef PF_ARM_SME_F16F16_INSTRUCTIONS_AVAILABLE
|
||||
#define PF_ARM_SME_F16F16_INSTRUCTIONS_AVAILABLE (83)
|
||||
#endif
|
||||
|
||||
#ifndef PF_ARM_SME_B16B16_INSTRUCTIONS_AVAILABLE
|
||||
#define PF_ARM_SME_B16B16_INSTRUCTIONS_AVAILABLE (84)
|
||||
#endif
|
||||
|
||||
#ifndef PF_ARM_V82_FP16_INSTRUCTIONS_AVAILABLE
|
||||
#define PF_ARM_V82_FP16_INSTRUCTIONS_AVAILABLE (67)
|
||||
#endif
|
||||
|
||||
2
3rdparty/cpuinfo/src/riscv/linux/riscv-hw.c
vendored
2
3rdparty/cpuinfo/src/riscv/linux/riscv-hw.c
vendored
@@ -112,7 +112,7 @@ void cpuinfo_riscv_linux_decode_vendor_uarch_from_hwprobe(
|
||||
*
|
||||
* for more details.
|
||||
*/
|
||||
int ret = syscall(NR_riscv_hwprobe, pairs, pairs_count, cpu_set_size, (unsigned long*)cpu_set, 0 /* flags */);
|
||||
int ret = syscall(NR_riscv_hwprobe, pairs, pairs_count, cpu_set_size, cpu_set, 0 /* flags */);
|
||||
#else
|
||||
int ret = __riscv_hwprobe(pairs, pairs_count, cpu_set_size, (unsigned long*)cpu_set, 0 /* flags */);
|
||||
#endif
|
||||
|
||||
1
3rdparty/cpuinfo/src/x86/api.h
vendored
1
3rdparty/cpuinfo/src/x86/api.h
vendored
@@ -105,6 +105,7 @@ CPUINFO_INTERNAL void cpuinfo_x86_detect_topology(
|
||||
CPUINFO_INTERNAL void cpuinfo_x86_detect_cache(
|
||||
uint32_t max_base_index,
|
||||
uint32_t max_extended_index,
|
||||
/* amd_topology_extensions is not used, kept for backward compatibility */
|
||||
bool amd_topology_extensions,
|
||||
enum cpuinfo_vendor vendor,
|
||||
const struct cpuinfo_x86_model_info* model_info,
|
||||
|
||||
2
3rdparty/cpuinfo/src/x86/cache/init.c
vendored
2
3rdparty/cpuinfo/src/x86/cache/init.c
vendored
@@ -87,7 +87,7 @@ void cpuinfo_x86_detect_cache(
|
||||
}
|
||||
}
|
||||
}
|
||||
if (amd_topology_extensions && max_extended_index >= UINT32_C(0x8000001D)) {
|
||||
if (max_extended_index >= UINT32_C(0x8000001D)) {
|
||||
struct cpuid_regs leaf0x8000001D;
|
||||
uint32_t input_ecx = 0;
|
||||
do {
|
||||
|
||||
2
3rdparty/cpuinfo/src/x86/init.c
vendored
2
3rdparty/cpuinfo/src/x86/init.c
vendored
@@ -72,7 +72,7 @@ void cpuinfo_x86_init_processor(struct cpuinfo_x86_processor* processor) {
|
||||
for (uint32_t i = 0; i < 3; i++) {
|
||||
brand_string[i] = cpuid(UINT32_C(0x80000002) + i);
|
||||
}
|
||||
memcpy(processor->brand_string, brand_string, sizeof(processor->brand_string));
|
||||
memcpy(processor->brand_string, brand_string, sizeof(brand_string));
|
||||
cpuinfo_log_debug("raw CPUID brand string: \"%48s\"", processor->brand_string);
|
||||
}
|
||||
}
|
||||
|
||||
11
3rdparty/cpuinfo/src/x86/isa.c
vendored
11
3rdparty/cpuinfo/src/x86/isa.c
vendored
@@ -46,6 +46,8 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa(
|
||||
(max_base_index >= 7) ? cpuidex(7, 0) : (struct cpuid_regs){0, 0, 0, 0};
|
||||
const struct cpuid_regs structured_feature_info1 =
|
||||
(max_base_index >= 7) ? cpuidex(7, 1) : (struct cpuid_regs){0, 0, 0, 0};
|
||||
const struct cpuid_regs structured_feature_info2 =
|
||||
(max_base_index >= 7) ? cpuidex(0x24, 0) : (struct cpuid_regs){0, 0, 0, 0};
|
||||
|
||||
const uint32_t processor_capacity_info_index = UINT32_C(0x80000008);
|
||||
const struct cpuid_regs processor_capacity_info = (max_extended_index >= processor_capacity_info_index)
|
||||
@@ -430,10 +432,17 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa(
|
||||
isa.avx512f = avx512_regs && !!(structured_feature_info0.ebx & UINT32_C(0x00010000));
|
||||
|
||||
/*
|
||||
* AVX 10.1 instructions:
|
||||
* AVX 10.1 instructions: avx 10 isa supported.
|
||||
* - Intel: edx[bit 19] in structured feature info (ecx = 1).
|
||||
*/
|
||||
isa.avx10_1 = avx512_regs && !!(structured_feature_info1.edx & UINT32_C(0x00080000));
|
||||
|
||||
/*
|
||||
* AVX 10.2 instructions: avx 10 version information.
|
||||
* - Intel: ebx[bits 0-7] in structured features info (eax = 24 ecx = 0).
|
||||
*/
|
||||
isa.avx10_2 = ((structured_feature_info2.ebx & UINT32_C(0x000000FF)) >= 2) && isa.avx10_1;
|
||||
|
||||
/*
|
||||
* AVX512PF instructions:
|
||||
* - Intel: ebx[bit 26] in structured feature info (ecx = 0).
|
||||
|
||||
10
3rdparty/cpuinfo/src/x86/linux/cpuinfo.c
vendored
10
3rdparty/cpuinfo/src/x86/linux/cpuinfo.c
vendored
@@ -80,11 +80,8 @@ struct proc_cpuinfo_parser_state {
|
||||
* Decode a single line of /proc/cpuinfo information.
|
||||
* Lines have format <words-with-spaces>[ ]*:[ ]<space-separated words>
|
||||
*/
|
||||
static bool parse_line(
|
||||
const char* line_start,
|
||||
const char* line_end,
|
||||
struct proc_cpuinfo_parser_state state[restrict static 1],
|
||||
uint64_t line_number) {
|
||||
static bool parse_line(const char* line_start, const char* line_end, void* context, uint64_t line_number) {
|
||||
struct proc_cpuinfo_parser_state* restrict state = context;
|
||||
/* Empty line. Skip. */
|
||||
if (line_start == line_end) {
|
||||
return true;
|
||||
@@ -214,6 +211,5 @@ bool cpuinfo_x86_linux_parse_proc_cpuinfo(
|
||||
.max_processors_count = max_processors_count,
|
||||
.processors = processors,
|
||||
};
|
||||
return cpuinfo_linux_parse_multiline_file(
|
||||
"/proc/cpuinfo", BUFFER_SIZE, (cpuinfo_line_callback)parse_line, &state);
|
||||
return cpuinfo_linux_parse_multiline_file("/proc/cpuinfo", BUFFER_SIZE, parse_line, &state);
|
||||
}
|
||||
|
||||
14
3rdparty/cpuinfo/src/x86/uarch.c
vendored
14
3rdparty/cpuinfo/src/x86/uarch.c
vendored
@@ -168,6 +168,9 @@ enum cpuinfo_uarch cpuinfo_x86_decode_uarch(
|
||||
case 0x7E: // Ice Lake-U
|
||||
return cpuinfo_uarch_sunny_cove;
|
||||
|
||||
case 0x8C: // Tiger U
|
||||
case 0x8D: // Tiger H
|
||||
return cpuinfo_uarch_willow_cove;
|
||||
/* Low-power cores */
|
||||
case 0x1C: // Diamondville,
|
||||
// Silverthorne,
|
||||
@@ -185,6 +188,17 @@ enum cpuinfo_uarch cpuinfo_x86_decode_uarch(
|
||||
case 0x5A: // Moorefield
|
||||
case 0x5D: // SoFIA
|
||||
return cpuinfo_uarch_silvermont;
|
||||
case 0x86: // Jasper Lake
|
||||
case 0x8A: // Lakefield
|
||||
case 0x96: // Elkhart Lake
|
||||
case 0x9C: // Jacobsville
|
||||
return cpuinfo_uarch_tremont;
|
||||
case 0xBE: // Alder Lake-N
|
||||
return cpuinfo_uarch_gracemont;
|
||||
case 0xAF: // Sierra Forest
|
||||
return cpuinfo_uarch_crestmont;
|
||||
case 0xDD: // Clearwater Forest
|
||||
return cpuinfo_uarch_darkmont;
|
||||
case 0x4C: // Braswell, Cherry
|
||||
// Trail
|
||||
case 0x75: // Spreadtrum
|
||||
|
||||
116
3rdparty/cubeb/README.md
vendored
116
3rdparty/cubeb/README.md
vendored
@@ -1,7 +1,117 @@
|
||||
# libcubeb - Cross-platform Audio I/O Library
|
||||
|
||||
[](https://github.com/mozilla/cubeb/actions/workflows/build.yml)
|
||||
|
||||
See INSTALL.md for build instructions.
|
||||
`libcubeb` is a cross-platform C library for high and low-latency audio input/output. It provides a simple, consistent API for audio playback and recording across multiple platforms and audio backends. It is written in C, C++ and Rust, with a C ABI and [Rust](https://github.com/mozilla/cubeb-rs) bindings. While originally written for use in the Firefox Web browser, a number of other software projects have adopted it.
|
||||
|
||||
See [Backend Support](https://github.com/mozilla/cubeb/wiki/Backend-Support) in the wiki for the support level of each backend.
|
||||
## Features
|
||||
|
||||
Licensed under an ISC-style license. See LICENSE for details.
|
||||
- **Cross-platform support**: Windows, macOS, Linux, Android, and other platforms
|
||||
- **Versatile**: Optimized for low-latency real-time audio applications, or power efficient higher latency playback
|
||||
- **A/V sync**: Latency compensated audio clock reporting for easy audio/video synchronization
|
||||
- **Full-duplex support**: Simultaneous audio input and output, reclocked
|
||||
- **Device enumeration**: Query available audio devices
|
||||
- **Audio processing for speech**: Can use VoiceProcessing IO on recent macOS
|
||||
|
||||
## Supported Backends & status
|
||||
|
||||
| *Backend* | *Support Level* | *Platform version* | *Notes* |
|
||||
|-------------------|-----------------|--------------------|--------------------------------------------------|
|
||||
| PulseAudio (Rust) | Tier-1 | | Main Linux desktop backend |
|
||||
| AudioUnit (Rust) | Tier-1 | | Main macOS backend |
|
||||
| WASAPI | Tier-1 | Windows >= 7 | Main Windows backend |
|
||||
| AAudio | Tier-1 | Android >= 8 | Main Android backend for most devices |
|
||||
| OpenSL | Tier-1 | Android >= 2.3 | Android backend for older devices |
|
||||
| OSS | Tier-2 | | |
|
||||
| sndio | Tier-2 | | |
|
||||
| Sun | Tier-2 | | |
|
||||
| WinMM | Tier-3 | Windows XP | Was Tier-1, Firefox minimum Windows version 7. |
|
||||
| AudioTrack | Tier-3 | Android < 2.3 | Was Tier-1, Firefox minimum Android version 4.1. |
|
||||
| ALSA | Tier-3 | | |
|
||||
| JACK | Tier-3 | | |
|
||||
| KAI | Tier-3 | | |
|
||||
| PulseAudio (C) | Tier-4 | | Was Tier-1, superseded by Rust |
|
||||
| AudioUnit (C++) | Tier-4 | | Was Tier-1, superseded by Rust |
|
||||
|
||||
Tier-1: Actively maintained. Should have CI coverage. Critical for Firefox.
|
||||
|
||||
Tier-2: Actively maintained by contributors. CI coverage appreciated.
|
||||
|
||||
Tier-3: Maintainers/patches accepted. Status unclear.
|
||||
|
||||
Tier-4: Deprecated, obsolete. Scheduled to be removed.
|
||||
|
||||
Note that the support level is not a judgement of the relative merits
|
||||
of a backend, only the current state of support, which is informed
|
||||
by Firefox's needs, the responsiveness of a backend's
|
||||
maintainer, and the level of contributions to that backend.
|
||||
|
||||
## Building
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- CMake 3.15 or later
|
||||
- Non-ancient MSVC, clang or gcc, for compiling both C and C++
|
||||
- Platform-specific audio libraries (automatically detected)
|
||||
- Optional but recommended: Rust compiler to compile and link more recent backends for macOS and PulseAudio
|
||||
|
||||
### Quick build
|
||||
|
||||
```bash
|
||||
git clone https://github.com/mozilla/cubeb.git
|
||||
cd cubeb
|
||||
cmake -B build
|
||||
cmake --build build
|
||||
```
|
||||
|
||||
### Better build with Rust backends
|
||||
|
||||
```bash
|
||||
git clone --recursive https://github.com/mozilla/cubeb.git
|
||||
cd cubeb
|
||||
cmake -B build -DBUILD_RUST_LIBS=ON
|
||||
cmake --build build
|
||||
```
|
||||
|
||||
### Platform-Specific Notes
|
||||
|
||||
**Windows**: Supports Visual Studio 2015+ and MinGW-w64. Use `-G "Visual Studio 16 2019"` or `-G "MinGW Makefiles"`.
|
||||
|
||||
**macOS**: Requires Xcode command line tools. Audio frameworks are automatically linked.
|
||||
|
||||
**Linux**: Development packages for desired backends:
|
||||
```bash
|
||||
# Ubuntu/Debian
|
||||
sudo apt-get install libpulse-dev libasound2-dev libjack-dev
|
||||
|
||||
# Fedora/RHEL
|
||||
sudo dnf install pulseaudio-libs-devel alsa-lib-devel jack-audio-connection-kit-devel
|
||||
```
|
||||
|
||||
**Android**: Use with Android NDK. AAudio requires API level 26+.
|
||||
|
||||
## Testing
|
||||
|
||||
Run the test suite:
|
||||
```bash
|
||||
cd build
|
||||
ctest
|
||||
```
|
||||
|
||||
Use the interactive test tool:
|
||||
```bash
|
||||
./cubeb-test
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
Licensed under an ISC-style license. See [LICENSE](LICENSE) for details.
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome! Please see the [contribution guidelines](CONTRIBUTING.md) and check the [issue tracker](https://github.com/mozilla/cubeb/issues).
|
||||
|
||||
## Links
|
||||
|
||||
- [GitHub Repository](https://github.com/mozilla/cubeb)
|
||||
- [API Documentation](https://mozilla.github.io/cubeb/)
|
||||
|
||||
97
3rdparty/cubeb/include/cubeb/cubeb.h
vendored
97
3rdparty/cubeb/include/cubeb/cubeb.h
vendored
@@ -49,6 +49,7 @@ extern "C" {
|
||||
output_params.channels = 2;
|
||||
output_params.layout = CUBEB_LAYOUT_UNDEFINED;
|
||||
output_params.prefs = CUBEB_STREAM_PREF_NONE;
|
||||
output_params.input_params = CUBEB_INPUT_PROCESSING_PARAM_NONE;
|
||||
|
||||
rv = cubeb_get_min_latency(app_ctx, &output_params, &latency_frames);
|
||||
if (rv != CUBEB_OK) {
|
||||
@@ -62,6 +63,7 @@ extern "C" {
|
||||
input_params.channels = 1;
|
||||
input_params.layout = CUBEB_LAYOUT_UNDEFINED;
|
||||
input_params.prefs = CUBEB_STREAM_PREF_NONE;
|
||||
input_params.input_params = CUBEB_INPUT_PROCESSING_PARAM_NONE;
|
||||
|
||||
cubeb_stream * stm;
|
||||
rv = cubeb_stream_init(app_ctx, &stm, "Example Stream 1",
|
||||
@@ -193,39 +195,39 @@ typedef uint32_t cubeb_channel_layout;
|
||||
// Some common layout definitions.
|
||||
enum {
|
||||
CUBEB_LAYOUT_UNDEFINED = 0, // Indicate the speaker's layout is undefined.
|
||||
CUBEB_LAYOUT_MONO = (uint32_t)CHANNEL_FRONT_CENTER,
|
||||
CUBEB_LAYOUT_MONO_LFE = (uint32_t)CUBEB_LAYOUT_MONO | (uint32_t)CHANNEL_LOW_FREQUENCY,
|
||||
CUBEB_LAYOUT_STEREO = (uint32_t)CHANNEL_FRONT_LEFT | (uint32_t)CHANNEL_FRONT_RIGHT,
|
||||
CUBEB_LAYOUT_STEREO_LFE = (uint32_t)CUBEB_LAYOUT_STEREO | (uint32_t)CHANNEL_LOW_FREQUENCY,
|
||||
CUBEB_LAYOUT_MONO = CHANNEL_FRONT_CENTER,
|
||||
CUBEB_LAYOUT_MONO_LFE = CUBEB_LAYOUT_MONO | CHANNEL_LOW_FREQUENCY,
|
||||
CUBEB_LAYOUT_STEREO = CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT,
|
||||
CUBEB_LAYOUT_STEREO_LFE = CUBEB_LAYOUT_STEREO | CHANNEL_LOW_FREQUENCY,
|
||||
CUBEB_LAYOUT_3F =
|
||||
(uint32_t)CHANNEL_FRONT_LEFT | (uint32_t)CHANNEL_FRONT_RIGHT | (uint32_t)CHANNEL_FRONT_CENTER,
|
||||
CUBEB_LAYOUT_3F_LFE = (uint32_t)CUBEB_LAYOUT_3F | (uint32_t)CHANNEL_LOW_FREQUENCY,
|
||||
CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | CHANNEL_FRONT_CENTER,
|
||||
CUBEB_LAYOUT_3F_LFE = CUBEB_LAYOUT_3F | CHANNEL_LOW_FREQUENCY,
|
||||
CUBEB_LAYOUT_2F1 =
|
||||
(uint32_t)CHANNEL_FRONT_LEFT | (uint32_t)CHANNEL_FRONT_RIGHT | (uint32_t)CHANNEL_BACK_CENTER,
|
||||
CUBEB_LAYOUT_2F1_LFE = (uint32_t)CUBEB_LAYOUT_2F1 | (uint32_t)CHANNEL_LOW_FREQUENCY,
|
||||
CUBEB_LAYOUT_3F1 = (uint32_t)CHANNEL_FRONT_LEFT | (uint32_t)CHANNEL_FRONT_RIGHT |
|
||||
(uint32_t)CHANNEL_FRONT_CENTER | (uint32_t)CHANNEL_BACK_CENTER,
|
||||
CUBEB_LAYOUT_3F1_LFE = (uint32_t)CUBEB_LAYOUT_3F1 | (uint32_t)CHANNEL_LOW_FREQUENCY,
|
||||
CUBEB_LAYOUT_2F2 = (uint32_t)CHANNEL_FRONT_LEFT | (uint32_t)CHANNEL_FRONT_RIGHT |
|
||||
(uint32_t)CHANNEL_SIDE_LEFT | (uint32_t)CHANNEL_SIDE_RIGHT,
|
||||
CUBEB_LAYOUT_2F2_LFE = (uint32_t)CUBEB_LAYOUT_2F2 | (uint32_t)CHANNEL_LOW_FREQUENCY,
|
||||
CUBEB_LAYOUT_QUAD = (uint32_t)CHANNEL_FRONT_LEFT | (uint32_t)CHANNEL_FRONT_RIGHT |
|
||||
(uint32_t)CHANNEL_BACK_LEFT | (uint32_t)CHANNEL_BACK_RIGHT,
|
||||
CUBEB_LAYOUT_QUAD_LFE = (uint32_t)CUBEB_LAYOUT_QUAD | (uint32_t)CHANNEL_LOW_FREQUENCY,
|
||||
CUBEB_LAYOUT_3F2 = (uint32_t)CHANNEL_FRONT_LEFT | (uint32_t)CHANNEL_FRONT_RIGHT |
|
||||
(uint32_t)CHANNEL_FRONT_CENTER | (uint32_t)CHANNEL_SIDE_LEFT |
|
||||
(uint32_t)CHANNEL_SIDE_RIGHT,
|
||||
CUBEB_LAYOUT_3F2_LFE = (uint32_t)CUBEB_LAYOUT_3F2 | (uint32_t)CHANNEL_LOW_FREQUENCY,
|
||||
CUBEB_LAYOUT_3F2_BACK = (uint32_t)CUBEB_LAYOUT_QUAD | (uint32_t)CHANNEL_FRONT_CENTER,
|
||||
CUBEB_LAYOUT_3F2_LFE_BACK = (uint32_t)CUBEB_LAYOUT_3F2_BACK | (uint32_t)CHANNEL_LOW_FREQUENCY,
|
||||
CUBEB_LAYOUT_3F3R_LFE = (uint32_t)CHANNEL_FRONT_LEFT | (uint32_t)CHANNEL_FRONT_RIGHT |
|
||||
(uint32_t)CHANNEL_FRONT_CENTER | (uint32_t)CHANNEL_LOW_FREQUENCY |
|
||||
(uint32_t)CHANNEL_BACK_CENTER | (uint32_t)CHANNEL_SIDE_LEFT |
|
||||
(uint32_t)CHANNEL_SIDE_RIGHT,
|
||||
CUBEB_LAYOUT_3F4_LFE = (uint32_t)CHANNEL_FRONT_LEFT | (uint32_t)CHANNEL_FRONT_RIGHT |
|
||||
(uint32_t)CHANNEL_FRONT_CENTER | (uint32_t)CHANNEL_LOW_FREQUENCY |
|
||||
(uint32_t)CHANNEL_BACK_LEFT | (uint32_t)CHANNEL_BACK_RIGHT |
|
||||
(uint32_t)CHANNEL_SIDE_LEFT | (uint32_t)CHANNEL_SIDE_RIGHT,
|
||||
CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | CHANNEL_BACK_CENTER,
|
||||
CUBEB_LAYOUT_2F1_LFE = CUBEB_LAYOUT_2F1 | CHANNEL_LOW_FREQUENCY,
|
||||
CUBEB_LAYOUT_3F1 = CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
|
||||
CHANNEL_FRONT_CENTER | CHANNEL_BACK_CENTER,
|
||||
CUBEB_LAYOUT_3F1_LFE = CUBEB_LAYOUT_3F1 | CHANNEL_LOW_FREQUENCY,
|
||||
CUBEB_LAYOUT_2F2 = CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
|
||||
CHANNEL_SIDE_LEFT | CHANNEL_SIDE_RIGHT,
|
||||
CUBEB_LAYOUT_2F2_LFE = CUBEB_LAYOUT_2F2 | CHANNEL_LOW_FREQUENCY,
|
||||
CUBEB_LAYOUT_QUAD = CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
|
||||
CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT,
|
||||
CUBEB_LAYOUT_QUAD_LFE = CUBEB_LAYOUT_QUAD | CHANNEL_LOW_FREQUENCY,
|
||||
CUBEB_LAYOUT_3F2 = CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
|
||||
CHANNEL_FRONT_CENTER | CHANNEL_SIDE_LEFT |
|
||||
CHANNEL_SIDE_RIGHT,
|
||||
CUBEB_LAYOUT_3F2_LFE = CUBEB_LAYOUT_3F2 | CHANNEL_LOW_FREQUENCY,
|
||||
CUBEB_LAYOUT_3F2_BACK = CUBEB_LAYOUT_QUAD | CHANNEL_FRONT_CENTER,
|
||||
CUBEB_LAYOUT_3F2_LFE_BACK = CUBEB_LAYOUT_3F2_BACK | CHANNEL_LOW_FREQUENCY,
|
||||
CUBEB_LAYOUT_3F3R_LFE = CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
|
||||
CHANNEL_FRONT_CENTER | CHANNEL_LOW_FREQUENCY |
|
||||
CHANNEL_BACK_CENTER | CHANNEL_SIDE_LEFT |
|
||||
CHANNEL_SIDE_RIGHT,
|
||||
CUBEB_LAYOUT_3F4_LFE = CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT |
|
||||
CHANNEL_FRONT_CENTER | CHANNEL_LOW_FREQUENCY |
|
||||
CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT |
|
||||
CHANNEL_SIDE_LEFT | CHANNEL_SIDE_RIGHT,
|
||||
};
|
||||
|
||||
/** Miscellaneous stream preferences. */
|
||||
@@ -279,7 +281,10 @@ typedef struct {
|
||||
cubeb_channel_layout
|
||||
layout; /**< Requested channel layout. This must be consistent with the
|
||||
provided channels. CUBEB_LAYOUT_UNDEFINED if unknown */
|
||||
cubeb_stream_prefs prefs; /**< Requested preferences. */
|
||||
cubeb_stream_prefs prefs; /**< Requested preferences. */
|
||||
cubeb_input_processing_params input_params; /**< Requested input processing
|
||||
params. Ignored for output streams. At present, only supported on the
|
||||
WASAPI backend; others should use cubeb_set_input_processing_params. */
|
||||
} cubeb_stream_params;
|
||||
|
||||
/** Audio device description */
|
||||
@@ -414,6 +419,13 @@ typedef struct {
|
||||
size_t count; /**< Device count in collection. */
|
||||
} cubeb_device_collection;
|
||||
|
||||
/** Array of compiled backends returned by `cubeb_get_backend_names`. */
|
||||
typedef struct {
|
||||
const char * const *
|
||||
names; /**< Array of strings representing backend names. */
|
||||
size_t count; /**< Length of the array. */
|
||||
} cubeb_backend_names;
|
||||
|
||||
/** User supplied data callback.
|
||||
- Calling other cubeb functions from this callback is unsafe.
|
||||
- The code in the callback should be non-blocking.
|
||||
@@ -454,6 +466,8 @@ typedef void (*cubeb_device_changed_callback)(void * user_ptr);
|
||||
|
||||
/**
|
||||
* User supplied callback called when the underlying device collection changed.
|
||||
* This callback will be called when devices are added or removed from the
|
||||
* system, or when the default device changes for the specified device type.
|
||||
* @param context A pointer to the cubeb context.
|
||||
* @param user_ptr The pointer passed to
|
||||
* cubeb_register_device_collection_changed. */
|
||||
@@ -485,17 +499,18 @@ CUBEB_EXPORT int
|
||||
cubeb_init(cubeb ** context, char const * context_name,
|
||||
char const * backend_name);
|
||||
|
||||
/** Returns a list of backend names which can be supplid to cubeb_init().
|
||||
Array is null-terminated. */
|
||||
CUBEB_EXPORT const char**
|
||||
cubeb_get_backend_names();
|
||||
|
||||
/** Get a read-only string identifying this context's current backend.
|
||||
@param context A pointer to the cubeb context.
|
||||
@retval Read-only string identifying current backend. */
|
||||
CUBEB_EXPORT char const *
|
||||
cubeb_get_backend_id(cubeb * context);
|
||||
|
||||
/** Get a read-only array of strings identifying available backends.
|
||||
These can be passed as `backend_name` parameter to `cubeb_init`.
|
||||
@retval Struct containing the array with backend names. */
|
||||
CUBEB_EXPORT cubeb_backend_names
|
||||
cubeb_get_backend_names();
|
||||
|
||||
/** Get the maximum possible number of channels.
|
||||
@param context A pointer to the cubeb context.
|
||||
@param max_channels The maximum number of channels.
|
||||
@@ -674,7 +689,7 @@ cubeb_stream_get_current_device(cubeb_stream * stm,
|
||||
application is accessing audio input. When all inputs are muted they can
|
||||
prove to the user that the application is not actively capturing any input.
|
||||
@param stream the stream for which to set input mute state
|
||||
@param muted whether the input should mute or not
|
||||
@param mute whether the input should mute or not
|
||||
@retval CUBEB_OK
|
||||
@retval CUBEB_ERROR_INVALID_PARAMETER if this stream does not have an input
|
||||
device
|
||||
@@ -745,14 +760,16 @@ cubeb_device_collection_destroy(cubeb * context,
|
||||
cubeb_device_collection * collection);
|
||||
|
||||
/** Registers a callback which is called when the system detects
|
||||
a new device or a device is removed.
|
||||
a new device or a device is removed, or when the default device
|
||||
changes for the specified device type.
|
||||
@param context
|
||||
@param devtype device type to include. Different callbacks and user pointers
|
||||
can be registered for each devtype. The hybrid devtype
|
||||
`CUBEB_DEVICE_TYPE_INPUT | CUBEB_DEVICE_TYPE_OUTPUT` is also valid
|
||||
and will register the provided callback and user pointer in both
|
||||
sides.
|
||||
@param callback a function called whenever the system device list changes.
|
||||
@param callback a function called whenever the system device list changes,
|
||||
including when default devices change.
|
||||
Passing NULL allow to unregister a function. You have to unregister
|
||||
first before you register a new callback.
|
||||
@param user_ptr pointer to user specified data which will be present in
|
||||
|
||||
125
3rdparty/cubeb/src/cubeb.c
vendored
125
3rdparty/cubeb/src/cubeb.c
vendored
@@ -31,6 +31,10 @@ struct cubeb_stream {
|
||||
int
|
||||
pulse_init(cubeb ** context, char const * context_name);
|
||||
#endif
|
||||
#if defined(USE_PULSE_RUST)
|
||||
int
|
||||
pulse_rust_init(cubeb ** contet, char const * context_name);
|
||||
#endif
|
||||
#if defined(USE_JACK)
|
||||
int
|
||||
jack_init(cubeb ** context, char const * context_name);
|
||||
@@ -43,6 +47,10 @@ alsa_init(cubeb ** context, char const * context_name);
|
||||
int
|
||||
audiounit_init(cubeb ** context, char const * context_name);
|
||||
#endif
|
||||
#if defined(USE_AUDIOUNIT_RUST)
|
||||
int
|
||||
audiounit_rust_init(cubeb ** contet, char const * context_name);
|
||||
#endif
|
||||
#if defined(USE_WINMM)
|
||||
int
|
||||
winmm_init(cubeb ** context, char const * context_name);
|
||||
@@ -55,10 +63,30 @@ wasapi_init(cubeb ** context, char const * context_name);
|
||||
int
|
||||
sndio_init(cubeb ** context, char const * context_name);
|
||||
#endif
|
||||
#if defined(USE_SUN)
|
||||
int
|
||||
sun_init(cubeb ** context, char const * context_name);
|
||||
#endif
|
||||
#if defined(USE_OPENSL)
|
||||
int
|
||||
opensl_init(cubeb ** context, char const * context_name);
|
||||
#endif
|
||||
#if defined(USE_OSS)
|
||||
int
|
||||
oss_init(cubeb ** context, char const * context_name);
|
||||
#endif
|
||||
#if defined(USE_AAUDIO)
|
||||
int
|
||||
aaudio_init(cubeb ** context, char const * context_name);
|
||||
#endif
|
||||
#if defined(USE_AUDIOTRACK)
|
||||
int
|
||||
audiotrack_init(cubeb ** context, char const * context_name);
|
||||
#endif
|
||||
#if defined(USE_KAI)
|
||||
int
|
||||
kai_init(cubeb ** context, char const * context_name);
|
||||
#endif
|
||||
|
||||
static int
|
||||
validate_stream_params(cubeb_stream_params * input_stream_params,
|
||||
@@ -123,6 +151,10 @@ cubeb_init(cubeb ** context, char const * context_name,
|
||||
if (!strcmp(backend_name, "pulse")) {
|
||||
#if defined(USE_PULSE)
|
||||
init_oneshot = pulse_init;
|
||||
#endif
|
||||
} else if (!strcmp(backend_name, "pulse-rust")) {
|
||||
#if defined(USE_PULSE_RUST)
|
||||
init_oneshot = pulse_rust_init;
|
||||
#endif
|
||||
} else if (!strcmp(backend_name, "jack")) {
|
||||
#if defined(USE_JACK)
|
||||
@@ -135,6 +167,10 @@ cubeb_init(cubeb ** context, char const * context_name,
|
||||
} else if (!strcmp(backend_name, "audiounit")) {
|
||||
#if defined(USE_AUDIOUNIT)
|
||||
init_oneshot = audiounit_init;
|
||||
#endif
|
||||
} else if (!strcmp(backend_name, "audiounit-rust")) {
|
||||
#if defined(USE_AUDIOUNIT_RUST)
|
||||
init_oneshot = audiounit_rust_init;
|
||||
#endif
|
||||
} else if (!strcmp(backend_name, "wasapi")) {
|
||||
#if defined(USE_WASAPI)
|
||||
@@ -147,10 +183,30 @@ cubeb_init(cubeb ** context, char const * context_name,
|
||||
} else if (!strcmp(backend_name, "sndio")) {
|
||||
#if defined(USE_SNDIO)
|
||||
init_oneshot = sndio_init;
|
||||
#endif
|
||||
} else if (!strcmp(backend_name, "sun")) {
|
||||
#if defined(USE_SUN)
|
||||
init_oneshot = sun_init;
|
||||
#endif
|
||||
} else if (!strcmp(backend_name, "opensl")) {
|
||||
#if defined(USE_OPENSL)
|
||||
init_oneshot = opensl_init;
|
||||
#endif
|
||||
} else if (!strcmp(backend_name, "oss")) {
|
||||
#if defined(USE_OSS)
|
||||
init_oneshot = oss_init;
|
||||
#endif
|
||||
} else if (!strcmp(backend_name, "aaudio")) {
|
||||
#if defined(USE_AAUDIO)
|
||||
init_oneshot = aaudio_init;
|
||||
#endif
|
||||
} else if (!strcmp(backend_name, "audiotrack")) {
|
||||
#if defined(USE_AUDIOTRACK)
|
||||
init_oneshot = audiotrack_init;
|
||||
#endif
|
||||
} else if (!strcmp(backend_name, "kai")) {
|
||||
#if defined(USE_KAI)
|
||||
init_oneshot = kai_init;
|
||||
#endif
|
||||
} else {
|
||||
/* Already set */
|
||||
@@ -163,6 +219,9 @@ cubeb_init(cubeb ** context, char const * context_name,
|
||||
* to override all other choices
|
||||
*/
|
||||
init_oneshot,
|
||||
#if defined(USE_PULSE_RUST)
|
||||
pulse_rust_init,
|
||||
#endif
|
||||
#if defined(USE_PULSE)
|
||||
pulse_init,
|
||||
#endif
|
||||
@@ -178,6 +237,9 @@ cubeb_init(cubeb ** context, char const * context_name,
|
||||
#if defined(USE_OSS)
|
||||
oss_init,
|
||||
#endif
|
||||
#if defined(USE_AUDIOUNIT_RUST)
|
||||
audiounit_rust_init,
|
||||
#endif
|
||||
#if defined(USE_AUDIOUNIT)
|
||||
audiounit_init,
|
||||
#endif
|
||||
@@ -189,6 +251,18 @@ cubeb_init(cubeb ** context, char const * context_name,
|
||||
#endif
|
||||
#if defined(USE_SUN)
|
||||
sun_init,
|
||||
#endif
|
||||
#if defined(USE_AAUDIO)
|
||||
aaudio_init,
|
||||
#endif
|
||||
#if defined(USE_OPENSL)
|
||||
opensl_init,
|
||||
#endif
|
||||
#if defined(USE_AUDIOTRACK)
|
||||
audiotrack_init,
|
||||
#endif
|
||||
#if defined(USE_KAI)
|
||||
kai_init,
|
||||
#endif
|
||||
};
|
||||
int i;
|
||||
@@ -214,13 +288,26 @@ cubeb_init(cubeb ** context, char const * context_name,
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
const char**
|
||||
char const *
|
||||
cubeb_get_backend_id(cubeb * context)
|
||||
{
|
||||
if (!context) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return context->ops->get_backend_id(context);
|
||||
}
|
||||
|
||||
cubeb_backend_names
|
||||
cubeb_get_backend_names()
|
||||
{
|
||||
static const char* backend_names[] = {
|
||||
static const char * const backend_names[] = {
|
||||
#if defined(USE_PULSE)
|
||||
"pulse",
|
||||
#endif
|
||||
#if defined(USE_PULSE_RUST)
|
||||
"pulse-rust",
|
||||
#endif
|
||||
#if defined(USE_JACK)
|
||||
"jack",
|
||||
#endif
|
||||
@@ -230,6 +317,9 @@ cubeb_get_backend_names()
|
||||
#if defined(USE_AUDIOUNIT)
|
||||
"audiounit",
|
||||
#endif
|
||||
#if defined(USE_AUDIOUNIT_RUST)
|
||||
"audiounit-rust",
|
||||
#endif
|
||||
#if defined(USE_WASAPI)
|
||||
"wasapi",
|
||||
#endif
|
||||
@@ -239,23 +329,30 @@ cubeb_get_backend_names()
|
||||
#if defined(USE_SNDIO)
|
||||
"sndio",
|
||||
#endif
|
||||
#if defined(USE_SUN)
|
||||
"sun",
|
||||
#endif
|
||||
#if defined(USE_OPENSL)
|
||||
"opensl",
|
||||
#endif
|
||||
#if defined(USE_OSS)
|
||||
"oss",
|
||||
#endif
|
||||
NULL,
|
||||
#if defined(USE_AAUDIO)
|
||||
"aaudio",
|
||||
#endif
|
||||
#if defined(USE_AUDIOTRACK)
|
||||
"audiotrack",
|
||||
#endif
|
||||
#if defined(USE_KAI)
|
||||
"kai",
|
||||
#endif
|
||||
};
|
||||
|
||||
return backend_names;
|
||||
}
|
||||
|
||||
char const *
|
||||
cubeb_get_backend_id(cubeb * context)
|
||||
{
|
||||
if (!context) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return context->ops->get_backend_id(context);
|
||||
return (cubeb_backend_names){
|
||||
.names = backend_names,
|
||||
.count = NELEMS(backend_names),
|
||||
};
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
17
3rdparty/cubeb/src/cubeb_audiounit.cpp
vendored
17
3rdparty/cubeb/src/cubeb_audiounit.cpp
vendored
@@ -213,12 +213,19 @@ struct cubeb_stream {
|
||||
cubeb_device_changed_callback device_changed_callback = nullptr;
|
||||
owned_critical_section device_changed_callback_lock;
|
||||
/* Stream creation parameters */
|
||||
cubeb_stream_params input_stream_params = {CUBEB_SAMPLE_FLOAT32NE, 0, 0,
|
||||
cubeb_stream_params input_stream_params = {CUBEB_SAMPLE_FLOAT32NE,
|
||||
0,
|
||||
0,
|
||||
CUBEB_LAYOUT_UNDEFINED,
|
||||
CUBEB_STREAM_PREF_NONE};
|
||||
cubeb_stream_params output_stream_params = {CUBEB_SAMPLE_FLOAT32NE, 0, 0,
|
||||
CUBEB_LAYOUT_UNDEFINED,
|
||||
CUBEB_STREAM_PREF_NONE};
|
||||
CUBEB_STREAM_PREF_NONE,
|
||||
CUBEB_INPUT_PROCESSING_PARAM_NONE};
|
||||
cubeb_stream_params output_stream_params = {
|
||||
CUBEB_SAMPLE_FLOAT32NE,
|
||||
0,
|
||||
0,
|
||||
CUBEB_LAYOUT_UNDEFINED,
|
||||
CUBEB_STREAM_PREF_NONE,
|
||||
CUBEB_INPUT_PROCESSING_PARAM_NONE};
|
||||
device_info input_device;
|
||||
device_info output_device;
|
||||
/* Format descriptions */
|
||||
|
||||
161
3rdparty/cubeb/src/cubeb_log.cpp
vendored
161
3rdparty/cubeb/src/cubeb_log.cpp
vendored
@@ -16,8 +16,8 @@
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
static std::atomic<cubeb_log_level> g_cubeb_log_level;
|
||||
static std::atomic<cubeb_log_callback> g_cubeb_log_callback;
|
||||
std::atomic<cubeb_log_level> g_cubeb_log_level;
|
||||
std::atomic<cubeb_log_callback> g_cubeb_log_callback;
|
||||
|
||||
/** The maximum size of a log message, after having been formatted. */
|
||||
const size_t CUBEB_LOG_MESSAGE_MAX_SIZE = 256;
|
||||
@@ -32,6 +32,133 @@ cubeb_noop_log_callback(char const * /* fmt */, ...)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This wraps an inline buffer, that represents a log message, that must be
|
||||
* null-terminated.
|
||||
* This class should not use system calls or other potentially blocking code.
|
||||
*/
|
||||
class cubeb_log_message {
|
||||
public:
|
||||
cubeb_log_message() { *storage = '\0'; }
|
||||
cubeb_log_message(char const str[CUBEB_LOG_MESSAGE_MAX_SIZE])
|
||||
{
|
||||
size_t length = strlen(str);
|
||||
/* paranoia against malformed message */
|
||||
assert(length < CUBEB_LOG_MESSAGE_MAX_SIZE);
|
||||
if (length > CUBEB_LOG_MESSAGE_MAX_SIZE - 1) {
|
||||
return;
|
||||
}
|
||||
PodCopy(storage, str, length);
|
||||
storage[length] = '\0';
|
||||
}
|
||||
char const * get() { return storage; }
|
||||
|
||||
private:
|
||||
char storage[CUBEB_LOG_MESSAGE_MAX_SIZE]{};
|
||||
};
|
||||
|
||||
/** Lock-free asynchronous logger, made so that logging from a
|
||||
* real-time audio callback does not block the audio thread. */
|
||||
class cubeb_async_logger {
|
||||
public:
|
||||
/* This is thread-safe since C++11 */
|
||||
static cubeb_async_logger & get()
|
||||
{
|
||||
static cubeb_async_logger instance;
|
||||
return instance;
|
||||
}
|
||||
void push(char const str[CUBEB_LOG_MESSAGE_MAX_SIZE])
|
||||
{
|
||||
cubeb_log_message msg(str);
|
||||
auto * owned_queue = msg_queue.load();
|
||||
// Check if the queue is being deallocated. If not, grab ownership. If yes,
|
||||
// return, the message won't be logged.
|
||||
if (!owned_queue ||
|
||||
!msg_queue.compare_exchange_strong(owned_queue, nullptr)) {
|
||||
return;
|
||||
}
|
||||
owned_queue->enqueue(msg);
|
||||
// Return ownership.
|
||||
msg_queue.store(owned_queue);
|
||||
}
|
||||
void run()
|
||||
{
|
||||
assert(logging_thread.get_id() == std::thread::id());
|
||||
logging_thread = std::thread([this]() {
|
||||
CUBEB_REGISTER_THREAD("cubeb_log");
|
||||
while (!shutdown_thread) {
|
||||
cubeb_log_message msg;
|
||||
while (msg_queue_consumer.load()->dequeue(&msg, 1)) {
|
||||
cubeb_log_internal_no_format(msg.get());
|
||||
}
|
||||
std::this_thread::sleep_for(
|
||||
std::chrono::milliseconds(CUBEB_LOG_BATCH_PRINT_INTERVAL_MS));
|
||||
}
|
||||
CUBEB_UNREGISTER_THREAD();
|
||||
});
|
||||
}
|
||||
// Tell the underlying queue the producer thread has changed, so it does not
|
||||
// assert in debug. This should be called with the thread stopped.
|
||||
void reset_producer_thread()
|
||||
{
|
||||
if (msg_queue) {
|
||||
msg_queue.load()->reset_thread_ids();
|
||||
}
|
||||
}
|
||||
void start()
|
||||
{
|
||||
auto * queue =
|
||||
new lock_free_queue<cubeb_log_message>(CUBEB_LOG_MESSAGE_QUEUE_DEPTH);
|
||||
msg_queue.store(queue);
|
||||
msg_queue_consumer.store(queue);
|
||||
shutdown_thread = false;
|
||||
run();
|
||||
}
|
||||
void stop()
|
||||
{
|
||||
assert(((g_cubeb_log_callback == cubeb_noop_log_callback) ||
|
||||
!g_cubeb_log_callback) &&
|
||||
"Only call stop after logging has been disabled.");
|
||||
shutdown_thread = true;
|
||||
if (logging_thread.get_id() != std::thread::id()) {
|
||||
logging_thread.join();
|
||||
logging_thread = std::thread();
|
||||
auto * owned_queue = msg_queue.load();
|
||||
// Check if the queue is being used. If not, grab ownership. If yes,
|
||||
// try again shortly. At this point, the logging thread has been joined,
|
||||
// so nothing is going to dequeue.
|
||||
// If there is a valid pointer here, then the real-time audio thread that
|
||||
// logs won't attempt to write into the queue, and instead drop the
|
||||
// message.
|
||||
while (!msg_queue.compare_exchange_weak(owned_queue, nullptr)) {
|
||||
}
|
||||
delete owned_queue;
|
||||
msg_queue_consumer.store(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
cubeb_async_logger() {}
|
||||
~cubeb_async_logger()
|
||||
{
|
||||
assert(logging_thread.get_id() == std::thread::id() &&
|
||||
(g_cubeb_log_callback == cubeb_noop_log_callback ||
|
||||
!g_cubeb_log_callback));
|
||||
if (msg_queue.load()) {
|
||||
delete msg_queue.load();
|
||||
}
|
||||
}
|
||||
/** This is quite a big data structure, but is only instantiated if the
|
||||
* asynchronous logger is used. The two pointers point to the same object, but
|
||||
* the first one can be temporarily null when a message is being enqueued. */
|
||||
std::atomic<lock_free_queue<cubeb_log_message> *> msg_queue = {nullptr};
|
||||
|
||||
std::atomic<lock_free_queue<cubeb_log_message> *> msg_queue_consumer = {
|
||||
nullptr};
|
||||
std::atomic<bool> shutdown_thread = {false};
|
||||
std::thread logging_thread;
|
||||
};
|
||||
|
||||
void
|
||||
cubeb_log_internal(char const * file, uint32_t line, char const * fmt, ...)
|
||||
{
|
||||
@@ -49,6 +176,29 @@ cubeb_log_internal_no_format(const char * msg)
|
||||
g_cubeb_log_callback.load()(msg);
|
||||
}
|
||||
|
||||
void
|
||||
cubeb_async_log(char const * fmt, ...)
|
||||
{
|
||||
// This is going to copy a 256 bytes array around, which is fine.
|
||||
// We don't want to allocate memory here, because this is made to
|
||||
// be called from a real-time callback.
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
char msg[CUBEB_LOG_MESSAGE_MAX_SIZE];
|
||||
vsnprintf(msg, CUBEB_LOG_MESSAGE_MAX_SIZE, fmt, args);
|
||||
cubeb_async_logger::get().push(msg);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void
|
||||
cubeb_async_log_reset_threads(void)
|
||||
{
|
||||
if (!g_cubeb_log_callback) {
|
||||
return;
|
||||
}
|
||||
cubeb_async_logger::get().reset_producer_thread();
|
||||
}
|
||||
|
||||
void
|
||||
cubeb_log_set(cubeb_log_level log_level, cubeb_log_callback log_callback)
|
||||
{
|
||||
@@ -57,8 +207,15 @@ cubeb_log_set(cubeb_log_level log_level, cubeb_log_callback log_callback)
|
||||
// nullptr, to prevent a TOCTOU race between checking the pointer
|
||||
if (log_callback && log_level != CUBEB_LOG_DISABLED) {
|
||||
g_cubeb_log_callback = log_callback;
|
||||
if (log_level == CUBEB_LOG_VERBOSE) {
|
||||
cubeb_async_logger::get().start();
|
||||
}
|
||||
} else if (!log_callback || CUBEB_LOG_DISABLED) {
|
||||
g_cubeb_log_callback = cubeb_noop_log_callback;
|
||||
// This returns once the thread has joined.
|
||||
// This is safe even if CUBEB_LOG_VERBOSE was not set; the thread will
|
||||
// simply not be joinable.
|
||||
cubeb_async_logger::get().stop();
|
||||
} else {
|
||||
assert(false && "Incorrect parameters passed to cubeb_log_set");
|
||||
}
|
||||
|
||||
18
3rdparty/cubeb/src/cubeb_log.h
vendored
18
3rdparty/cubeb/src/cubeb_log.h
vendored
@@ -39,7 +39,12 @@ cubeb_log_get_callback(void);
|
||||
void
|
||||
cubeb_log_internal_no_format(const char * msg);
|
||||
void
|
||||
cubeb_log_internal(const char * filename, uint32_t line, const char * fmt, ...);
|
||||
cubeb_log_internal(const char * filename, uint32_t line, const char * fmt, ...)
|
||||
PRINTF_FORMAT(3, 4);
|
||||
void
|
||||
cubeb_async_log(const char * fmt, ...) PRINTF_FORMAT(1, 2);
|
||||
void
|
||||
cubeb_async_log_reset_threads(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
@@ -55,9 +60,16 @@ cubeb_log_internal(const char * filename, uint32_t line, const char * fmt, ...);
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define ALOG_INTERNAL(level, fmt, ...) \
|
||||
do { \
|
||||
if (cubeb_log_get_level() >= level && cubeb_log_get_callback()) { \
|
||||
cubeb_async_log(fmt, ##__VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Asynchronous logging macros to log in real-time callbacks. */
|
||||
/* Should not be used on android due to the use of global/static variables. */
|
||||
#define ALOGV(msg, ...) LOG_INTERNAL(CUBEB_LOG_VERBOSE, msg, ##__VA_ARGS__)
|
||||
#define ALOG(msg, ...) LOG_INTERNAL(CUBEB_LOG_NORMAL, msg, ##__VA_ARGS__)
|
||||
#define ALOGV(msg, ...) ALOG_INTERNAL(CUBEB_LOG_VERBOSE, msg, ##__VA_ARGS__)
|
||||
#define ALOG(msg, ...) ALOG_INTERNAL(CUBEB_LOG_NORMAL, msg, ##__VA_ARGS__)
|
||||
|
||||
#endif // CUBEB_LOG
|
||||
|
||||
6
3rdparty/cubeb/src/cubeb_resampler.cpp
vendored
6
3rdparty/cubeb/src/cubeb_resampler.cpp
vendored
@@ -371,3 +371,9 @@ cubeb_resampler_latency(cubeb_resampler * resampler)
|
||||
{
|
||||
return resampler->latency();
|
||||
}
|
||||
|
||||
cubeb_resampler_stats
|
||||
cubeb_resampler_stats_get(cubeb_resampler * resampler)
|
||||
{
|
||||
return resampler->stats();
|
||||
}
|
||||
|
||||
14
3rdparty/cubeb/src/cubeb_resampler.h
vendored
14
3rdparty/cubeb/src/cubeb_resampler.h
vendored
@@ -84,6 +84,20 @@ cubeb_resampler_destroy(cubeb_resampler * resampler);
|
||||
long
|
||||
cubeb_resampler_latency(cubeb_resampler * resampler);
|
||||
|
||||
/**
|
||||
* Test-only introspection API to ensure that there is no buffering
|
||||
* buildup when resampling.
|
||||
*/
|
||||
typedef struct {
|
||||
size_t input_input_buffer_size;
|
||||
size_t input_output_buffer_size;
|
||||
size_t output_input_buffer_size;
|
||||
size_t output_output_buffer_size;
|
||||
} cubeb_resampler_stats;
|
||||
|
||||
cubeb_resampler_stats
|
||||
cubeb_resampler_stats_get(cubeb_resampler * resampler);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
92
3rdparty/cubeb/src/cubeb_resampler_internal.h
vendored
92
3rdparty/cubeb/src/cubeb_resampler_internal.h
vendored
@@ -56,6 +56,7 @@ struct cubeb_resampler {
|
||||
virtual long fill(void * input_buffer, long * input_frames_count,
|
||||
void * output_buffer, long frames_needed) = 0;
|
||||
virtual long latency() = 0;
|
||||
virtual cubeb_resampler_stats stats() = 0;
|
||||
virtual ~cubeb_resampler() {}
|
||||
};
|
||||
|
||||
@@ -86,6 +87,16 @@ public:
|
||||
|
||||
virtual long latency() { return 0; }
|
||||
|
||||
virtual cubeb_resampler_stats stats()
|
||||
{
|
||||
cubeb_resampler_stats stats;
|
||||
stats.input_input_buffer_size = internal_input_buffer.length();
|
||||
stats.input_output_buffer_size = 0;
|
||||
stats.output_input_buffer_size = 0;
|
||||
stats.output_output_buffer_size = 0;
|
||||
return stats;
|
||||
}
|
||||
|
||||
void drop_audio_if_needed()
|
||||
{
|
||||
uint32_t to_keep = min_buffered_audio_frame(sample_rate);
|
||||
@@ -122,6 +133,20 @@ public:
|
||||
virtual long fill(void * input_buffer, long * input_frames_count,
|
||||
void * output_buffer, long output_frames_needed);
|
||||
|
||||
virtual cubeb_resampler_stats stats()
|
||||
{
|
||||
cubeb_resampler_stats stats = {};
|
||||
if (input_processor) {
|
||||
stats.input_input_buffer_size = input_processor->input_buffer_size();
|
||||
stats.input_output_buffer_size = input_processor->output_buffer_size();
|
||||
}
|
||||
if (output_processor) {
|
||||
stats.output_input_buffer_size = output_processor->input_buffer_size();
|
||||
stats.output_output_buffer_size = output_processor->output_buffer_size();
|
||||
}
|
||||
return stats;
|
||||
}
|
||||
|
||||
virtual long latency()
|
||||
{
|
||||
if (input_processor && output_processor) {
|
||||
@@ -280,29 +305,28 @@ public:
|
||||
}
|
||||
|
||||
/** Returns the number of frames to pass in the input of the resampler to have
|
||||
* exactly `output_frame_count` resampled frames. This can return a number
|
||||
* slightly bigger than what is strictly necessary, but it guaranteed that the
|
||||
* number of output frames will be exactly equal. */
|
||||
* at least `output_frame_count` resampled frames. */
|
||||
uint32_t input_needed_for_output(int32_t output_frame_count) const
|
||||
{
|
||||
assert(output_frame_count >= 0); // Check overflow
|
||||
int32_t unresampled_frames_left =
|
||||
samples_to_frames(resampling_in_buffer.length());
|
||||
int32_t resampled_frames_left =
|
||||
samples_to_frames(resampling_out_buffer.length());
|
||||
float input_frames_needed =
|
||||
(output_frame_count - unresampled_frames_left) * resampling_ratio -
|
||||
resampled_frames_left;
|
||||
if (input_frames_needed < 0) {
|
||||
return 0;
|
||||
}
|
||||
return (uint32_t)ceilf(input_frames_needed);
|
||||
float input_frames_needed_frac =
|
||||
static_cast<float>(output_frame_count) * resampling_ratio;
|
||||
// speex_resample()` can be irregular in its consumption of input samples.
|
||||
// Provide one more frame than the number that would be required with
|
||||
// regular consumption, to make the speex resampler behave more regularly,
|
||||
// and so predictably.
|
||||
auto input_frame_needed =
|
||||
1 + static_cast<int32_t>(ceilf(input_frames_needed_frac));
|
||||
input_frame_needed -= std::min(unresampled_frames_left, input_frame_needed);
|
||||
return input_frame_needed;
|
||||
}
|
||||
|
||||
/** Returns a pointer to the input buffer, that contains empty space for at
|
||||
* least `frame_count` elements. This is useful so that consumer can directly
|
||||
* write into the input buffer of the resampler. The pointer returned is
|
||||
* adjusted so that leftover data are not overwritten.
|
||||
* least `frame_count` elements. This is useful so that consumer can
|
||||
* directly write into the input buffer of the resampler. The pointer
|
||||
* returned is adjusted so that leftover data are not overwritten.
|
||||
*/
|
||||
T * input_buffer(size_t frame_count)
|
||||
{
|
||||
@@ -312,8 +336,8 @@ public:
|
||||
return resampling_in_buffer.data() + leftover_samples;
|
||||
}
|
||||
|
||||
/** This method works with `input_buffer`, and allows to inform the processor
|
||||
how much frames have been written in the provided buffer. */
|
||||
/** This method works with `input_buffer`, and allows to inform the
|
||||
processor how much frames have been written in the provided buffer. */
|
||||
void written(size_t written_frames)
|
||||
{
|
||||
resampling_in_buffer.set_length(leftover_samples +
|
||||
@@ -331,6 +355,9 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
size_t input_buffer_size() const { return resampling_in_buffer.length(); }
|
||||
size_t output_buffer_size() const { return resampling_out_buffer.length(); }
|
||||
|
||||
private:
|
||||
/** Wrapper for the speex resampling functions to have a typed
|
||||
* interface. */
|
||||
@@ -359,6 +386,7 @@ private:
|
||||
output_frame_count);
|
||||
assert(rv == RESAMPLER_ERR_SUCCESS);
|
||||
}
|
||||
|
||||
/** The state for the speex resampler used internaly. */
|
||||
SpeexResamplerState * speex_resampler;
|
||||
/** Source rate / target rate. */
|
||||
@@ -371,8 +399,8 @@ private:
|
||||
auto_array<T> resampling_out_buffer;
|
||||
/** Additional latency inserted into the pipeline for synchronisation. */
|
||||
uint32_t additional_latency;
|
||||
/** When `input_buffer` is called, this allows tracking the number of samples
|
||||
that were in the buffer. */
|
||||
/** When `input_buffer` is called, this allows tracking the number of
|
||||
samples that were in the buffer. */
|
||||
uint32_t leftover_samples;
|
||||
};
|
||||
|
||||
@@ -417,8 +445,8 @@ public:
|
||||
return delay_output_buffer.data();
|
||||
}
|
||||
/** Get a pointer to the first writable location in the input buffer>
|
||||
* @parameter frames_needed the number of frames the user needs to write into
|
||||
* the buffer.
|
||||
* @parameter frames_needed the number of frames the user needs to write
|
||||
* into the buffer.
|
||||
* @returns a pointer to a location in the input buffer where #frames_needed
|
||||
* can be writen. */
|
||||
T * input_buffer(uint32_t frames_needed)
|
||||
@@ -428,8 +456,8 @@ public:
|
||||
frames_to_samples(frames_needed));
|
||||
return delay_input_buffer.data() + leftover_samples;
|
||||
}
|
||||
/** This method works with `input_buffer`, and allows to inform the processor
|
||||
how much frames have been written in the provided buffer. */
|
||||
/** This method works with `input_buffer`, and allows to inform the
|
||||
processor how much frames have been written in the provided buffer. */
|
||||
void written(size_t frames_written)
|
||||
{
|
||||
delay_input_buffer.set_length(leftover_samples +
|
||||
@@ -450,8 +478,8 @@ public:
|
||||
|
||||
return to_pop;
|
||||
}
|
||||
/** Returns the number of frames one needs to input into the delay line to get
|
||||
* #frames_needed frames back.
|
||||
/** Returns the number of frames one needs to input into the delay line to
|
||||
* get #frames_needed frames back.
|
||||
* @parameter frames_needed the number of frames one want to write into the
|
||||
* delay_line
|
||||
* @returns the number of frames one will get. */
|
||||
@@ -469,19 +497,23 @@ public:
|
||||
|
||||
void drop_audio_if_needed()
|
||||
{
|
||||
size_t available = samples_to_frames(delay_input_buffer.length());
|
||||
uint32_t available = samples_to_frames(delay_input_buffer.length());
|
||||
uint32_t to_keep = min_buffered_audio_frame(sample_rate);
|
||||
if (available > to_keep) {
|
||||
ALOGV("Dropping %u frames", available - to_keep);
|
||||
|
||||
delay_input_buffer.pop(nullptr, frames_to_samples(available - to_keep));
|
||||
}
|
||||
}
|
||||
|
||||
size_t input_buffer_size() const { return delay_input_buffer.length(); }
|
||||
size_t output_buffer_size() const { return delay_output_buffer.length(); }
|
||||
|
||||
private:
|
||||
/** The length, in frames, of this delay line */
|
||||
uint32_t length;
|
||||
/** When `input_buffer` is called, this allows tracking the number of samples
|
||||
that where in the buffer. */
|
||||
/** When `input_buffer` is called, this allows tracking the number of
|
||||
samples that where in the buffer. */
|
||||
uint32_t leftover_samples;
|
||||
/** The input buffer, where the delay is applied. */
|
||||
auto_array<T> delay_input_buffer;
|
||||
@@ -511,8 +543,8 @@ cubeb_resampler_create_internal(cubeb_stream * stream,
|
||||
"need at least one valid parameter pointer.");
|
||||
|
||||
/* All the streams we have have a sample rate that matches the target
|
||||
sample rate, use a no-op resampler, that simply forwards the buffers to the
|
||||
callback. */
|
||||
sample rate, use a no-op resampler, that simply forwards the buffers to
|
||||
the callback. */
|
||||
if (((input_params && input_params->rate == target_rate) &&
|
||||
(output_params && output_params->rate == target_rate)) ||
|
||||
(input_params && !output_params && (input_params->rate == target_rate)) ||
|
||||
|
||||
490
3rdparty/cubeb/src/cubeb_wasapi.cpp
vendored
490
3rdparty/cubeb/src/cubeb_wasapi.cpp
vendored
@@ -4,8 +4,12 @@
|
||||
* This program is made available under an ISC-style license. See the
|
||||
* accompanying file LICENSE for details.
|
||||
*/
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0603
|
||||
#endif // !_WIN32_WINNT
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif // !NOMINMAX
|
||||
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
@@ -37,31 +41,6 @@
|
||||
#include "cubeb_tracing.h"
|
||||
#include "cubeb_utils.h"
|
||||
|
||||
// Some people have reported glitches with IAudioClient3 capture streams:
|
||||
// http://blog.nirbheek.in/2018/03/low-latency-audio-on-windows-with.html
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1590902
|
||||
#define ALLOW_AUDIO_CLIENT_3_FOR_INPUT 0
|
||||
// IAudioClient3::GetSharedModeEnginePeriod() seem to return min latencies
|
||||
// bigger than IAudioClient::GetDevicePeriod(), which is confusing (10ms vs
|
||||
// 3ms), though the default latency is usually the same and we should use the
|
||||
// IAudioClient3 function anyway, as it's more correct
|
||||
#define USE_AUDIO_CLIENT_3_MIN_PERIOD 1
|
||||
// If this is true, we allow IAudioClient3 the creation of sessions with a
|
||||
// latency above the default one (usually 10ms).
|
||||
// Whether we should default this to true or false depend on many things:
|
||||
// -Does creating a shared IAudioClient3 session (not locked to a format)
|
||||
// actually forces all the IAudioClient(1) sessions to have the same latency?
|
||||
// I could find no proof of that.
|
||||
// -Does creating a shared IAudioClient3 session with a latency >= the default
|
||||
// one actually improve the latency (as in how late the audio is) at all?
|
||||
// -Maybe we could expose this as cubeb stream pref
|
||||
// (e.g. take priority over other apps)?
|
||||
#define ALLOW_AUDIO_CLIENT_3_LATENCY_OVER_DEFAULT 1
|
||||
// If this is true and the user specified a target latency >= the IAudioClient3
|
||||
// max one, then we reject it and fall back to IAudioClient(1). There wouldn't
|
||||
// be much point in having a low latency if that's not what the user wants.
|
||||
#define REJECT_AUDIO_CLIENT_3_LATENCY_OVER_MAX 0
|
||||
|
||||
// Windows 10 exposes the IAudioClient3 interface to create low-latency streams.
|
||||
// Copy the interface definition from audioclient.h here to make the code
|
||||
// simpler and so that we can still access IAudioClient3 via COM if cubeb was
|
||||
@@ -229,11 +208,6 @@ struct auto_stream_ref {
|
||||
cubeb_stream * stm;
|
||||
};
|
||||
|
||||
using set_mm_thread_characteristics_function =
|
||||
decltype(&AvSetMmThreadCharacteristicsW);
|
||||
using revert_mm_thread_characteristics_function =
|
||||
decltype(&AvRevertMmThreadCharacteristics);
|
||||
|
||||
extern cubeb_ops const wasapi_ops;
|
||||
|
||||
static com_heap_ptr<wchar_t>
|
||||
@@ -304,8 +278,8 @@ wasapi_enumerate_devices_internal(cubeb * context, cubeb_device_type type,
|
||||
static int
|
||||
wasapi_device_collection_destroy(cubeb * ctx,
|
||||
cubeb_device_collection * collection);
|
||||
static char const *
|
||||
wstr_to_utf8(wchar_t const * str);
|
||||
static std::unique_ptr<char const[]>
|
||||
wstr_to_utf8(LPCWSTR str);
|
||||
static std::unique_ptr<wchar_t const[]>
|
||||
utf8_to_wstr(char const * str);
|
||||
|
||||
@@ -314,6 +288,15 @@ utf8_to_wstr(char const * str);
|
||||
class wasapi_collection_notification_client;
|
||||
class monitor_device_notifications;
|
||||
|
||||
typedef enum {
|
||||
/* Clear options */
|
||||
CUBEB_AUDIO_CLIENT2_NONE,
|
||||
/* Use AUDCLNT_STREAMOPTIONS_RAW */
|
||||
CUBEB_AUDIO_CLIENT2_RAW,
|
||||
/* Use CUBEB_STREAM_PREF_COMMUNICATIONS */
|
||||
CUBEB_AUDIO_CLIENT2_VOICE
|
||||
} AudioClient2Option;
|
||||
|
||||
struct cubeb {
|
||||
cubeb_ops const * ops = &wasapi_ops;
|
||||
owned_critical_section lock;
|
||||
@@ -331,13 +314,6 @@ struct cubeb {
|
||||
nullptr;
|
||||
void * output_collection_changed_user_ptr = nullptr;
|
||||
UINT64 performance_counter_frequency;
|
||||
/* Library dynamically opened to increase the render thread priority, and
|
||||
the two function pointers we need. */
|
||||
HMODULE mmcss_module = nullptr;
|
||||
set_mm_thread_characteristics_function set_mm_thread_characteristics =
|
||||
nullptr;
|
||||
revert_mm_thread_characteristics_function revert_mm_thread_characteristics =
|
||||
nullptr;
|
||||
};
|
||||
|
||||
class wasapi_endpoint_notification_client;
|
||||
@@ -360,20 +336,33 @@ struct cubeb_stream {
|
||||
/* Mixer pameters. We need to convert the input stream to this
|
||||
samplerate/channel layout, as WASAPI does not resample nor upmix
|
||||
itself. */
|
||||
cubeb_stream_params input_mix_params = {CUBEB_SAMPLE_FLOAT32NE, 0, 0,
|
||||
cubeb_stream_params input_mix_params = {CUBEB_SAMPLE_FLOAT32NE,
|
||||
0,
|
||||
0,
|
||||
CUBEB_LAYOUT_UNDEFINED,
|
||||
CUBEB_STREAM_PREF_NONE};
|
||||
cubeb_stream_params output_mix_params = {CUBEB_SAMPLE_FLOAT32NE, 0, 0,
|
||||
CUBEB_STREAM_PREF_NONE,
|
||||
CUBEB_INPUT_PROCESSING_PARAM_NONE};
|
||||
cubeb_stream_params output_mix_params = {CUBEB_SAMPLE_FLOAT32NE,
|
||||
0,
|
||||
0,
|
||||
CUBEB_LAYOUT_UNDEFINED,
|
||||
CUBEB_STREAM_PREF_NONE};
|
||||
CUBEB_STREAM_PREF_NONE,
|
||||
CUBEB_INPUT_PROCESSING_PARAM_NONE};
|
||||
/* Stream parameters. This is what the client requested,
|
||||
* and what will be presented in the callback. */
|
||||
cubeb_stream_params input_stream_params = {CUBEB_SAMPLE_FLOAT32NE, 0, 0,
|
||||
cubeb_stream_params input_stream_params = {CUBEB_SAMPLE_FLOAT32NE,
|
||||
0,
|
||||
0,
|
||||
CUBEB_LAYOUT_UNDEFINED,
|
||||
CUBEB_STREAM_PREF_NONE};
|
||||
cubeb_stream_params output_stream_params = {CUBEB_SAMPLE_FLOAT32NE, 0, 0,
|
||||
CUBEB_LAYOUT_UNDEFINED,
|
||||
CUBEB_STREAM_PREF_NONE};
|
||||
CUBEB_STREAM_PREF_NONE,
|
||||
CUBEB_INPUT_PROCESSING_PARAM_NONE};
|
||||
cubeb_stream_params output_stream_params = {
|
||||
CUBEB_SAMPLE_FLOAT32NE,
|
||||
0,
|
||||
0,
|
||||
CUBEB_LAYOUT_UNDEFINED,
|
||||
CUBEB_STREAM_PREF_NONE,
|
||||
CUBEB_INPUT_PROCESSING_PARAM_NONE};
|
||||
/* A MMDevice role for this stream: either communication or console here. */
|
||||
ERole role;
|
||||
/* True if this stream will transport voice-data. */
|
||||
@@ -662,6 +651,10 @@ public:
|
||||
LPCWSTR device_id)
|
||||
{
|
||||
LOG("collection: Audio device default changed, id = %S.", device_id);
|
||||
|
||||
/* Default device changes count as device collection changes */
|
||||
monitor_notifications.notify(flow);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -772,7 +765,7 @@ public:
|
||||
LPCWSTR device_id)
|
||||
{
|
||||
LOG("endpoint: Audio device default changed flow=%d role=%d "
|
||||
"new_device_id=%ws.",
|
||||
"new_device_id=%S.",
|
||||
flow, role, device_id);
|
||||
|
||||
/* we only support a single stream type for now. */
|
||||
@@ -783,11 +776,13 @@ public:
|
||||
DWORD last_change_ms = timeGetTime() - last_device_change;
|
||||
bool same_device = default_device_id && device_id &&
|
||||
wcscmp(default_device_id.get(), device_id) == 0;
|
||||
LOG("endpoint: Audio device default changed last_change=%u same_device=%d",
|
||||
LOG("endpoint: Audio device default changed last_change=%lu same_device=%d",
|
||||
last_change_ms, same_device);
|
||||
if (last_change_ms > DEVICE_CHANGE_DEBOUNCE_MS || !same_device) {
|
||||
if (device_id) {
|
||||
default_device_id.reset(_wcsdup(device_id));
|
||||
wchar_t * new_device_id = new wchar_t[wcslen(device_id) + 1];
|
||||
wcscpy(new_device_id, device_id);
|
||||
default_device_id.reset(new_device_id);
|
||||
} else {
|
||||
default_device_id.reset();
|
||||
}
|
||||
@@ -863,16 +858,12 @@ intern_device_id(cubeb * ctx, wchar_t const * id)
|
||||
|
||||
auto_lock lock(ctx->lock);
|
||||
|
||||
char const * tmp = wstr_to_utf8(id);
|
||||
std::unique_ptr<char const[]> tmp = wstr_to_utf8(id);
|
||||
if (!tmp) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
char const * interned = cubeb_strings_intern(ctx->device_ids, tmp);
|
||||
|
||||
free((void *)tmp);
|
||||
|
||||
return interned;
|
||||
return cubeb_strings_intern(ctx->device_ids, tmp.get());
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -977,7 +968,7 @@ refill(cubeb_stream * stm, void * input_buffer, long input_frames_count,
|
||||
cubeb_resampler_fill(stm->resampler.get(), input_buffer,
|
||||
&input_frames_count, dest, output_frames_needed);
|
||||
if (out_frames < 0) {
|
||||
ALOGV("Callback refill error: %d", out_frames);
|
||||
ALOGV("Callback refill error: %ld", out_frames);
|
||||
wasapi_state_callback(stm, stm->user_ptr, CUBEB_STATE_ERROR);
|
||||
return out_frames;
|
||||
}
|
||||
@@ -1263,8 +1254,8 @@ refill_callback_duplex(cubeb_stream * stm)
|
||||
XASSERT(has_input(stm) && has_output(stm));
|
||||
|
||||
if (stm->input_stream_params.prefs & CUBEB_STREAM_PREF_LOOPBACK) {
|
||||
HRESULT rv = get_input_buffer(stm);
|
||||
if (FAILED(rv)) {
|
||||
rv = get_input_buffer(stm);
|
||||
if (!rv) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
@@ -1274,7 +1265,6 @@ refill_callback_duplex(cubeb_stream * stm)
|
||||
|
||||
rv = get_output_buffer(stm, output_buffer, output_frames);
|
||||
if (!rv) {
|
||||
hr = stm->render_client->ReleaseBuffer(output_frames, 0);
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -1291,9 +1281,11 @@ refill_callback_duplex(cubeb_stream * stm)
|
||||
|
||||
stm->total_output_frames += output_frames;
|
||||
|
||||
ALOGV("in: %zu, out: %zu, missing: %ld, ratio: %f", stm->total_input_frames,
|
||||
stm->total_output_frames,
|
||||
static_cast<long>(stm->total_output_frames) - stm->total_input_frames,
|
||||
ALOGV("in: %llu, out: %llu, missing: %ld, ratio: %f",
|
||||
(unsigned long long)stm->total_input_frames,
|
||||
(unsigned long long)stm->total_output_frames,
|
||||
static_cast<long long>(stm->total_output_frames) -
|
||||
static_cast<long long>(stm->total_input_frames),
|
||||
static_cast<float>(stm->total_output_frames) / stm->total_input_frames);
|
||||
|
||||
long got;
|
||||
@@ -1438,8 +1430,7 @@ static unsigned int __stdcall wasapi_stream_render_loop(LPVOID stream)
|
||||
|
||||
/* We could consider using "Pro Audio" here for WebAudio and
|
||||
maybe WebRTC. */
|
||||
mmcss_handle =
|
||||
stm->context->set_mm_thread_characteristics(L"Audio", &mmcss_task_index);
|
||||
mmcss_handle = AvSetMmThreadCharacteristicsA("Audio", &mmcss_task_index);
|
||||
if (!mmcss_handle) {
|
||||
/* This is not fatal, but we might glitch under heavy load. */
|
||||
LOG("Unable to use mmcss to bump the render thread priority: %lx",
|
||||
@@ -1519,8 +1510,8 @@ static unsigned int __stdcall wasapi_stream_render_loop(LPVOID stream)
|
||||
is_playing = stm->refill_callback(stm);
|
||||
break;
|
||||
case WAIT_OBJECT_0 + 3: { /* input available */
|
||||
HRESULT rv = get_input_buffer(stm);
|
||||
if (FAILED(rv)) {
|
||||
bool rv = get_input_buffer(stm);
|
||||
if (!rv) {
|
||||
is_playing = false;
|
||||
continue;
|
||||
}
|
||||
@@ -1532,8 +1523,11 @@ static unsigned int __stdcall wasapi_stream_render_loop(LPVOID stream)
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LOG("case %lu not handled in render loop.", waitResult);
|
||||
XASSERT(false);
|
||||
LOG("render_loop: waitResult=%lu (lastError=%lu) unhandled, exiting",
|
||||
waitResult, GetLastError());
|
||||
is_playing = false;
|
||||
hr = E_FAIL;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1547,7 +1541,7 @@ static unsigned int __stdcall wasapi_stream_render_loop(LPVOID stream)
|
||||
}
|
||||
|
||||
if (mmcss_handle) {
|
||||
stm->context->revert_mm_thread_characteristics(mmcss_handle);
|
||||
AvRevertMmThreadCharacteristics(mmcss_handle);
|
||||
}
|
||||
|
||||
if (FAILED(hr)) {
|
||||
@@ -1560,18 +1554,6 @@ static unsigned int __stdcall wasapi_stream_render_loop(LPVOID stream)
|
||||
void
|
||||
wasapi_destroy(cubeb * context);
|
||||
|
||||
HANDLE WINAPI
|
||||
set_mm_thread_characteristics_noop(LPCWSTR, LPDWORD mmcss_task_index)
|
||||
{
|
||||
return (HANDLE)1;
|
||||
}
|
||||
|
||||
BOOL WINAPI
|
||||
revert_mm_thread_characteristics_noop(HANDLE mmcss_handle)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
register_notification_client(cubeb_stream * stm)
|
||||
{
|
||||
@@ -1807,31 +1789,6 @@ wasapi_init(cubeb ** context, char const * context_name)
|
||||
ctx->performance_counter_frequency = 0;
|
||||
}
|
||||
|
||||
ctx->mmcss_module = LoadLibraryW(L"Avrt.dll");
|
||||
|
||||
bool success = false;
|
||||
if (ctx->mmcss_module) {
|
||||
ctx->set_mm_thread_characteristics =
|
||||
reinterpret_cast<set_mm_thread_characteristics_function>(
|
||||
GetProcAddress(ctx->mmcss_module, "AvSetMmThreadCharacteristicsW"));
|
||||
ctx->revert_mm_thread_characteristics =
|
||||
reinterpret_cast<revert_mm_thread_characteristics_function>(
|
||||
GetProcAddress(ctx->mmcss_module,
|
||||
"AvRevertMmThreadCharacteristics"));
|
||||
success = ctx->set_mm_thread_characteristics &&
|
||||
ctx->revert_mm_thread_characteristics;
|
||||
}
|
||||
if (!success) {
|
||||
// This is not a fatal error, but we might end up glitching when
|
||||
// the system is under high load.
|
||||
LOG("Could not load avrt.dll or fetch AvSetMmThreadCharacteristicsW "
|
||||
"AvRevertMmThreadCharacteristics: %lx",
|
||||
GetLastError());
|
||||
ctx->set_mm_thread_characteristics = &set_mm_thread_characteristics_noop;
|
||||
ctx->revert_mm_thread_characteristics =
|
||||
&revert_mm_thread_characteristics_noop;
|
||||
}
|
||||
|
||||
*context = ctx;
|
||||
|
||||
return CUBEB_OK;
|
||||
@@ -1839,7 +1796,6 @@ wasapi_init(cubeb ** context, char const * context_name)
|
||||
}
|
||||
|
||||
namespace {
|
||||
enum ShutdownPhase { OnStop, OnDestroy };
|
||||
|
||||
bool
|
||||
stop_and_join_render_thread(cubeb_stream * stm)
|
||||
@@ -1855,16 +1811,7 @@ stop_and_join_render_thread(cubeb_stream * stm)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Wait five seconds for the rendering thread to return. It's supposed to
|
||||
* check its event loop very often, five seconds is rather conservative.
|
||||
* Note: 5*1s loop to work around timer sleep issues on pre-Windows 8. */
|
||||
DWORD r;
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
r = WaitForSingleObject(stm->thread, 1000);
|
||||
if (r == WAIT_OBJECT_0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
DWORD r = WaitForSingleObject(stm->thread, INFINITE);
|
||||
if (r != WAIT_OBJECT_0) {
|
||||
LOG("stop_and_join_render_thread: WaitForSingleObject on thread failed: "
|
||||
"%lx, %lx",
|
||||
@@ -1888,10 +1835,6 @@ wasapi_destroy(cubeb * context)
|
||||
}
|
||||
}
|
||||
|
||||
if (context->mmcss_module) {
|
||||
FreeLibrary(context->mmcss_module);
|
||||
}
|
||||
|
||||
delete context;
|
||||
}
|
||||
|
||||
@@ -1949,44 +1892,6 @@ wasapi_get_min_latency(cubeb * ctx, cubeb_stream_params params,
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
#if USE_AUDIO_CLIENT_3_MIN_PERIOD
|
||||
// This is unreliable as we can't know the actual mixer format cubeb will
|
||||
// ask for later on (nor we can branch on ALLOW_AUDIO_CLIENT_3_FOR_INPUT),
|
||||
// and the min latency can change based on that.
|
||||
com_ptr<IAudioClient3> client3;
|
||||
hr = device->Activate(__uuidof(IAudioClient3), CLSCTX_INPROC_SERVER, NULL,
|
||||
client3.receive_vpp());
|
||||
if (SUCCEEDED(hr)) {
|
||||
WAVEFORMATEX * mix_format = nullptr;
|
||||
hr = client3->GetMixFormat(&mix_format);
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
uint32_t default_period = 0, fundamental_period = 0, min_period = 0,
|
||||
max_period = 0;
|
||||
hr = client3->GetSharedModeEnginePeriod(mix_format, &default_period,
|
||||
&fundamental_period, &min_period,
|
||||
&max_period);
|
||||
|
||||
auto sample_rate = mix_format->nSamplesPerSec;
|
||||
CoTaskMemFree(mix_format);
|
||||
if (SUCCEEDED(hr)) {
|
||||
// Print values in the same format as IAudioDevice::GetDevicePeriod()
|
||||
REFERENCE_TIME min_period_rt(frames_to_hns(sample_rate, min_period));
|
||||
REFERENCE_TIME default_period_rt(
|
||||
frames_to_hns(sample_rate, default_period));
|
||||
LOG("default device period: %I64d, minimum device period: %I64d",
|
||||
default_period_rt, min_period_rt);
|
||||
|
||||
*latency_frames = hns_to_frames(params.rate, min_period_rt);
|
||||
|
||||
LOG("Minimum latency in frames: %u", *latency_frames);
|
||||
|
||||
return CUBEB_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
com_ptr<IAudioClient> client;
|
||||
hr = device->Activate(__uuidof(IAudioClient), CLSCTX_INPROC_SERVER, NULL,
|
||||
client.receive_vpp());
|
||||
@@ -2006,8 +1911,18 @@ wasapi_get_min_latency(cubeb * ctx, cubeb_stream_params params,
|
||||
LOG("default device period: %I64d, minimum device period: %I64d",
|
||||
default_period, minimum_period);
|
||||
|
||||
// The minimum_period is only relevant in exclusive streams.
|
||||
/* If we're on Windows 10, we can use IAudioClient3 to get minimal latency.
|
||||
Otherwise, according to the docs, the best latency we can achieve is by
|
||||
synchronizing the stream and the engine.
|
||||
http://msdn.microsoft.com/en-us/library/windows/desktop/dd370871%28v=vs.85%29.aspx
|
||||
*/
|
||||
|
||||
// #ifdef _WIN32_WINNT_WIN10
|
||||
#if 0
|
||||
*latency_frames = hns_to_frames(params.rate, minimum_period);
|
||||
#else
|
||||
*latency_frames = hns_to_frames(params.rate, default_period);
|
||||
#endif
|
||||
|
||||
LOG("Minimum latency in frames: %u", *latency_frames);
|
||||
|
||||
@@ -2044,6 +1959,21 @@ wasapi_get_preferred_sample_rate(cubeb * ctx, uint32_t * rate)
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
int
|
||||
wasapi_get_supported_input_processing_params(
|
||||
cubeb * ctx, cubeb_input_processing_params * params)
|
||||
{
|
||||
// This is not entirely accurate -- windows doesn't document precisely what
|
||||
// AudioCategory_Communications does -- but assume that we can set all or none
|
||||
// of them.
|
||||
*params = static_cast<cubeb_input_processing_params>(
|
||||
CUBEB_INPUT_PROCESSING_PARAM_ECHO_CANCELLATION |
|
||||
CUBEB_INPUT_PROCESSING_PARAM_NOISE_SUPPRESSION |
|
||||
CUBEB_INPUT_PROCESSING_PARAM_AUTOMATIC_GAIN_CONTROL |
|
||||
CUBEB_INPUT_PROCESSING_PARAM_VOICE_ISOLATION);
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
waveformatex_update_derived_properties(WAVEFORMATEX * format)
|
||||
{
|
||||
@@ -2097,10 +2027,7 @@ handle_channel_layout(cubeb_stream * stm, EDataFlow direction,
|
||||
if (hr == S_FALSE) {
|
||||
/* Channel layout not supported, but WASAPI gives us a suggestion. Use it,
|
||||
and handle the eventual upmix/downmix ourselves. Ignore the subformat of
|
||||
the suggestion, since it seems to always be IEEE_FLOAT.
|
||||
This fallback doesn't update the bit depth, so if a device
|
||||
only supported bit depths cubeb doesn't support, so IAudioClient3
|
||||
streams might fail */
|
||||
the suggestion, since it seems to always be IEEE_FLOAT. */
|
||||
LOG("Using WASAPI suggested format: channels: %d", closest->nChannels);
|
||||
XASSERT(closest->wFormatTag == WAVE_FORMAT_EXTENSIBLE);
|
||||
WAVEFORMATEXTENSIBLE * closest_pcm =
|
||||
@@ -2122,7 +2049,8 @@ handle_channel_layout(cubeb_stream * stm, EDataFlow direction,
|
||||
}
|
||||
|
||||
static int
|
||||
initialize_iaudioclient2(com_ptr<IAudioClient> & audio_client)
|
||||
initialize_iaudioclient2(com_ptr<IAudioClient> & audio_client,
|
||||
AudioClient2Option option)
|
||||
{
|
||||
com_ptr<IAudioClient2> audio_client2;
|
||||
audio_client->QueryInterface<IAudioClient2>(audio_client2.receive());
|
||||
@@ -2131,10 +2059,14 @@ initialize_iaudioclient2(com_ptr<IAudioClient> & audio_client)
|
||||
"AUDCLNT_STREAMOPTIONS_RAW.");
|
||||
return CUBEB_OK;
|
||||
}
|
||||
AudioClientProperties properties = {0};
|
||||
AudioClientProperties properties = {};
|
||||
properties.cbSize = sizeof(AudioClientProperties);
|
||||
#ifndef __MINGW32__
|
||||
properties.Options |= AUDCLNT_STREAMOPTIONS_RAW;
|
||||
if (option == CUBEB_AUDIO_CLIENT2_RAW) {
|
||||
properties.Options |= AUDCLNT_STREAMOPTIONS_RAW;
|
||||
} else if (option == CUBEB_AUDIO_CLIENT2_VOICE) {
|
||||
properties.eCategory = AudioCategory_Communications;
|
||||
}
|
||||
#endif
|
||||
HRESULT hr = audio_client2->SetClientProperties(&properties);
|
||||
if (FAILED(hr)) {
|
||||
@@ -2144,12 +2076,12 @@ initialize_iaudioclient2(com_ptr<IAudioClient> & audio_client)
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
#if 0
|
||||
bool
|
||||
initialize_iaudioclient3(com_ptr<IAudioClient> & audio_client,
|
||||
cubeb_stream * stm,
|
||||
const com_heap_ptr<WAVEFORMATEX> & mix_format,
|
||||
DWORD flags, EDataFlow direction,
|
||||
REFERENCE_TIME latency_hns)
|
||||
DWORD flags, EDataFlow direction)
|
||||
{
|
||||
com_ptr<IAudioClient3> audio_client3;
|
||||
audio_client->QueryInterface<IAudioClient3>(audio_client3.receive());
|
||||
@@ -2165,22 +2097,24 @@ initialize_iaudioclient3(com_ptr<IAudioClient> & audio_client,
|
||||
return false;
|
||||
}
|
||||
|
||||
// Some people have reported glitches with capture streams:
|
||||
// http://blog.nirbheek.in/2018/03/low-latency-audio-on-windows-with.html
|
||||
if (direction == eCapture) {
|
||||
LOG("Audio stream is capture, not using IAudioClient3");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Possibly initialize a shared-mode stream using IAudioClient3. Initializing
|
||||
// a stream this way lets you request lower latencies, but also locks the
|
||||
// global WASAPI engine at that latency.
|
||||
// - If we request a shared-mode stream, streams created with IAudioClient
|
||||
// might have their latency adjusted to match. When the shared-mode stream
|
||||
// is closed, they'll go back to normal.
|
||||
// - If there's already a shared-mode stream running, if it created with the
|
||||
// AUDCLNT_STREAMOPTIONS_MATCH_FORMAT option, the audio engine would be
|
||||
// locked to that format, so we have to match it (a custom one would fail).
|
||||
// - We don't lock the WASAPI engine to a format, as it's antisocial towards
|
||||
// other apps, especially if we locked to a latency >= than its default.
|
||||
// - If the user requested latency is >= the default one, we might still
|
||||
// accept it (without locking the format) depending on
|
||||
// ALLOW_AUDIO_CLIENT_3_LATENCY_OVER_DEFAULT, as we might want to prioritize
|
||||
// to lower our latency over other apps
|
||||
// (there might still be latency advantages compared to IAudioDevice(1)).
|
||||
// will
|
||||
// have their latency adjusted to match. When the shared-mode stream is
|
||||
// closed, they'll go back to normal.
|
||||
// - If there's already a shared-mode stream running, then we cannot request
|
||||
// the engine change to a different latency - we have to match it.
|
||||
// - It's antisocial to lock the WASAPI engine at its default latency. If we
|
||||
// would do this, then stop and use IAudioClient instead.
|
||||
|
||||
HRESULT hr;
|
||||
uint32_t default_period = 0, fundamental_period = 0, min_period = 0,
|
||||
@@ -2192,59 +2126,28 @@ initialize_iaudioclient3(com_ptr<IAudioClient> & audio_client,
|
||||
LOG("Could not get shared mode engine period: error: %lx", hr);
|
||||
return false;
|
||||
}
|
||||
uint32_t requested_latency =
|
||||
hns_to_frames(mix_format->nSamplesPerSec, latency_hns);
|
||||
#if !ALLOW_AUDIO_CLIENT_3_LATENCY_OVER_DEFAULT
|
||||
uint32_t requested_latency = stm->latency;
|
||||
if (requested_latency >= default_period) {
|
||||
LOG("Requested latency %i equal or greater than default latency %i,"
|
||||
" not using IAudioClient3",
|
||||
LOG("Requested latency %i greater than default latency %i, not using "
|
||||
"IAudioClient3",
|
||||
requested_latency, default_period);
|
||||
return false;
|
||||
}
|
||||
#elif REJECT_AUDIO_CLIENT_3_LATENCY_OVER_MAX
|
||||
if (requested_latency > max_period) {
|
||||
// Fallback to IAudioClient(1) as it's more accepting of large latencies
|
||||
LOG("Requested latency %i greater than max latency %i,"
|
||||
" not using IAudioClient3",
|
||||
requested_latency, max_period);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
LOG("Got shared mode engine period: default=%i fundamental=%i min=%i max=%i",
|
||||
default_period, fundamental_period, min_period, max_period);
|
||||
// Snap requested latency to a valid value
|
||||
uint32_t old_requested_latency = requested_latency;
|
||||
// The period is required to be a multiple of the fundamental period
|
||||
// (and >= min and <= max, which should still be true)
|
||||
requested_latency -= requested_latency % fundamental_period;
|
||||
if (requested_latency < min_period) {
|
||||
requested_latency = min_period;
|
||||
}
|
||||
// Likely unnecessary, but won't hurt
|
||||
if (requested_latency > max_period) {
|
||||
requested_latency = max_period;
|
||||
}
|
||||
requested_latency -= (requested_latency - min_period) % fundamental_period;
|
||||
if (requested_latency != old_requested_latency) {
|
||||
LOG("Requested latency %i was adjusted to %i", old_requested_latency,
|
||||
requested_latency);
|
||||
}
|
||||
|
||||
DWORD new_flags = flags;
|
||||
// Always add these flags to IAudioClient3, they might help
|
||||
// if the stream doesn't have the same format as the audio engine.
|
||||
new_flags |= AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM;
|
||||
new_flags |= AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY;
|
||||
|
||||
hr = audio_client3->InitializeSharedAudioStream(new_flags, requested_latency,
|
||||
hr = audio_client3->InitializeSharedAudioStream(flags, requested_latency,
|
||||
mix_format.get(), NULL);
|
||||
// This error should be returned first even if
|
||||
// the period was locked (AUDCLNT_E_ENGINE_PERIODICITY_LOCKED)
|
||||
if (hr == AUDCLNT_E_INVALID_STREAM_FLAG) {
|
||||
LOG("Got AUDCLNT_E_INVALID_STREAM_FLAG, removing some flags");
|
||||
hr = audio_client3->InitializeSharedAudioStream(flags, requested_latency,
|
||||
mix_format.get(), NULL);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr)) {
|
||||
return true;
|
||||
} else if (hr == AUDCLNT_E_ENGINE_PERIODICITY_LOCKED) {
|
||||
@@ -2256,37 +2159,22 @@ initialize_iaudioclient3(com_ptr<IAudioClient> & audio_client,
|
||||
}
|
||||
|
||||
uint32_t current_period = 0;
|
||||
WAVEFORMATEX * current_format_ptr = nullptr;
|
||||
WAVEFORMATEX * current_format = nullptr;
|
||||
// We have to pass a valid WAVEFORMATEX** and not nullptr, otherwise
|
||||
// GetCurrentSharedModeEnginePeriod will return E_POINTER
|
||||
hr = audio_client3->GetCurrentSharedModeEnginePeriod(¤t_format_ptr,
|
||||
hr = audio_client3->GetCurrentSharedModeEnginePeriod(¤t_format,
|
||||
¤t_period);
|
||||
CoTaskMemFree(current_format);
|
||||
if (FAILED(hr)) {
|
||||
LOG("Could not get current shared mode engine period: error: %lx", hr);
|
||||
return false;
|
||||
}
|
||||
com_heap_ptr<WAVEFORMATEX> current_format(current_format_ptr);
|
||||
if (current_format->nSamplesPerSec != mix_format->nSamplesPerSec) {
|
||||
// Unless some other external app locked the shared mode engine period
|
||||
// within our audio initialization, this is unlikely to happen, though we
|
||||
// can't respect the user selected latency, so we fallback on IAudioClient
|
||||
LOG("IAudioClient3::GetCurrentSharedModeEnginePeriod() returned a "
|
||||
"different mixer format (nSamplesPerSec) from "
|
||||
"IAudioClient::GetMixFormat(); not using IAudioClient3");
|
||||
return false;
|
||||
}
|
||||
|
||||
#if REJECT_AUDIO_CLIENT_3_LATENCY_OVER_MAX
|
||||
// Reject IAudioClient3 if we can't respect the user target latency.
|
||||
// We don't need to check against default_latency anymore,
|
||||
// as the current_period is already the best one we could get.
|
||||
if (old_requested_latency > current_period) {
|
||||
LOG("Requested latency %i greater than currently locked shared mode "
|
||||
"latency %i, not using IAudioClient3",
|
||||
old_requested_latency, current_period);
|
||||
if (current_period >= default_period) {
|
||||
LOG("Current shared mode engine period %i too high, not using IAudioClient",
|
||||
current_period);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
hr = audio_client3->InitializeSharedAudioStream(flags, current_period,
|
||||
mix_format.get(), NULL);
|
||||
@@ -2299,6 +2187,7 @@ initialize_iaudioclient3(com_ptr<IAudioClient> & audio_client,
|
||||
LOG("Could not initialize shared stream with IAudioClient3: error: %lx", hr);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define DIRECTION_NAME (direction == eCapture ? "capture" : "render")
|
||||
|
||||
@@ -2322,12 +2211,6 @@ setup_wasapi_stream_one_side(cubeb_stream * stm,
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
|
||||
#if ALLOW_AUDIO_CLIENT_3_FOR_INPUT
|
||||
constexpr bool allow_audio_client_3 = true;
|
||||
#else
|
||||
const bool allow_audio_client_3 = direction == eRender;
|
||||
#endif
|
||||
|
||||
stm->stream_reset_lock.assert_current_thread_owns();
|
||||
// If user doesn't specify a particular device, we can choose another one when
|
||||
// the given devid is unavailable.
|
||||
@@ -2364,14 +2247,17 @@ setup_wasapi_stream_one_side(cubeb_stream * stm,
|
||||
|
||||
/* Get a client. We will get all other interfaces we need from
|
||||
* this pointer. */
|
||||
if (allow_audio_client_3) {
|
||||
hr = device->Activate(__uuidof(IAudioClient3), CLSCTX_INPROC_SERVER, NULL,
|
||||
audio_client.receive_vpp());
|
||||
}
|
||||
if (!allow_audio_client_3 || hr == E_NOINTERFACE) {
|
||||
hr = device->Activate(__uuidof(IAudioClient), CLSCTX_INPROC_SERVER, NULL,
|
||||
audio_client.receive_vpp());
|
||||
#if 0 // See https://bugzilla.mozilla.org/show_bug.cgi?id=1590902
|
||||
hr = device->Activate(__uuidof(IAudioClient3),
|
||||
CLSCTX_INPROC_SERVER,
|
||||
NULL, audio_client.receive_vpp());
|
||||
if (hr == E_NOINTERFACE) {
|
||||
#endif
|
||||
hr = device->Activate(__uuidof(IAudioClient), CLSCTX_INPROC_SERVER, NULL,
|
||||
audio_client.receive_vpp());
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
if (FAILED(hr)) {
|
||||
LOG("Could not activate the device to get an audio"
|
||||
@@ -2494,21 +2380,41 @@ setup_wasapi_stream_one_side(cubeb_stream * stm,
|
||||
}
|
||||
|
||||
if (stream_params->prefs & CUBEB_STREAM_PREF_RAW) {
|
||||
if (initialize_iaudioclient2(audio_client) != CUBEB_OK) {
|
||||
if (initialize_iaudioclient2(audio_client, CUBEB_AUDIO_CLIENT2_RAW) !=
|
||||
CUBEB_OK) {
|
||||
LOG("Can't initialize an IAudioClient2, error: %lx", GetLastError());
|
||||
// This is not fatal.
|
||||
}
|
||||
} else if (direction == eCapture &&
|
||||
(stream_params->prefs & CUBEB_STREAM_PREF_VOICE) &&
|
||||
stream_params->input_params != CUBEB_INPUT_PROCESSING_PARAM_NONE) {
|
||||
if (stream_params->input_params ==
|
||||
(CUBEB_INPUT_PROCESSING_PARAM_ECHO_CANCELLATION |
|
||||
CUBEB_INPUT_PROCESSING_PARAM_NOISE_SUPPRESSION |
|
||||
CUBEB_INPUT_PROCESSING_PARAM_AUTOMATIC_GAIN_CONTROL |
|
||||
CUBEB_INPUT_PROCESSING_PARAM_VOICE_ISOLATION)) {
|
||||
if (initialize_iaudioclient2(audio_client, CUBEB_AUDIO_CLIENT2_VOICE) !=
|
||||
CUBEB_OK) {
|
||||
LOG("Can't initialize an IAudioClient2, error: %lx", GetLastError());
|
||||
// This is not fatal.
|
||||
}
|
||||
} else {
|
||||
LOG("Invalid combination of input processing params %#x",
|
||||
stream_params->input_params);
|
||||
return CUBEB_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (allow_audio_client_3 &&
|
||||
initialize_iaudioclient3(audio_client, stm, mix_format, flags, direction,
|
||||
latency_hns)) {
|
||||
#if 0 // See https://bugzilla.mozilla.org/show_bug.cgi?id=1590902
|
||||
if (initialize_iaudioclient3(audio_client, stm, mix_format, flags, direction)) {
|
||||
LOG("Initialized with IAudioClient3");
|
||||
} else {
|
||||
hr = audio_client->Initialize(AUDCLNT_SHAREMODE_SHARED, flags, latency_hns,
|
||||
0, mix_format.get(), NULL);
|
||||
#endif
|
||||
hr = audio_client->Initialize(AUDCLNT_SHAREMODE_SHARED, flags, latency_hns, 0,
|
||||
mix_format.get(), NULL);
|
||||
#if 0
|
||||
}
|
||||
|
||||
#endif
|
||||
if (FAILED(hr)) {
|
||||
LOG("Unable to initialize audio client for %s: %lx.", DIRECTION_NAME, hr);
|
||||
return CUBEB_ERROR;
|
||||
@@ -2970,6 +2876,7 @@ wasapi_stream_init(cubeb * context, cubeb_stream ** stream,
|
||||
}
|
||||
}
|
||||
|
||||
cubeb_async_log_reset_threads();
|
||||
stm->thread =
|
||||
(HANDLE)_beginthreadex(NULL, 512 * 1024, wasapi_stream_render_loop, stm,
|
||||
STACK_SIZE_PARAM_IS_A_RESERVATION, NULL);
|
||||
@@ -3031,7 +2938,7 @@ wasapi_stream_add_ref(cubeb_stream * stm)
|
||||
{
|
||||
XASSERT(stm);
|
||||
LONG result = InterlockedIncrement(&stm->ref_count);
|
||||
LOGV("Stream ref count incremented = %i (%p)", result, stm);
|
||||
LOGV("Stream ref count incremented = %ld (%p)", result, stm);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -3041,7 +2948,7 @@ wasapi_stream_release(cubeb_stream * stm)
|
||||
XASSERT(stm);
|
||||
|
||||
LONG result = InterlockedDecrement(&stm->ref_count);
|
||||
LOGV("Stream ref count decremented = %i (%p)", result, stm);
|
||||
LOGV("Stream ref count decremented = %ld (%p)", result, stm);
|
||||
if (result == 0) {
|
||||
LOG("Stream ref count hit zero, destroying (%p)", stm);
|
||||
|
||||
@@ -3303,7 +3210,7 @@ wasapi_stream_set_volume(cubeb_stream * stm, float volume)
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
static char const *
|
||||
static std::unique_ptr<char const[]>
|
||||
wstr_to_utf8(LPCWSTR str)
|
||||
{
|
||||
int size = ::WideCharToMultiByte(CP_UTF8, 0, str, -1, nullptr, 0, NULL, NULL);
|
||||
@@ -3311,8 +3218,8 @@ wstr_to_utf8(LPCWSTR str)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
char * ret = static_cast<char *>(malloc(size));
|
||||
::WideCharToMultiByte(CP_UTF8, 0, str, -1, ret, size, NULL, NULL);
|
||||
std::unique_ptr<char[]> ret(new char[size]);
|
||||
::WideCharToMultiByte(CP_UTF8, 0, str, -1, ret.get(), size, NULL, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -3440,7 +3347,7 @@ wasapi_create_device(cubeb * ctx, cubeb_device_info & ret,
|
||||
prop_variant namevar;
|
||||
hr = propstore->GetValue(PKEY_Device_FriendlyName, &namevar);
|
||||
if (SUCCEEDED(hr) && namevar.vt == VT_LPWSTR) {
|
||||
ret.friendly_name = wstr_to_utf8(namevar.pwszVal);
|
||||
ret.friendly_name = wstr_to_utf8(namevar.pwszVal).release();
|
||||
}
|
||||
if (!ret.friendly_name) {
|
||||
// This is not fatal, but a valid string is expected in all cases.
|
||||
@@ -3461,7 +3368,7 @@ wasapi_create_device(cubeb * ctx, cubeb_device_info & ret,
|
||||
prop_variant instancevar;
|
||||
hr = ps->GetValue(PKEY_Device_InstanceId, &instancevar);
|
||||
if (SUCCEEDED(hr) && instancevar.vt == VT_LPWSTR) {
|
||||
ret.group_id = wstr_to_utf8(instancevar.pwszVal);
|
||||
ret.group_id = wstr_to_utf8(instancevar.pwszVal).release();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3477,7 +3384,8 @@ wasapi_create_device(cubeb * ctx, cubeb_device_info & ret,
|
||||
ret.preferred =
|
||||
(cubeb_device_pref)(ret.preferred | CUBEB_DEVICE_PREF_MULTIMEDIA |
|
||||
CUBEB_DEVICE_PREF_NOTIFICATION);
|
||||
} else if (defaults->is_default(flow, eCommunications, device_id.get())) {
|
||||
}
|
||||
if (defaults->is_default(flow, eCommunications, device_id.get())) {
|
||||
ret.preferred =
|
||||
(cubeb_device_pref)(ret.preferred | CUBEB_DEVICE_PREF_VOICE);
|
||||
}
|
||||
@@ -3504,7 +3412,6 @@ wasapi_create_device(cubeb * ctx, cubeb_device_info & ret,
|
||||
CUBEB_DEVICE_FMT_S16NE);
|
||||
ret.default_format = CUBEB_DEVICE_FMT_F32NE;
|
||||
prop_variant fmtvar;
|
||||
WAVEFORMATEX * wfx = NULL;
|
||||
hr = propstore->GetValue(PKEY_AudioEngine_DeviceFormat, &fmtvar);
|
||||
if (SUCCEEDED(hr) && fmtvar.vt == VT_BLOB) {
|
||||
if (fmtvar.blob.cbSize == sizeof(PCMWAVEFORMAT)) {
|
||||
@@ -3514,7 +3421,8 @@ wasapi_create_device(cubeb * ctx, cubeb_device_info & ret,
|
||||
ret.max_rate = ret.min_rate = ret.default_rate = pcm->wf.nSamplesPerSec;
|
||||
ret.max_channels = pcm->wf.nChannels;
|
||||
} else if (fmtvar.blob.cbSize >= sizeof(WAVEFORMATEX)) {
|
||||
wfx = reinterpret_cast<WAVEFORMATEX *>(fmtvar.blob.pBlobData);
|
||||
WAVEFORMATEX * wfx =
|
||||
reinterpret_cast<WAVEFORMATEX *>(fmtvar.blob.pBlobData);
|
||||
|
||||
if (fmtvar.blob.cbSize >= sizeof(WAVEFORMATEX) + wfx->cbSize ||
|
||||
wfx->wFormatTag == WAVE_FORMAT_PCM) {
|
||||
@@ -3524,30 +3432,9 @@ wasapi_create_device(cubeb * ctx, cubeb_device_info & ret,
|
||||
}
|
||||
}
|
||||
|
||||
#if USE_AUDIO_CLIENT_3_MIN_PERIOD
|
||||
// Here we assume an IAudioClient3 stream will successfully
|
||||
// be initialized later (it might fail)
|
||||
#if ALLOW_AUDIO_CLIENT_3_FOR_INPUT
|
||||
constexpr bool allow_audio_client_3 = true;
|
||||
#else
|
||||
const bool allow_audio_client_3 = flow == eRender;
|
||||
#endif
|
||||
com_ptr<IAudioClient3> client3;
|
||||
uint32_t def, fun, min, max;
|
||||
if (allow_audio_client_3 && wfx &&
|
||||
SUCCEEDED(dev->Activate(__uuidof(IAudioClient3), CLSCTX_INPROC_SERVER,
|
||||
NULL, client3.receive_vpp())) &&
|
||||
SUCCEEDED(
|
||||
client3->GetSharedModeEnginePeriod(wfx, &def, &fun, &min, &max))) {
|
||||
ret.latency_lo = min;
|
||||
// This latency might actually be used as "default" and not "max" later on,
|
||||
// so we return the default (we never really want to use the max anyway)
|
||||
ret.latency_hi = def;
|
||||
} else
|
||||
#endif
|
||||
if (SUCCEEDED(dev->Activate(__uuidof(IAudioClient), CLSCTX_INPROC_SERVER,
|
||||
NULL, client.receive_vpp())) &&
|
||||
SUCCEEDED(client->GetDevicePeriod(&def_period, &min_period))) {
|
||||
if (SUCCEEDED(dev->Activate(__uuidof(IAudioClient), CLSCTX_INPROC_SERVER,
|
||||
NULL, client.receive_vpp())) &&
|
||||
SUCCEEDED(client->GetDevicePeriod(&def_period, &min_period))) {
|
||||
ret.latency_lo = hns_to_frames(ret.default_rate, min_period);
|
||||
ret.latency_hi = hns_to_frames(ret.default_rate, def_period);
|
||||
} else {
|
||||
@@ -3638,7 +3525,7 @@ wasapi_enumerate_devices(cubeb * context, cubeb_device_type type,
|
||||
{
|
||||
return wasapi_enumerate_devices_internal(
|
||||
context, type, out,
|
||||
DEVICE_STATE_ACTIVE /*| DEVICE_STATE_DISABLED | DEVICE_STATE_UNPLUGGED*/);
|
||||
DEVICE_STATE_ACTIVE | DEVICE_STATE_DISABLED | DEVICE_STATE_UNPLUGGED);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -3656,6 +3543,14 @@ wasapi_device_collection_destroy(cubeb * /*ctx*/,
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
int
|
||||
wasapi_set_input_processing_params(cubeb_stream * stream,
|
||||
cubeb_input_processing_params params)
|
||||
{
|
||||
LOG("Cannot set voice processing params after init. Use cubeb_stream_init.");
|
||||
return CUBEB_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static int
|
||||
wasapi_register_device_collection_changed(
|
||||
cubeb * context, cubeb_device_type devtype,
|
||||
@@ -3736,7 +3631,8 @@ cubeb_ops const wasapi_ops = {
|
||||
/*.get_max_channel_count =*/wasapi_get_max_channel_count,
|
||||
/*.get_min_latency =*/wasapi_get_min_latency,
|
||||
/*.get_preferred_sample_rate =*/wasapi_get_preferred_sample_rate,
|
||||
/*.get_supported_input_processing_params =*/NULL,
|
||||
/*.get_supported_input_processing_params =*/
|
||||
wasapi_get_supported_input_processing_params,
|
||||
/*.enumerate_devices =*/wasapi_enumerate_devices,
|
||||
/*.device_collection_destroy =*/wasapi_device_collection_destroy,
|
||||
/*.destroy =*/wasapi_destroy,
|
||||
@@ -3751,7 +3647,7 @@ cubeb_ops const wasapi_ops = {
|
||||
/*.stream_set_name =*/NULL,
|
||||
/*.stream_get_current_device =*/NULL,
|
||||
/*.stream_set_input_mute =*/NULL,
|
||||
/*.stream_set_input_processing_params =*/NULL,
|
||||
/*.stream_set_input_processing_params =*/wasapi_set_input_processing_params,
|
||||
/*.stream_device_destroy =*/NULL,
|
||||
/*.stream_register_device_changed_callback =*/NULL,
|
||||
/*.register_device_collection_changed =*/
|
||||
|
||||
19
3rdparty/cubeb/subprojects/speex/arch.h
vendored
19
3rdparty/cubeb/subprojects/speex/arch.h
vendored
@@ -41,10 +41,10 @@
|
||||
#ifdef FLOATING_POINT
|
||||
#error You cannot compile as floating point and fixed point at the same time
|
||||
#endif
|
||||
#ifdef _USE_SSE
|
||||
#ifdef USE_SSE
|
||||
#error SSE is only for floating-point
|
||||
#endif
|
||||
#if ((defined (ARM4_ASM)||defined (ARM4_ASM)) && defined(BFIN_ASM)) || (defined (ARM4_ASM)&&defined(ARM5E_ASM))
|
||||
#if defined(ARM4_ASM) + defined(ARM5E_ASM) + defined(BFIN_ASM) > 1
|
||||
#error Make up your mind. What CPU do you have?
|
||||
#endif
|
||||
#ifdef VORBIS_PSYCHO
|
||||
@@ -56,10 +56,10 @@
|
||||
#ifndef FLOATING_POINT
|
||||
#error You now need to define either FIXED_POINT or FLOATING_POINT
|
||||
#endif
|
||||
#if defined (ARM4_ASM) || defined(ARM5E_ASM) || defined(BFIN_ASM)
|
||||
#if defined(ARM4_ASM) || defined(ARM5E_ASM) || defined(BFIN_ASM)
|
||||
#error I suppose you can have a [ARM4/ARM5E/Blackfin] that has float instructions?
|
||||
#endif
|
||||
#ifdef FIXED_POINT_DEBUG
|
||||
#ifdef FIXED_DEBUG
|
||||
#error "Don't you think enabling fixed-point is a good thing to do if you want to debug that?"
|
||||
#endif
|
||||
|
||||
@@ -117,9 +117,9 @@ typedef spx_word32_t spx_sig_t;
|
||||
|
||||
#ifdef ARM5E_ASM
|
||||
#include "fixed_arm5e.h"
|
||||
#elif defined (ARM4_ASM)
|
||||
#elif defined(ARM4_ASM)
|
||||
#include "fixed_arm4.h"
|
||||
#elif defined (BFIN_ASM)
|
||||
#elif defined(BFIN_ASM)
|
||||
#include "fixed_bfin.h"
|
||||
#endif
|
||||
|
||||
@@ -177,16 +177,13 @@ typedef float spx_word32_t;
|
||||
#define ADD32(a,b) ((a)+(b))
|
||||
#define SUB32(a,b) ((a)-(b))
|
||||
#define MULT16_16_16(a,b) ((a)*(b))
|
||||
#define MULT16_32_32(a,b) ((a)*(b))
|
||||
#define MULT16_16(a,b) ((spx_word32_t)(a)*(spx_word32_t)(b))
|
||||
#define MAC16_16(c,a,b) ((c)+(spx_word32_t)(a)*(spx_word32_t)(b))
|
||||
|
||||
#define MULT16_32_Q11(a,b) ((a)*(b))
|
||||
#define MULT16_32_Q13(a,b) ((a)*(b))
|
||||
#define MULT16_32_Q14(a,b) ((a)*(b))
|
||||
#define MULT16_32_Q15(a,b) ((a)*(b))
|
||||
#define MULT16_32_P15(a,b) ((a)*(b))
|
||||
|
||||
#define MAC16_32_Q11(c,a,b) ((c)+(a)*(b))
|
||||
#define MAC16_32_Q15(c,a,b) ((c)+(a)*(b))
|
||||
|
||||
#define MAC16_16_Q11(c,a,b) ((c)+(a)*(b))
|
||||
@@ -210,7 +207,7 @@ typedef float spx_word32_t;
|
||||
#endif
|
||||
|
||||
|
||||
#if defined (CONFIG_TI_C54X) || defined (CONFIG_TI_C55X)
|
||||
#if defined(CONFIG_TI_C54X) || defined(CONFIG_TI_C55X)
|
||||
|
||||
/* 2 on TI C5x DSP */
|
||||
#define BYTES_PER_CHAR 2
|
||||
|
||||
16
3rdparty/cubeb/subprojects/speex/fixed_generic.h
vendored
16
3rdparty/cubeb/subprojects/speex/fixed_generic.h
vendored
@@ -69,22 +69,18 @@
|
||||
|
||||
|
||||
/* result fits in 16 bits */
|
||||
#define MULT16_16_16(a,b) ((((spx_word16_t)(a))*((spx_word16_t)(b))))
|
||||
#define MULT16_16_16(a,b) (((spx_word16_t)(a))*((spx_word16_t)(b)))
|
||||
/* result fits in 32 bits */
|
||||
#define MULT16_32_32(a,b) (((spx_word16_t)(a))*((spx_word32_t)(b)))
|
||||
|
||||
/* (spx_word32_t)(spx_word16_t) gives TI compiler a hint that it's 16x16->32 multiply */
|
||||
#define MULT16_16(a,b) (((spx_word32_t)(spx_word16_t)(a))*((spx_word32_t)(spx_word16_t)(b)))
|
||||
|
||||
#define MAC16_16(c,a,b) (ADD32((c),MULT16_16((a),(b))))
|
||||
#define MULT16_32_Q12(a,b) ADD32(MULT16_16((a),SHR((b),12)), SHR(MULT16_16((a),((b)&0x00000fff)),12))
|
||||
#define MULT16_32_Q13(a,b) ADD32(MULT16_16((a),SHR((b),13)), SHR(MULT16_16((a),((b)&0x00001fff)),13))
|
||||
#define MULT16_32_Q14(a,b) ADD32(MULT16_16((a),SHR((b),14)), SHR(MULT16_16((a),((b)&0x00003fff)),14))
|
||||
|
||||
#define MULT16_32_Q11(a,b) ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11))
|
||||
#define MAC16_32_Q11(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11)))
|
||||
|
||||
#define MULT16_32_P15(a,b) ADD32(MULT16_16((a),SHR((b),15)), PSHR(MULT16_16((a),((b)&0x00007fff)),15))
|
||||
#define MULT16_32_Q15(a,b) ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15))
|
||||
#define MAC16_32_Q15(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15)))
|
||||
#define MULT16_32_P15(a,b) ADD32(MULT16_32_32(a,SHR((b),15)), PSHR(MULT16_16((a),((b)&0x00007fff)),15))
|
||||
#define MULT16_32_Q15(a,b) ADD32(MULT16_32_32(a,SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15))
|
||||
#define MAC16_32_Q15(c,a,b) ADD32(c,MULT16_32_Q15(a,b))
|
||||
|
||||
|
||||
#define MAC16_16_Q11(c,a,b) (ADD32((c),SHR(MULT16_16((a),(b)),11)))
|
||||
|
||||
90
3rdparty/cubeb/subprojects/speex/resample.c
vendored
90
3rdparty/cubeb/subprojects/speex/resample.c
vendored
@@ -46,7 +46,7 @@
|
||||
Smith, Julius O. Digital Audio Resampling Home Page
|
||||
Center for Computer Research in Music and Acoustics (CCRMA),
|
||||
Stanford University, 2007.
|
||||
Web published at http://ccrma.stanford.edu/~jos/resample/.
|
||||
Web published at https://ccrma.stanford.edu/~jos/resample/.
|
||||
|
||||
There is one main difference, though. This resampler uses cubic
|
||||
interpolation instead of linear interpolation in the above paper. This
|
||||
@@ -63,9 +63,12 @@
|
||||
|
||||
#ifdef OUTSIDE_SPEEX
|
||||
#include <stdlib.h>
|
||||
static void *speex_alloc (int size) {return calloc(size,1);}
|
||||
static void *speex_realloc (void *ptr, int size) {return realloc(ptr, size);}
|
||||
static void speex_free (void *ptr) {free(ptr);}
|
||||
static void *speex_alloc(int size) {return calloc(size,1);}
|
||||
static void *speex_realloc(void *ptr, int size) {return realloc(ptr, size);}
|
||||
static void speex_free(void *ptr) {free(ptr);}
|
||||
#ifndef EXPORT
|
||||
#define EXPORT
|
||||
#endif
|
||||
#include "speex_resampler.h"
|
||||
#include "arch.h"
|
||||
#else /* OUTSIDE_SPEEX */
|
||||
@@ -75,7 +78,6 @@ static void speex_free (void *ptr) {free(ptr);}
|
||||
#include "os_support.h"
|
||||
#endif /* OUTSIDE_SPEEX */
|
||||
|
||||
#include "stack_alloc.h"
|
||||
#include <math.h>
|
||||
#include <limits.h>
|
||||
|
||||
@@ -91,18 +93,18 @@ static void speex_free (void *ptr) {free(ptr);}
|
||||
#endif
|
||||
|
||||
#ifndef UINT32_MAX
|
||||
#define UINT32_MAX 4294967296U
|
||||
#define UINT32_MAX 4294967295U
|
||||
#endif
|
||||
|
||||
#ifdef _USE_SSE
|
||||
#ifdef USE_SSE
|
||||
#include "resample_sse.h"
|
||||
#endif
|
||||
|
||||
#ifdef _USE_NEON
|
||||
#ifdef USE_NEON
|
||||
#include "resample_neon.h"
|
||||
#endif
|
||||
|
||||
/* Numer of elements to allocate on the stack */
|
||||
/* Number of elements to allocate on the stack */
|
||||
#ifdef VAR_ARRAYS
|
||||
#define FIXED_STACK_ALLOC 8192
|
||||
#else
|
||||
@@ -194,16 +196,14 @@ struct FuncDef {
|
||||
int oversample;
|
||||
};
|
||||
|
||||
static const struct FuncDef _KAISER12 = {kaiser12_table, 64};
|
||||
#define KAISER12 (&_KAISER12)
|
||||
/*static struct FuncDef _KAISER12 = {kaiser12_table, 32};
|
||||
#define KAISER12 (&_KAISER12)*/
|
||||
static const struct FuncDef _KAISER10 = {kaiser10_table, 32};
|
||||
#define KAISER10 (&_KAISER10)
|
||||
static const struct FuncDef _KAISER8 = {kaiser8_table, 32};
|
||||
#define KAISER8 (&_KAISER8)
|
||||
static const struct FuncDef _KAISER6 = {kaiser6_table, 32};
|
||||
#define KAISER6 (&_KAISER6)
|
||||
static const struct FuncDef kaiser12_funcdef = {kaiser12_table, 64};
|
||||
#define KAISER12 (&kaiser12_funcdef)
|
||||
static const struct FuncDef kaiser10_funcdef = {kaiser10_table, 32};
|
||||
#define KAISER10 (&kaiser10_funcdef)
|
||||
static const struct FuncDef kaiser8_funcdef = {kaiser8_table, 32};
|
||||
#define KAISER8 (&kaiser8_funcdef)
|
||||
static const struct FuncDef kaiser6_funcdef = {kaiser6_table, 32};
|
||||
#define KAISER6 (&kaiser6_funcdef)
|
||||
|
||||
struct QualityMapping {
|
||||
int base_length;
|
||||
@@ -473,7 +473,7 @@ static int resampler_basic_interpolate_single(SpeexResamplerState *st, spx_uint3
|
||||
}
|
||||
|
||||
cubic_coef(frac, interp);
|
||||
sum = MULT16_32_Q15(interp[0],SHR32(accum[0], 1)) + MULT16_32_Q15(interp[1],SHR32(accum[1], 1)) + MULT16_32_Q15(interp[2],SHR32(accum[2], 1)) + MULT16_32_Q15(interp[3],SHR32(accum[3], 1));
|
||||
sum = MULT16_32_Q15(interp[0],accum[0]) + MULT16_32_Q15(interp[1],accum[1]) + MULT16_32_Q15(interp[2],accum[2]) + MULT16_32_Q15(interp[3],accum[3]);
|
||||
sum = SATURATE32PSHR(sum, 15, 32767);
|
||||
#else
|
||||
cubic_coef(frac, interp);
|
||||
@@ -572,6 +572,7 @@ static int resampler_basic_zero(SpeexResamplerState *st, spx_uint32_t channel_in
|
||||
const int frac_advance = st->frac_advance;
|
||||
const spx_uint32_t den_rate = st->den_rate;
|
||||
|
||||
(void)in;
|
||||
while (!(last_sample >= (spx_int32_t)*in_len || out_sample >= (spx_int32_t)*out_len))
|
||||
{
|
||||
out[out_stride * out_sample++] = 0;
|
||||
@@ -589,16 +590,15 @@ static int resampler_basic_zero(SpeexResamplerState *st, spx_uint32_t channel_in
|
||||
return out_sample;
|
||||
}
|
||||
|
||||
static int _muldiv(spx_uint32_t *result, spx_uint32_t value, spx_uint32_t mul, spx_uint32_t div)
|
||||
static int multiply_frac(spx_uint32_t *result, spx_uint32_t value, spx_uint32_t num, spx_uint32_t den)
|
||||
{
|
||||
speex_assert(result);
|
||||
spx_uint32_t major = value / div;
|
||||
spx_uint32_t remainder = value % div;
|
||||
spx_uint32_t major = value / den;
|
||||
spx_uint32_t remain = value % den;
|
||||
/* TODO: Could use 64 bits operation to check for overflow. But only guaranteed in C99+ */
|
||||
if (remainder > UINT32_MAX / mul || major > UINT32_MAX / mul
|
||||
|| major * mul > UINT32_MAX - remainder * mul / div)
|
||||
if (remain > UINT32_MAX / num || major > UINT32_MAX / num
|
||||
|| major * num > UINT32_MAX - remain * num / den)
|
||||
return RESAMPLER_ERR_OVERFLOW;
|
||||
*result = remainder * mul / div + major * mul;
|
||||
*result = remain * num / den + major * num;
|
||||
return RESAMPLER_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -619,7 +619,7 @@ static int update_filter(SpeexResamplerState *st)
|
||||
{
|
||||
/* down-sampling */
|
||||
st->cutoff = quality_map[st->quality].downsample_bandwidth * st->den_rate / st->num_rate;
|
||||
if (_muldiv(&st->filt_len,st->filt_len,st->num_rate,st->den_rate) != RESAMPLER_ERR_SUCCESS)
|
||||
if (multiply_frac(&st->filt_len,st->filt_len,st->num_rate,st->den_rate) != RESAMPLER_ERR_SUCCESS)
|
||||
goto fail;
|
||||
/* Round up to make sure we have a multiple of 8 for SSE */
|
||||
st->filt_len = ((st->filt_len-1)&(~0x7))+8;
|
||||
@@ -638,12 +638,12 @@ static int update_filter(SpeexResamplerState *st)
|
||||
st->cutoff = quality_map[st->quality].upsample_bandwidth;
|
||||
}
|
||||
|
||||
/* Choose the resampling type that requires the least amount of memory */
|
||||
#ifdef RESAMPLE_FULL_SINC_TABLE
|
||||
use_direct = 1;
|
||||
if (INT_MAX/sizeof(spx_word16_t)/st->den_rate < st->filt_len)
|
||||
goto fail;
|
||||
#else
|
||||
/* Choose the resampling type that requires the least amount of memory */
|
||||
use_direct = st->filt_len*st->den_rate <= st->filt_len*st->oversample+8
|
||||
&& INT_MAX/sizeof(spx_word16_t)/st->den_rate >= st->filt_len;
|
||||
#endif
|
||||
@@ -733,16 +733,18 @@ static int update_filter(SpeexResamplerState *st)
|
||||
{
|
||||
spx_uint32_t j;
|
||||
spx_uint32_t olen = old_length;
|
||||
spx_uint32_t start = i*st->mem_alloc_size;
|
||||
spx_uint32_t magic_samples = st->magic_samples[i];
|
||||
/*if (st->magic_samples[i])*/
|
||||
{
|
||||
/* Try and remove the magic samples as if nothing had happened */
|
||||
|
||||
/* FIXME: This is wrong but for now we need it to avoid going over the array bounds */
|
||||
olen = old_length + 2*st->magic_samples[i];
|
||||
for (j=old_length-1+st->magic_samples[i];j--;)
|
||||
st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]] = st->mem[i*old_alloc_size+j];
|
||||
for (j=0;j<st->magic_samples[i];j++)
|
||||
st->mem[i*st->mem_alloc_size+j] = 0;
|
||||
olen = old_length + 2*magic_samples;
|
||||
for (j=old_length-1+magic_samples;j--;)
|
||||
st->mem[start+j+magic_samples] = st->mem[i*old_alloc_size+j];
|
||||
for (j=0;j<magic_samples;j++)
|
||||
st->mem[start+j] = 0;
|
||||
st->magic_samples[i] = 0;
|
||||
}
|
||||
if (st->filt_len > olen)
|
||||
@@ -750,17 +752,18 @@ static int update_filter(SpeexResamplerState *st)
|
||||
/* If the new filter length is still bigger than the "augmented" length */
|
||||
/* Copy data going backward */
|
||||
for (j=0;j<olen-1;j++)
|
||||
st->mem[i*st->mem_alloc_size+(st->filt_len-2-j)] = st->mem[i*st->mem_alloc_size+(olen-2-j)];
|
||||
st->mem[start+(st->filt_len-2-j)] = st->mem[start+(olen-2-j)];
|
||||
/* Then put zeros for lack of anything better */
|
||||
for (;j<st->filt_len-1;j++)
|
||||
st->mem[i*st->mem_alloc_size+(st->filt_len-2-j)] = 0;
|
||||
st->mem[start+(st->filt_len-2-j)] = 0;
|
||||
/* Adjust last_sample */
|
||||
st->last_sample[i] += (st->filt_len - olen)/2;
|
||||
} else {
|
||||
/* Put back some of the magic! */
|
||||
st->magic_samples[i] = (olen - st->filt_len)/2;
|
||||
for (j=0;j<st->filt_len-1+st->magic_samples[i];j++)
|
||||
st->mem[i*st->mem_alloc_size+j] = st->mem[i*st->mem_alloc_size+j+st->magic_samples[i]];
|
||||
magic_samples = (olen - st->filt_len)/2;
|
||||
for (j=0;j<st->filt_len-1+magic_samples;j++)
|
||||
st->mem[start+j] = st->mem[start+j+magic_samples];
|
||||
st->magic_samples[i] = magic_samples;
|
||||
}
|
||||
}
|
||||
} else if (st->filt_len < old_length)
|
||||
@@ -977,8 +980,7 @@ EXPORT int speex_resampler_process_int(SpeexResamplerState *st, spx_uint32_t cha
|
||||
const spx_uint32_t xlen = st->mem_alloc_size - (st->filt_len - 1);
|
||||
#ifdef VAR_ARRAYS
|
||||
const unsigned int ylen = (olen < FIXED_STACK_ALLOC) ? olen : FIXED_STACK_ALLOC;
|
||||
VARDECL(spx_word16_t *ystack);
|
||||
ALLOC(ystack, ylen, spx_word16_t);
|
||||
spx_word16_t ystack[ylen];
|
||||
#else
|
||||
const unsigned int ylen = FIXED_STACK_ALLOC;
|
||||
spx_word16_t ystack[FIXED_STACK_ALLOC];
|
||||
@@ -1093,7 +1095,7 @@ EXPORT void speex_resampler_get_rate(SpeexResamplerState *st, spx_uint32_t *in_r
|
||||
*out_rate = st->out_rate;
|
||||
}
|
||||
|
||||
static inline spx_uint32_t _gcd(spx_uint32_t a, spx_uint32_t b)
|
||||
static inline spx_uint32_t compute_gcd(spx_uint32_t a, spx_uint32_t b)
|
||||
{
|
||||
while (b != 0)
|
||||
{
|
||||
@@ -1123,7 +1125,7 @@ EXPORT int speex_resampler_set_rate_frac(SpeexResamplerState *st, spx_uint32_t r
|
||||
st->num_rate = ratio_num;
|
||||
st->den_rate = ratio_den;
|
||||
|
||||
fact = _gcd (st->num_rate, st->den_rate);
|
||||
fact = compute_gcd(st->num_rate, st->den_rate);
|
||||
|
||||
st->num_rate /= fact;
|
||||
st->den_rate /= fact;
|
||||
@@ -1132,7 +1134,7 @@ EXPORT int speex_resampler_set_rate_frac(SpeexResamplerState *st, spx_uint32_t r
|
||||
{
|
||||
for (i=0;i<st->nb_channels;i++)
|
||||
{
|
||||
if (_muldiv(&st->samp_frac_num[i],st->samp_frac_num[i],st->den_rate,old_den) != RESAMPLER_ERR_SUCCESS)
|
||||
if (multiply_frac(&st->samp_frac_num[i],st->samp_frac_num[i],st->den_rate,old_den) != RESAMPLER_ERR_SUCCESS)
|
||||
return RESAMPLER_ERR_OVERFLOW;
|
||||
/* Safety net */
|
||||
if (st->samp_frac_num[i] >= st->den_rate)
|
||||
|
||||
168
3rdparty/cubeb/subprojects/speex/resample_neon.h
vendored
168
3rdparty/cubeb/subprojects/speex/resample_neon.h
vendored
@@ -36,14 +36,26 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <arm_neon.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
#ifdef __thumb2__
|
||||
#if defined(__aarch64__)
|
||||
static inline int32_t saturate_32bit_to_16bit(int32_t a) {
|
||||
int32_t ret;
|
||||
asm ("fmov s0, %w[a]\n"
|
||||
"sqxtn h0, s0\n"
|
||||
"sxtl v0.4s, v0.4h\n"
|
||||
"fmov %w[ret], s0\n"
|
||||
: [ret] "=r" (ret)
|
||||
: [a] "r" (a)
|
||||
: "v0" );
|
||||
return ret;
|
||||
}
|
||||
#elif defined(__thumb2__)
|
||||
static inline int32_t saturate_32bit_to_16bit(int32_t a) {
|
||||
int32_t ret;
|
||||
asm ("ssat %[ret], #16, %[a]"
|
||||
: [ret] "=&r" (ret)
|
||||
: [ret] "=r" (ret)
|
||||
: [a] "r" (a)
|
||||
: );
|
||||
return ret;
|
||||
@@ -54,7 +66,7 @@ static inline int32_t saturate_32bit_to_16bit(int32_t a) {
|
||||
asm ("vmov.s32 d0[0], %[a]\n"
|
||||
"vqmovn.s32 d0, q0\n"
|
||||
"vmov.s16 %[ret], d0[0]\n"
|
||||
: [ret] "=&r" (ret)
|
||||
: [ret] "=r" (ret)
|
||||
: [a] "r" (a)
|
||||
: "q0");
|
||||
return ret;
|
||||
@@ -64,7 +76,63 @@ static inline int32_t saturate_32bit_to_16bit(int32_t a) {
|
||||
#define WORD2INT(x) (saturate_32bit_to_16bit(x))
|
||||
|
||||
#define OVERRIDE_INNER_PRODUCT_SINGLE
|
||||
/* Only works when len % 4 == 0 */
|
||||
/* Only works when len % 4 == 0 and len >= 4 */
|
||||
#if defined(__aarch64__)
|
||||
static inline int32_t inner_product_single(const int16_t *a, const int16_t *b, unsigned int len)
|
||||
{
|
||||
int32_t ret;
|
||||
uint32_t remainder = len % 16;
|
||||
len = len - remainder;
|
||||
|
||||
asm volatile (" cmp %w[len], #0\n"
|
||||
" b.ne 1f\n"
|
||||
" ld1 {v16.4h}, [%[b]], #8\n"
|
||||
" ld1 {v20.4h}, [%[a]], #8\n"
|
||||
" subs %w[remainder], %w[remainder], #4\n"
|
||||
" smull v0.4s, v16.4h, v20.4h\n"
|
||||
" b.ne 4f\n"
|
||||
" b 5f\n"
|
||||
"1:"
|
||||
" ld1 {v16.4h, v17.4h, v18.4h, v19.4h}, [%[b]], #32\n"
|
||||
" ld1 {v20.4h, v21.4h, v22.4h, v23.4h}, [%[a]], #32\n"
|
||||
" subs %w[len], %w[len], #16\n"
|
||||
" smull v0.4s, v16.4h, v20.4h\n"
|
||||
" smlal v0.4s, v17.4h, v21.4h\n"
|
||||
" smlal v0.4s, v18.4h, v22.4h\n"
|
||||
" smlal v0.4s, v19.4h, v23.4h\n"
|
||||
" b.eq 3f\n"
|
||||
"2:"
|
||||
" ld1 {v16.4h, v17.4h, v18.4h, v19.4h}, [%[b]], #32\n"
|
||||
" ld1 {v20.4h, v21.4h, v22.4h, v23.4h}, [%[a]], #32\n"
|
||||
" subs %w[len], %w[len], #16\n"
|
||||
" smlal v0.4s, v16.4h, v20.4h\n"
|
||||
" smlal v0.4s, v17.4h, v21.4h\n"
|
||||
" smlal v0.4s, v18.4h, v22.4h\n"
|
||||
" smlal v0.4s, v19.4h, v23.4h\n"
|
||||
" b.ne 2b\n"
|
||||
"3:"
|
||||
" cmp %w[remainder], #0\n"
|
||||
" b.eq 5f\n"
|
||||
"4:"
|
||||
" ld1 {v18.4h}, [%[b]], #8\n"
|
||||
" ld1 {v22.4h}, [%[a]], #8\n"
|
||||
" subs %w[remainder], %w[remainder], #4\n"
|
||||
" smlal v0.4s, v18.4h, v22.4h\n"
|
||||
" b.ne 4b\n"
|
||||
"5:"
|
||||
" saddlv d0, v0.4s\n"
|
||||
" sqxtn s0, d0\n"
|
||||
" sqrshrn h0, s0, #15\n"
|
||||
" sxtl v0.4s, v0.4h\n"
|
||||
" fmov %w[ret], s0\n"
|
||||
: [ret] "=r" (ret), [a] "+r" (a), [b] "+r" (b),
|
||||
[len] "+r" (len), [remainder] "+r" (remainder)
|
||||
:
|
||||
: "cc", "v0",
|
||||
"v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23");
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
static inline int32_t inner_product_single(const int16_t *a, const int16_t *b, unsigned int len)
|
||||
{
|
||||
int32_t ret;
|
||||
@@ -112,33 +180,104 @@ static inline int32_t inner_product_single(const int16_t *a, const int16_t *b, u
|
||||
" vqmovn.s64 d0, q0\n"
|
||||
" vqrshrn.s32 d0, q0, #15\n"
|
||||
" vmov.s16 %[ret], d0[0]\n"
|
||||
: [ret] "=&r" (ret), [a] "+r" (a), [b] "+r" (b),
|
||||
: [ret] "=r" (ret), [a] "+r" (a), [b] "+r" (b),
|
||||
[len] "+r" (len), [remainder] "+r" (remainder)
|
||||
:
|
||||
: "cc", "q0",
|
||||
"d16", "d17", "d18", "d19",
|
||||
"d20", "d21", "d22", "d23");
|
||||
"d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23");
|
||||
|
||||
return ret;
|
||||
}
|
||||
#elif defined(FLOATING_POINT)
|
||||
#endif // !defined(__aarch64__)
|
||||
|
||||
#elif defined(FLOATING_POINT)
|
||||
#if defined(__aarch64__)
|
||||
static inline int32_t saturate_float_to_16bit(float a) {
|
||||
int32_t ret;
|
||||
asm ("fcvtas s1, %s[a]\n"
|
||||
"sqxtn h1, s1\n"
|
||||
"sxtl v1.4s, v1.4h\n"
|
||||
"fmov %w[ret], s1\n"
|
||||
: [ret] "=r" (ret)
|
||||
: [a] "w" (a)
|
||||
: "v1");
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
static inline int32_t saturate_float_to_16bit(float a) {
|
||||
int32_t ret;
|
||||
asm ("vmov.f32 d0[0], %[a]\n"
|
||||
"vcvt.s32.f32 d0, d0, #15\n"
|
||||
"vqrshrn.s32 d0, q0, #15\n"
|
||||
"vmov.s16 %[ret], d0[0]\n"
|
||||
: [ret] "=&r" (ret)
|
||||
: [ret] "=r" (ret)
|
||||
: [a] "r" (a)
|
||||
: "q0");
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef WORD2INT
|
||||
#define WORD2INT(x) (saturate_float_to_16bit(x))
|
||||
|
||||
#define OVERRIDE_INNER_PRODUCT_SINGLE
|
||||
/* Only works when len % 4 == 0 */
|
||||
/* Only works when len % 4 == 0 and len >= 4 */
|
||||
#if defined(__aarch64__)
|
||||
static inline float inner_product_single(const float *a, const float *b, unsigned int len)
|
||||
{
|
||||
float ret;
|
||||
uint32_t remainder = len % 16;
|
||||
len = len - remainder;
|
||||
|
||||
asm volatile (" cmp %w[len], #0\n"
|
||||
" b.ne 1f\n"
|
||||
" ld1 {v16.4s}, [%[b]], #16\n"
|
||||
" ld1 {v20.4s}, [%[a]], #16\n"
|
||||
" subs %w[remainder], %w[remainder], #4\n"
|
||||
" fmul v1.4s, v16.4s, v20.4s\n"
|
||||
" b.ne 4f\n"
|
||||
" b 5f\n"
|
||||
"1:"
|
||||
" ld1 {v16.4s, v17.4s, v18.4s, v19.4s}, [%[b]], #64\n"
|
||||
" ld1 {v20.4s, v21.4s, v22.4s, v23.4s}, [%[a]], #64\n"
|
||||
" subs %w[len], %w[len], #16\n"
|
||||
" fmul v1.4s, v16.4s, v20.4s\n"
|
||||
" fmul v2.4s, v17.4s, v21.4s\n"
|
||||
" fmul v3.4s, v18.4s, v22.4s\n"
|
||||
" fmul v4.4s, v19.4s, v23.4s\n"
|
||||
" b.eq 3f\n"
|
||||
"2:"
|
||||
" ld1 {v16.4s, v17.4s, v18.4s, v19.4s}, [%[b]], #64\n"
|
||||
" ld1 {v20.4s, v21.4s, v22.4s, v23.4s}, [%[a]], #64\n"
|
||||
" subs %w[len], %w[len], #16\n"
|
||||
" fmla v1.4s, v16.4s, v20.4s\n"
|
||||
" fmla v2.4s, v17.4s, v21.4s\n"
|
||||
" fmla v3.4s, v18.4s, v22.4s\n"
|
||||
" fmla v4.4s, v19.4s, v23.4s\n"
|
||||
" b.ne 2b\n"
|
||||
"3:"
|
||||
" fadd v16.4s, v1.4s, v2.4s\n"
|
||||
" fadd v17.4s, v3.4s, v4.4s\n"
|
||||
" cmp %w[remainder], #0\n"
|
||||
" fadd v1.4s, v16.4s, v17.4s\n"
|
||||
" b.eq 5f\n"
|
||||
"4:"
|
||||
" ld1 {v18.4s}, [%[b]], #16\n"
|
||||
" ld1 {v22.4s}, [%[a]], #16\n"
|
||||
" subs %w[remainder], %w[remainder], #4\n"
|
||||
" fmla v1.4s, v18.4s, v22.4s\n"
|
||||
" b.ne 4b\n"
|
||||
"5:"
|
||||
" faddp v1.4s, v1.4s, v1.4s\n"
|
||||
" faddp %[ret].4s, v1.4s, v1.4s\n"
|
||||
: [ret] "=w" (ret), [a] "+r" (a), [b] "+r" (b),
|
||||
[len] "+r" (len), [remainder] "+r" (remainder)
|
||||
:
|
||||
: "cc", "v1", "v2", "v3", "v4",
|
||||
"v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23");
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
static inline float inner_product_single(const float *a, const float *b, unsigned int len)
|
||||
{
|
||||
float ret;
|
||||
@@ -191,11 +330,12 @@ static inline float inner_product_single(const float *a, const float *b, unsigne
|
||||
" vadd.f32 d0, d0, d1\n"
|
||||
" vpadd.f32 d0, d0, d0\n"
|
||||
" vmov.f32 %[ret], d0[0]\n"
|
||||
: [ret] "=&r" (ret), [a] "+r" (a), [b] "+r" (b),
|
||||
: [ret] "=r" (ret), [a] "+r" (a), [b] "+r" (b),
|
||||
[len] "+l" (len), [remainder] "+l" (remainder)
|
||||
:
|
||||
: "cc", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8",
|
||||
"q9", "q10", "q11");
|
||||
: "cc", "q0", "q1", "q2", "q3",
|
||||
"q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11");
|
||||
return ret;
|
||||
}
|
||||
#endif // defined(__aarch64__)
|
||||
#endif
|
||||
|
||||
@@ -71,7 +71,7 @@ static inline float interpolate_product_single(const float *a, const float *b, u
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef _USE_SSE2
|
||||
#ifdef USE_SSE2
|
||||
#include <emmintrin.h>
|
||||
#define OVERRIDE_INNER_PRODUCT_DOUBLE
|
||||
|
||||
|
||||
31
3rdparty/d3d12memalloc/CHANGELOG.md
vendored
31
3rdparty/d3d12memalloc/CHANGELOG.md
vendored
@@ -1,3 +1,34 @@
|
||||
# 3.0.1 (2025-05-08)
|
||||
|
||||
- Fixed macros `D3D12MA_RECOMMENDED_ALLOCATOR_FLAGS`, `D3D12MA_RECOMMENDED_POOL_FLAGS` (#73).
|
||||
|
||||
# 3.0.0 (2025-05-05)
|
||||
|
||||
It has been a long time since the previous official release, so hopefully everyone has been using the latest code from "master" branch, which is always maintained in a good state, not the old version. For completeness, here is the list of changes since v2.0.1. The major version number has changed, so there are some compatibility-breaking changes, but the basic API stays the same and is mostly backward-compatible.
|
||||
|
||||
- Added helper structs: `CALLOCATION_DESC`, `CPOOL_DESC`, `CVIRTUAL_BLOCK_DESC`, `CVIRTUAL_ALLOCATION_DESC`.
|
||||
- Added macros: `D3D12MA_RECOMMENDED_ALLOCATOR_FLAGS`, `D3D12MA_RECOMMENDED_HEAP_FLAGS`, `D3D12MA_RECOMMENDED_POOL_FLAGS`.
|
||||
- Added functions: `Allocator::CreateResource3`, `CreateAliasingResource2`.
|
||||
- They support parameters: `D3D12_BARRIER_LAYOUT InitialLayout`, `const DXGI_FORMAT* pCastableFormats`.
|
||||
- They require recent DirectX 12 Agility SDK. To use them, `ID3D12Device10` must be available.
|
||||
To use non-empty list of castable formats, `ID3D12Device12` must be available.
|
||||
- Added support for GPU Upload Heaps (`D3D12_HEAP_TYPE_GPU_UPLOAD`).
|
||||
- Requires recent DirectX 12 Agility SDK. Support on the user's machine is available only when supported by the motherboard, GPU, drivers, and enabled as "Resizable BAR" in UEFI settings. It can be queried using new `Allocator::IsGPUUploadHeapSupported` function.
|
||||
- `TotalStatistics::HeapType` array was extended from 4 to 5 elements.
|
||||
- Added missing function `Allocator::CreateAliasingResource1`.
|
||||
- Added `POOL_DESC::ResidencyPriority` member.
|
||||
- Removed `Allocation::WasZeroInitialized` function. It wasn't fully implemented anyway.
|
||||
- Added `POOL_FLAG_ALWAYS_COMMITTED`.
|
||||
- Added a heuristic that prefers creating small buffers as committed to save memory.
|
||||
- It is enabled by default. It can be disabled by new flag `ALLOCATOR_FLAG_DONT_PREFER_SMALL_BUFFERS_COMMITTED`.
|
||||
- Macro `D3D12MA_OPTIONS16_SUPPORTED` is no longer exposed in the header or Cmake script.
|
||||
It is defined automatically based on the Agility SDK version.
|
||||
- Added macro `D3D12MA_DEBUG_LOG`, which can be used to log unfreed allocations.
|
||||
- Many improvements in the documentation, including new chapters: "Frequently asked questions", "Optimal resource allocation".
|
||||
- Countless fixes and improvements, including performance optimizations, compatibility with various compilers, tests.
|
||||
- Major changes in the Cmake script.
|
||||
- Fixes in "GpuMemDumpVis.py" script.
|
||||
|
||||
# 2.0.1 (2022-04-05)
|
||||
|
||||
A maintenance release with some bug fixes and improvements. There are no changes in the library API.
|
||||
|
||||
2
3rdparty/d3d12memalloc/LICENSE.txt
vendored
2
3rdparty/d3d12memalloc/LICENSE.txt
vendored
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2019-2024 Advanced Micro Devices, Inc. All rights reserved.
|
||||
Copyright (c) 2019-2025 Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
9
3rdparty/d3d12memalloc/README.md
vendored
9
3rdparty/d3d12memalloc/README.md
vendored
@@ -10,10 +10,6 @@ Easy to integrate memory allocation library for Direct3D 12.
|
||||
|
||||
**Product page:** [D3D12 Memory Allocator on GPUOpen](https://gpuopen.com/gaming-product/d3d12-memory-allocator/)
|
||||
|
||||
**Build status:**
|
||||
|
||||
Windows: [](https://ci.appveyor.com/project/adam-sawicki-amd/d3d12memoryallocator)
|
||||
|
||||
[](http://isitmaintained.com/project/GPUOpen-LibrariesAndSDKs/D3D12MemoryAllocator "Average time to resolve an issue")
|
||||
|
||||
# Problem
|
||||
@@ -91,7 +87,7 @@ With this one function call:
|
||||
|
||||
# Binaries
|
||||
|
||||
The release comes with precompiled binary executable for "D3D12Sample" application which contains test suite. It is compiled using Visual Studio 2019, so it requires appropriate libraries to work, including "MSVCP140.dll", "VCRUNTIME140.dll", "VCRUNTIME140_1.dll". If its launch fails with error message telling about those files missing, please download and install [Microsoft Visual C++ Redistributable for Visual Studio 2015, 2017 and 2019](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads), "x64" version.
|
||||
The release comes with precompiled binary executable for "D3D12Sample" application which contains test suite. It is compiled using Visual Studio 2022, so it requires appropriate libraries to work, including "MSVCP140.dll", "VCRUNTIME140.dll", "VCRUNTIME140_1.dll". If its launch fails with error message telling about those files missing, please download and install [Microsoft Visual C++ Redistributable](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170), "X64" version.
|
||||
|
||||
# Copyright notice
|
||||
|
||||
@@ -113,7 +109,8 @@ For more information see [NOTICES.txt](NOTICES.txt).
|
||||
|
||||
- **[Qt Project](https://github.com/qt)**
|
||||
- **[Ghost of Tsushima: Director's Cut PC](https://www.youtube.com/watch?v=cPKBDbCYctc&t=698s)** - Information avaliable in 11:38 of credits
|
||||
- **[Godot Engine](https://github.com/godotengine/godot/)** - multi-platform 2D and 3D game engine. License: MIT.
|
||||
- **[The Forge](https://github.com/ConfettiFX/The-Forge)** - cross-platform rendering framework. Apache License 2.0.
|
||||
- **[Wicked Engine<img src="https://github.com/turanszkij/WickedEngine/blob/master/Content/logo_small.png" width="28px" align="center"/>](https://github.com/turanszkij/WickedEngine)** - 3D engine with modern graphics
|
||||
- **[Wicked Engine](https://github.com/turanszkij/WickedEngine)** - 3D engine with modern graphics
|
||||
|
||||
[Some other projects on GitHub](https://github.com/search?q=D3D12MemAlloc.h&type=Code) and some game development studios that use DX12 in their games.
|
||||
|
||||
1062
3rdparty/d3d12memalloc/include/D3D12MemAlloc.h
vendored
1062
3rdparty/d3d12memalloc/include/D3D12MemAlloc.h
vendored
File diff suppressed because it is too large
Load Diff
467
3rdparty/d3d12memalloc/src/D3D12MemAlloc.cpp
vendored
467
3rdparty/d3d12memalloc/src/D3D12MemAlloc.cpp
vendored
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2019-2024 Advanced Micro Devices, Inc. All rights reserved.
|
||||
// Copyright (c) 2019-2025 Advanced Micro Devices, Inc. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -33,6 +33,13 @@
|
||||
#include <shared_mutex>
|
||||
#endif
|
||||
|
||||
// Includes needed for MinGW - see #71.
|
||||
#ifndef _MSC_VER
|
||||
#include <guiddef.h>
|
||||
// guiddef.h must be included first.
|
||||
#include <dxguids.h>
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -42,6 +49,14 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef _D3D12MA_CONFIGURATION
|
||||
|
||||
#if !defined(D3D12MA_CPP20)
|
||||
#if __cplusplus >= 202002L || _MSVC_LANG >= 202002L // C++20
|
||||
#define D3D12MA_CPP20 1
|
||||
#else
|
||||
#define D3D12MA_CPP20 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#if !defined(WINVER) || WINVER < 0x0600
|
||||
#error Required at least WinAPI version supporting: client = Windows Vista, server = Windows Server 2008.
|
||||
@@ -64,6 +79,10 @@
|
||||
#define D3D12MA_ASSERT(cond) assert(cond)
|
||||
#endif
|
||||
|
||||
#if D3D12MA_CPP20
|
||||
#include <bit>
|
||||
#endif
|
||||
|
||||
// Assert that will be called very often, like inside data structures e.g. operator[].
|
||||
// Making it non-empty can make program slow.
|
||||
#ifndef D3D12MA_HEAVY_ASSERT
|
||||
@@ -107,6 +126,14 @@ especially to test compatibility with D3D12_RESOURCE_HEAP_TIER_1 on modern GPUs.
|
||||
#define D3D12MA_DEFAULT_BLOCK_SIZE (64ull * 1024 * 1024)
|
||||
#endif
|
||||
|
||||
#ifndef D3D12MA_OPTIONS16_SUPPORTED
|
||||
#if D3D12_SDK_VERSION >= 610
|
||||
#define D3D12MA_OPTIONS16_SUPPORTED 1
|
||||
#else
|
||||
#define D3D12MA_OPTIONS16_SUPPORTED 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef D3D12MA_DEBUG_LOG
|
||||
#define D3D12MA_DEBUG_LOG(format, ...)
|
||||
/*
|
||||
@@ -128,10 +155,6 @@ especially to test compatibility with D3D12_RESOURCE_HEAP_TIER_1 on modern GPUs.
|
||||
|
||||
#define D3D12MA_IID_PPV_ARGS(ppType) __uuidof(**(ppType)), reinterpret_cast<void**>(ppType)
|
||||
|
||||
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
|
||||
#define D3D12MA_CREATE_NOT_ZEROED_AVAILABLE 1
|
||||
#endif
|
||||
|
||||
namespace D3D12MA
|
||||
{
|
||||
static constexpr UINT HEAP_TYPE_COUNT = 5;
|
||||
@@ -292,6 +315,10 @@ static UINT8 BitScanLSB(UINT64 mask)
|
||||
if (_BitScanForward64(&pos, mask))
|
||||
return static_cast<UINT8>(pos);
|
||||
return UINT8_MAX;
|
||||
#elif D3D12MA_CPP20
|
||||
if (mask != 0)
|
||||
return static_cast<uint8_t>(std::countr_zero(mask));
|
||||
return UINT8_MAX;
|
||||
#elif defined __GNUC__ || defined __clang__
|
||||
return static_cast<UINT8>(__builtin_ffsll(mask)) - 1U;
|
||||
#else
|
||||
@@ -314,6 +341,10 @@ static UINT8 BitScanLSB(UINT32 mask)
|
||||
if (_BitScanForward(&pos, mask))
|
||||
return static_cast<UINT8>(pos);
|
||||
return UINT8_MAX;
|
||||
#elif D3D12MA_CPP20
|
||||
if (mask != 0)
|
||||
return static_cast<uint8_t>(std::countr_zero(mask));
|
||||
return UINT8_MAX;
|
||||
#elif defined __GNUC__ || defined __clang__
|
||||
return static_cast<UINT8>(__builtin_ffs(mask)) - 1U;
|
||||
#else
|
||||
@@ -336,6 +367,9 @@ static UINT8 BitScanMSB(UINT64 mask)
|
||||
unsigned long pos;
|
||||
if (_BitScanReverse64(&pos, mask))
|
||||
return static_cast<UINT8>(pos);
|
||||
#elif D3D12MA_CPP20
|
||||
if (mask != 0)
|
||||
return 63 - static_cast<uint8_t>(std::countl_zero(mask));
|
||||
#elif defined __GNUC__ || defined __clang__
|
||||
if (mask)
|
||||
return 63 - static_cast<UINT8>(__builtin_clzll(mask));
|
||||
@@ -358,6 +392,9 @@ static UINT8 BitScanMSB(UINT32 mask)
|
||||
unsigned long pos;
|
||||
if (_BitScanReverse(&pos, mask))
|
||||
return static_cast<UINT8>(pos);
|
||||
#elif D3D12MA_CPP20
|
||||
if (mask != 0)
|
||||
return 31 - static_cast<uint8_t>(std::countl_zero(mask));
|
||||
#elif defined __GNUC__ || defined __clang__
|
||||
if (mask)
|
||||
return 31 - static_cast<UINT8>(__builtin_clz(mask));
|
||||
@@ -2791,7 +2828,7 @@ class AllocationObjectAllocator
|
||||
D3D12MA_CLASS_NO_COPY(AllocationObjectAllocator);
|
||||
public:
|
||||
AllocationObjectAllocator(const ALLOCATION_CALLBACKS& allocationCallbacks, bool useMutex)
|
||||
: m_Allocator(allocationCallbacks, 1024), m_UseMutex(useMutex) {}
|
||||
: m_UseMutex(useMutex), m_Allocator(allocationCallbacks, 1024) {}
|
||||
|
||||
template<typename... Types>
|
||||
Allocation* Allocate(Types... args);
|
||||
@@ -2982,7 +3019,7 @@ void BlockMetadata::DebugLogAllocation(UINT64 offset, UINT64 size, void* private
|
||||
LPCWSTR name = allocation->GetName();
|
||||
|
||||
D3D12MA_DEBUG_LOG(L"UNFREED ALLOCATION; Offset: %llu; Size: %llu; PrivateData: %p; Name: %s",
|
||||
offset, size, privateData, name ? name : L"D3D12MA_Empty");
|
||||
offset, size, privateData, name ? name : L"");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5369,8 +5406,8 @@ struct CREATE_RESOURCE_PARAMS
|
||||
{
|
||||
CREATE_RESOURCE_PARAMS() = delete;
|
||||
CREATE_RESOURCE_PARAMS(
|
||||
const D3D12_RESOURCE_DESC* pResourceDesc,
|
||||
D3D12_RESOURCE_STATES InitialResourceState,
|
||||
const D3D12_RESOURCE_DESC* pResourceDesc,
|
||||
D3D12_RESOURCE_STATES InitialResourceState,
|
||||
const D3D12_CLEAR_VALUE* pOptimizedClearValue)
|
||||
: Variant(VARIANT_WITH_STATE)
|
||||
, pResourceDesc(pResourceDesc)
|
||||
@@ -5380,8 +5417,8 @@ struct CREATE_RESOURCE_PARAMS
|
||||
}
|
||||
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
|
||||
CREATE_RESOURCE_PARAMS(
|
||||
const D3D12_RESOURCE_DESC1* pResourceDesc,
|
||||
D3D12_RESOURCE_STATES InitialResourceState,
|
||||
const D3D12_RESOURCE_DESC1* pResourceDesc,
|
||||
D3D12_RESOURCE_STATES InitialResourceState,
|
||||
const D3D12_CLEAR_VALUE* pOptimizedClearValue)
|
||||
: Variant(VARIANT_WITH_STATE_AND_DESC1)
|
||||
, pResourceDesc1(pResourceDesc)
|
||||
@@ -5396,7 +5433,7 @@ struct CREATE_RESOURCE_PARAMS
|
||||
D3D12_BARRIER_LAYOUT InitialLayout,
|
||||
const D3D12_CLEAR_VALUE* pOptimizedClearValue,
|
||||
UINT32 NumCastableFormats,
|
||||
DXGI_FORMAT* pCastableFormats)
|
||||
const DXGI_FORMAT* pCastableFormats)
|
||||
: Variant(VARIANT_WITH_LAYOUT)
|
||||
, pResourceDesc1(pResourceDesc)
|
||||
, InitialLayout(InitialLayout)
|
||||
@@ -5466,7 +5503,7 @@ struct CREATE_RESOURCE_PARAMS
|
||||
D3D12MA_ASSERT(Variant >= VARIANT_WITH_LAYOUT);
|
||||
return NumCastableFormats;
|
||||
}
|
||||
DXGI_FORMAT* GetCastableFormats() const
|
||||
const DXGI_FORMAT* GetCastableFormats() const
|
||||
{
|
||||
D3D12MA_ASSERT(Variant >= VARIANT_WITH_LAYOUT);
|
||||
return pCastableFormats;
|
||||
@@ -5491,7 +5528,7 @@ private:
|
||||
const D3D12_CLEAR_VALUE* pOptimizedClearValue;
|
||||
#ifdef __ID3D12Device10_INTERFACE_DEFINED__
|
||||
UINT32 NumCastableFormats;
|
||||
DXGI_FORMAT* pCastableFormats;
|
||||
const DXGI_FORMAT* pCastableFormats;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -5541,6 +5578,7 @@ public:
|
||||
UINT64 size,
|
||||
UINT64 alignment,
|
||||
const ALLOCATION_DESC& allocDesc,
|
||||
bool committedAllowed,
|
||||
size_t allocationCount,
|
||||
Allocation** pAllocations);
|
||||
|
||||
@@ -5551,6 +5589,7 @@ public:
|
||||
UINT64 alignment,
|
||||
const ALLOCATION_DESC& allocDesc,
|
||||
const CREATE_RESOURCE_PARAMS& createParams,
|
||||
bool committedAllowed,
|
||||
Allocation** ppAllocation,
|
||||
REFIID riidResource,
|
||||
void** ppvResource);
|
||||
@@ -5601,6 +5640,7 @@ private:
|
||||
UINT64 size,
|
||||
UINT64 alignment,
|
||||
const ALLOCATION_DESC& allocDesc,
|
||||
bool committedAllowed,
|
||||
Allocation** pAllocation);
|
||||
|
||||
HRESULT AllocateFromBlock(
|
||||
@@ -5706,29 +5746,31 @@ HRESULT CurrentBudgetData::UpdateBudget(IDXGIAdapter3* adapter3, bool useMutex)
|
||||
DXGI_QUERY_VIDEO_MEMORY_INFO infoLocal = {};
|
||||
DXGI_QUERY_VIDEO_MEMORY_INFO infoNonLocal = {};
|
||||
const HRESULT hrLocal = adapter3->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_LOCAL, &infoLocal);
|
||||
if (FAILED(hrLocal))
|
||||
{
|
||||
return hrLocal;
|
||||
}
|
||||
const HRESULT hrNonLocal = adapter3->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL, &infoNonLocal);
|
||||
if (FAILED(hrNonLocal))
|
||||
{
|
||||
return hrNonLocal;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hrLocal) || SUCCEEDED(hrNonLocal))
|
||||
{
|
||||
MutexLockWrite lockWrite(m_BudgetMutex, useMutex);
|
||||
|
||||
if (SUCCEEDED(hrLocal))
|
||||
{
|
||||
m_D3D12Usage[0] = infoLocal.CurrentUsage;
|
||||
m_D3D12Budget[0] = infoLocal.Budget;
|
||||
}
|
||||
if (SUCCEEDED(hrNonLocal))
|
||||
{
|
||||
m_D3D12Usage[1] = infoNonLocal.CurrentUsage;
|
||||
m_D3D12Budget[1] = infoNonLocal.Budget;
|
||||
}
|
||||
m_D3D12Usage[0] = infoLocal.CurrentUsage;
|
||||
m_D3D12Budget[0] = infoLocal.Budget;
|
||||
|
||||
m_D3D12Usage[1] = infoNonLocal.CurrentUsage;
|
||||
m_D3D12Budget[1] = infoNonLocal.Budget;
|
||||
|
||||
m_BlockBytesAtD3D12Fetch[0] = m_BlockBytes[0];
|
||||
m_BlockBytesAtD3D12Fetch[1] = m_BlockBytes[1];
|
||||
m_OperationsSinceBudgetFetch = 0;
|
||||
}
|
||||
|
||||
return FAILED(hrLocal) ? hrLocal : hrNonLocal;
|
||||
return S_OK;
|
||||
}
|
||||
#endif // #if D3D12MA_DXGI_1_4
|
||||
|
||||
@@ -5847,6 +5889,7 @@ public:
|
||||
|
||||
AllocatorPimpl* GetAllocator() const { return m_Allocator; }
|
||||
const POOL_DESC& GetDesc() const { return m_Desc; }
|
||||
bool AlwaysCommitted() const { return (m_Desc.Flags & POOL_FLAG_ALWAYS_COMMITTED) != 0; }
|
||||
bool SupportsCommittedAllocations() const { return m_Desc.BlockSize == 0; }
|
||||
LPCWSTR GetName() const { return m_Name; }
|
||||
|
||||
@@ -5903,6 +5946,12 @@ public:
|
||||
#endif
|
||||
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
|
||||
ID3D12Device8* GetDevice8() const { return m_Device8; }
|
||||
#endif
|
||||
#ifdef __ID3D12Device10_INTERFACE_DEFINED__
|
||||
ID3D12Device10* GetDevice10() const { return m_Device10; }
|
||||
#endif
|
||||
#ifdef __ID3D12Device12_INTERFACE_DEFINED__
|
||||
ID3D12Device12* GetDevice12() const { return m_Device12; }
|
||||
#endif
|
||||
// Shortcut for "Allocation Callbacks", because this function is called so often.
|
||||
const ALLOCATION_CALLBACKS& GetAllocs() const { return m_AllocationCallbacks; }
|
||||
@@ -6011,6 +6060,9 @@ private:
|
||||
#endif
|
||||
#ifdef __ID3D12Device10_INTERFACE_DEFINED__
|
||||
ID3D12Device10* m_Device10 = NULL; // AddRef, optional
|
||||
#endif
|
||||
#ifdef __ID3D12Device12_INTERFACE_DEFINED__
|
||||
ID3D12Device12* m_Device12 = NULL; // AddRef, optional
|
||||
#endif
|
||||
IDXGIAdapter* m_Adapter; // AddRef
|
||||
#if D3D12MA_DXGI_1_4
|
||||
@@ -6071,12 +6123,26 @@ private:
|
||||
HRESULT UpdateD3D12Budget();
|
||||
|
||||
D3D12_RESOURCE_ALLOCATION_INFO GetResourceAllocationInfoNative(const D3D12_RESOURCE_DESC& resourceDesc) const;
|
||||
HRESULT GetResourceAllocationInfoMiddle(D3D12_RESOURCE_DESC& inOutResourceDesc,
|
||||
UINT32 NumCastableFormats, const DXGI_FORMAT* pCastableFormats,
|
||||
D3D12_RESOURCE_ALLOCATION_INFO& outAllocInfo) const;
|
||||
|
||||
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
|
||||
D3D12_RESOURCE_ALLOCATION_INFO GetResourceAllocationInfoNative(const D3D12_RESOURCE_DESC1& resourceDesc) const;
|
||||
D3D12_RESOURCE_ALLOCATION_INFO GetResourceAllocationInfo2Native(const D3D12_RESOURCE_DESC1& resourceDesc) const;
|
||||
HRESULT GetResourceAllocationInfoMiddle(D3D12_RESOURCE_DESC1& inOutResourceDesc,
|
||||
UINT32 NumCastableFormats, const DXGI_FORMAT* pCastableFormats,
|
||||
D3D12_RESOURCE_ALLOCATION_INFO& outAllocInfo) const;
|
||||
#endif
|
||||
|
||||
#ifdef __ID3D12Device12_INTERFACE_DEFINED__
|
||||
D3D12_RESOURCE_ALLOCATION_INFO GetResourceAllocationInfo3Native(const D3D12_RESOURCE_DESC1& resourceDesc,
|
||||
UINT32 NumCastableFormats, const DXGI_FORMAT* pCastableFormats) const;
|
||||
#endif
|
||||
|
||||
template<typename D3D12_RESOURCE_DESC_T>
|
||||
D3D12_RESOURCE_ALLOCATION_INFO GetResourceAllocationInfo(D3D12_RESOURCE_DESC_T& inOutResourceDesc) const;
|
||||
HRESULT GetResourceAllocationInfo(D3D12_RESOURCE_DESC_T& inOutResourceDesc,
|
||||
UINT32 NumCastableFormats, const DXGI_FORMAT* pCastableFormats,
|
||||
D3D12_RESOURCE_ALLOCATION_INFO& outAllocInfo) const;
|
||||
|
||||
bool NewAllocationWithinBudget(D3D12_HEAP_TYPE heapType, UINT64 size);
|
||||
|
||||
@@ -6148,6 +6214,10 @@ HRESULT AllocatorPimpl::Init(const ALLOCATOR_DESC& desc)
|
||||
m_Device->QueryInterface(D3D12MA_IID_PPV_ARGS(&m_Device10));
|
||||
#endif
|
||||
|
||||
#ifdef __ID3D12Device12_INTERFACE_DEFINED__
|
||||
m_Device->QueryInterface(D3D12MA_IID_PPV_ARGS(&m_Device12));
|
||||
#endif
|
||||
|
||||
HRESULT hr = m_Adapter->GetDesc(&m_AdapterDesc);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
@@ -6163,9 +6233,6 @@ HRESULT AllocatorPimpl::Init(const ALLOCATOR_DESC& desc)
|
||||
m_D3D12Options.ResourceHeapTier = (D3D12MA_FORCE_RESOURCE_HEAP_TIER);
|
||||
#endif
|
||||
|
||||
// You must define this macro to like `#define D3D12MA_OPTIONS16_SUPPORTED 1` to enable GPU Upload Heaps!
|
||||
// Unfortunately there is no way to programmatically check if the included <d3d12.h> defines D3D12_FEATURE_DATA_D3D12_OPTIONS16 or not.
|
||||
// Main interfaces have respective macros like __ID3D12Device4_INTERFACE_DEFINED__, but structures like this do not.
|
||||
#if D3D12MA_OPTIONS16_SUPPORTED
|
||||
{
|
||||
D3D12_FEATURE_DATA_D3D12_OPTIONS16 options16 = {};
|
||||
@@ -6175,7 +6242,7 @@ HRESULT AllocatorPimpl::Init(const ALLOCATOR_DESC& desc)
|
||||
m_GPUUploadHeapSupported = options16.GPUUploadHeapSupported;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // #if D3D12MA_OPTIONS16_SUPPORTED
|
||||
|
||||
hr = m_Device->CheckFeatureSupport(D3D12_FEATURE_ARCHITECTURE, &m_D3D12Architecture, sizeof(m_D3D12Architecture));
|
||||
if (FAILED(hr))
|
||||
@@ -6223,6 +6290,9 @@ HRESULT AllocatorPimpl::Init(const ALLOCATOR_DESC& desc)
|
||||
|
||||
AllocatorPimpl::~AllocatorPimpl()
|
||||
{
|
||||
#ifdef __ID3D12Device12_INTERFACE_DEFINED__
|
||||
SAFE_RELEASE(m_Device12);
|
||||
#endif
|
||||
#ifdef __ID3D12Device10_INTERFACE_DEFINED__
|
||||
SAFE_RELEASE(m_Device10);
|
||||
#endif
|
||||
@@ -6319,12 +6389,15 @@ HRESULT AllocatorPimpl::CreatePlacedResourceWrap(
|
||||
{
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
// Microsoft defined pCastableFormats parameter as pointer to non-const and only fixed it in later Agility SDK,
|
||||
// thus we need const_cast.
|
||||
return m_Device10->CreatePlacedResource2(pHeap, HeapOffset,
|
||||
createParams.GetResourceDesc1(), createParams.GetInitialLayout(),
|
||||
createParams.GetOptimizedClearValue(), createParams.GetNumCastableFormats(),
|
||||
createParams.GetCastableFormats(), riidResource, ppvResource);
|
||||
} else
|
||||
const_cast<DXGI_FORMAT*>(createParams.GetCastableFormats()), riidResource, ppvResource);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
|
||||
if (createParams.Variant == CREATE_RESOURCE_PARAMS::VARIANT_WITH_STATE_AND_DESC1)
|
||||
{
|
||||
@@ -6335,21 +6408,19 @@ HRESULT AllocatorPimpl::CreatePlacedResourceWrap(
|
||||
return m_Device8->CreatePlacedResource1(pHeap, HeapOffset,
|
||||
createParams.GetResourceDesc1(), createParams.GetInitialResourceState(),
|
||||
createParams.GetOptimizedClearValue(), riidResource, ppvResource);
|
||||
} else
|
||||
}
|
||||
#endif
|
||||
|
||||
if (createParams.Variant == CREATE_RESOURCE_PARAMS::VARIANT_WITH_STATE)
|
||||
{
|
||||
return m_Device->CreatePlacedResource(pHeap, HeapOffset,
|
||||
createParams.GetResourceDesc(), createParams.GetInitialResourceState(),
|
||||
createParams.GetOptimizedClearValue(), riidResource, ppvResource);
|
||||
}
|
||||
else
|
||||
{
|
||||
D3D12MA_ASSERT(0);
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
|
||||
D3D12MA_ASSERT(0);
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
HRESULT AllocatorPimpl::CreateResource(
|
||||
const ALLOCATION_DESC* pAllocDesc,
|
||||
@@ -6366,6 +6437,7 @@ HRESULT AllocatorPimpl::CreateResource(
|
||||
*ppvResource = NULL;
|
||||
}
|
||||
|
||||
HRESULT hr = E_NOINTERFACE;
|
||||
CREATE_RESOURCE_PARAMS finalCreateParams = createParams;
|
||||
D3D12_RESOURCE_DESC finalResourceDesc;
|
||||
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
|
||||
@@ -6376,45 +6448,49 @@ HRESULT AllocatorPimpl::CreateResource(
|
||||
{
|
||||
finalResourceDesc = *createParams.GetResourceDesc();
|
||||
finalCreateParams.AccessResourceDesc() = &finalResourceDesc;
|
||||
resAllocInfo = GetResourceAllocationInfo(finalResourceDesc);
|
||||
hr = GetResourceAllocationInfo(finalResourceDesc, 0, NULL, resAllocInfo);
|
||||
}
|
||||
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
|
||||
else if (createParams.Variant == CREATE_RESOURCE_PARAMS::VARIANT_WITH_STATE_AND_DESC1)
|
||||
{
|
||||
if (!m_Device8)
|
||||
if (m_Device8 != NULL)
|
||||
{
|
||||
return E_NOINTERFACE;
|
||||
finalResourceDesc1 = *createParams.GetResourceDesc1();
|
||||
finalCreateParams.AccessResourceDesc1() = &finalResourceDesc1;
|
||||
hr = GetResourceAllocationInfo(finalResourceDesc1, 0, NULL, resAllocInfo);
|
||||
}
|
||||
finalResourceDesc1 = *createParams.GetResourceDesc1();
|
||||
finalCreateParams.AccessResourceDesc1() = &finalResourceDesc1;
|
||||
resAllocInfo = GetResourceAllocationInfo(finalResourceDesc1);
|
||||
}
|
||||
#endif
|
||||
#ifdef __ID3D12Device10_INTERFACE_DEFINED__
|
||||
else if (createParams.Variant == CREATE_RESOURCE_PARAMS::VARIANT_WITH_LAYOUT)
|
||||
{
|
||||
if (!m_Device10)
|
||||
if (m_Device10 != NULL)
|
||||
{
|
||||
return E_NOINTERFACE;
|
||||
finalResourceDesc1 = *createParams.GetResourceDesc1();
|
||||
finalCreateParams.AccessResourceDesc1() = &finalResourceDesc1;
|
||||
hr = GetResourceAllocationInfo(finalResourceDesc1,
|
||||
createParams.GetNumCastableFormats(), createParams.GetCastableFormats(), resAllocInfo);
|
||||
}
|
||||
finalResourceDesc1 = *createParams.GetResourceDesc1();
|
||||
finalCreateParams.AccessResourceDesc1() = &finalResourceDesc1;
|
||||
resAllocInfo = GetResourceAllocationInfo(finalResourceDesc1);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
D3D12MA_ASSERT(0);
|
||||
return E_INVALIDARG;
|
||||
hr = E_INVALIDARG;
|
||||
}
|
||||
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
D3D12MA_ASSERT(IsPow2(resAllocInfo.Alignment));
|
||||
// We've seen UINT64_MAX returned when the call to GetResourceAllocationInfo was invalid.
|
||||
D3D12MA_ASSERT(resAllocInfo.SizeInBytes != UINT64_MAX);
|
||||
D3D12MA_ASSERT(resAllocInfo.SizeInBytes > 0);
|
||||
|
||||
BlockVector* blockVector = NULL;
|
||||
CommittedAllocationParameters committedAllocationParams = {};
|
||||
bool preferCommitted = false;
|
||||
|
||||
HRESULT hr;
|
||||
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
|
||||
if (createParams.Variant >= CREATE_RESOURCE_PARAMS::VARIANT_WITH_STATE_AND_DESC1)
|
||||
{
|
||||
@@ -6445,7 +6521,7 @@ HRESULT AllocatorPimpl::CreateResource(
|
||||
if (blockVector != NULL)
|
||||
{
|
||||
hr = blockVector->CreateResource(resAllocInfo.SizeInBytes, resAllocInfo.Alignment,
|
||||
*pAllocDesc, finalCreateParams,
|
||||
*pAllocDesc, finalCreateParams, committedAllocationParams.IsValid(),
|
||||
ppAllocation, riidResource, ppvResource);
|
||||
if (SUCCEEDED(hr))
|
||||
return hr;
|
||||
@@ -6488,7 +6564,7 @@ HRESULT AllocatorPimpl::AllocateMemory(
|
||||
if (blockVector != NULL)
|
||||
{
|
||||
hr = blockVector->Allocate(pAllocInfo->SizeInBytes, pAllocInfo->Alignment,
|
||||
*pAllocDesc, 1, (Allocation**)ppAllocation);
|
||||
*pAllocDesc, committedAllocationParams.IsValid(), 1, (Allocation**)ppAllocation);
|
||||
if (SUCCEEDED(hr))
|
||||
return hr;
|
||||
}
|
||||
@@ -6510,6 +6586,7 @@ HRESULT AllocatorPimpl::CreateAliasingResource(
|
||||
{
|
||||
*ppvResource = NULL;
|
||||
|
||||
HRESULT hr = E_NOINTERFACE;
|
||||
CREATE_RESOURCE_PARAMS finalCreateParams = createParams;
|
||||
D3D12_RESOURCE_DESC finalResourceDesc;
|
||||
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
|
||||
@@ -6520,37 +6597,40 @@ HRESULT AllocatorPimpl::CreateAliasingResource(
|
||||
{
|
||||
finalResourceDesc = *createParams.GetResourceDesc();
|
||||
finalCreateParams.AccessResourceDesc() = &finalResourceDesc;
|
||||
resAllocInfo = GetResourceAllocationInfo(finalResourceDesc);
|
||||
hr = GetResourceAllocationInfo(finalResourceDesc, 0, NULL, resAllocInfo);
|
||||
}
|
||||
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
|
||||
else if (createParams.Variant == CREATE_RESOURCE_PARAMS::VARIANT_WITH_STATE_AND_DESC1)
|
||||
{
|
||||
if (!m_Device8)
|
||||
if (m_Device8 != NULL)
|
||||
{
|
||||
return E_NOINTERFACE;
|
||||
finalResourceDesc1 = *createParams.GetResourceDesc1();
|
||||
finalCreateParams.AccessResourceDesc1() = &finalResourceDesc1;
|
||||
hr = GetResourceAllocationInfo(finalResourceDesc1, 0, NULL, resAllocInfo);
|
||||
}
|
||||
finalResourceDesc1 = *createParams.GetResourceDesc1();
|
||||
finalCreateParams.AccessResourceDesc1() = &finalResourceDesc1;
|
||||
resAllocInfo = GetResourceAllocationInfo(finalResourceDesc1);
|
||||
}
|
||||
#endif
|
||||
#ifdef __ID3D12Device10_INTERFACE_DEFINED__
|
||||
else if (createParams.Variant == CREATE_RESOURCE_PARAMS::VARIANT_WITH_LAYOUT)
|
||||
{
|
||||
if (!m_Device10)
|
||||
if (m_Device10 != NULL)
|
||||
{
|
||||
return E_NOINTERFACE;
|
||||
finalResourceDesc1 = *createParams.GetResourceDesc1();
|
||||
finalCreateParams.AccessResourceDesc1() = &finalResourceDesc1;
|
||||
hr = GetResourceAllocationInfo(finalResourceDesc1,
|
||||
createParams.GetNumCastableFormats(), createParams.GetCastableFormats(), resAllocInfo);
|
||||
}
|
||||
finalResourceDesc1 = *createParams.GetResourceDesc1();
|
||||
finalCreateParams.AccessResourceDesc1() = &finalResourceDesc1;
|
||||
resAllocInfo = GetResourceAllocationInfo(finalResourceDesc1);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
D3D12MA_ASSERT(0);
|
||||
return E_INVALIDARG;
|
||||
hr = E_INVALIDARG;
|
||||
}
|
||||
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
D3D12MA_ASSERT(IsPow2(resAllocInfo.Alignment));
|
||||
D3D12MA_ASSERT(resAllocInfo.SizeInBytes > 0);
|
||||
|
||||
@@ -6773,42 +6853,41 @@ void AllocatorPimpl::GetBudget(Budget* outLocalBudget, Budget* outNonLocalBudget
|
||||
outLocalBudget ? &outLocalBudget->BudgetBytes : NULL,
|
||||
outNonLocalBudget ? &outNonLocalBudget->UsageBytes : NULL,
|
||||
outNonLocalBudget ? &outNonLocalBudget->BudgetBytes : NULL);
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
if (SUCCEEDED(UpdateD3D12Budget()))
|
||||
{
|
||||
UpdateD3D12Budget();
|
||||
GetBudget(outLocalBudget, outNonLocalBudget); // Recursion
|
||||
GetBudget(outLocalBudget, outNonLocalBudget); // Recursion.
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
// Fallback path - manual calculation, not real budget.
|
||||
if (outLocalBudget)
|
||||
{
|
||||
if (outLocalBudget)
|
||||
{
|
||||
outLocalBudget->UsageBytes = outLocalBudget->Stats.BlockBytes;
|
||||
outLocalBudget->BudgetBytes = GetMemoryCapacity(DXGI_MEMORY_SEGMENT_GROUP_LOCAL_COPY) * 8 / 10; // 80% heuristics.
|
||||
}
|
||||
if (outNonLocalBudget)
|
||||
{
|
||||
outNonLocalBudget->UsageBytes = outNonLocalBudget->Stats.BlockBytes;
|
||||
outNonLocalBudget->BudgetBytes = GetMemoryCapacity(DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL_COPY) * 8 / 10; // 80% heuristics.
|
||||
}
|
||||
outLocalBudget->UsageBytes = outLocalBudget->Stats.BlockBytes;
|
||||
outLocalBudget->BudgetBytes = GetMemoryCapacity(DXGI_MEMORY_SEGMENT_GROUP_LOCAL_COPY) * 8 / 10; // 80% heuristics.
|
||||
}
|
||||
if (outNonLocalBudget)
|
||||
{
|
||||
outNonLocalBudget->UsageBytes = outNonLocalBudget->Stats.BlockBytes;
|
||||
outNonLocalBudget->BudgetBytes = GetMemoryCapacity(DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL_COPY) * 8 / 10; // 80% heuristics.
|
||||
}
|
||||
}
|
||||
|
||||
void AllocatorPimpl::GetBudgetForHeapType(Budget& outBudget, D3D12_HEAP_TYPE heapType)
|
||||
{
|
||||
switch (heapType)
|
||||
const bool isLocal = StandardHeapTypeToMemorySegmentGroup(heapType) ==
|
||||
DXGI_MEMORY_SEGMENT_GROUP_LOCAL_COPY;
|
||||
if (isLocal)
|
||||
{
|
||||
case D3D12_HEAP_TYPE_DEFAULT:
|
||||
case D3D12_HEAP_TYPE_GPU_UPLOAD_COPY:
|
||||
GetBudget(&outBudget, NULL);
|
||||
break;
|
||||
case D3D12_HEAP_TYPE_UPLOAD:
|
||||
case D3D12_HEAP_TYPE_READBACK:
|
||||
}
|
||||
else
|
||||
{
|
||||
GetBudget(NULL, &outBudget);
|
||||
break;
|
||||
default: D3D12MA_ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7248,12 +7327,15 @@ HRESULT AllocatorPimpl::AllocateCommittedResource(
|
||||
{
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
// Microsoft defined pCastableFormats parameter as pointer to non-const and only fixed it in later Agility SDK,
|
||||
// thus we need const_cast.
|
||||
hr = m_Device10->CreateCommittedResource3(
|
||||
&committedAllocParams.m_HeapProperties,
|
||||
committedAllocParams.m_HeapFlags & ~RESOURCE_CLASS_HEAP_FLAGS,
|
||||
createParams.GetResourceDesc1(), createParams.GetInitialLayout(),
|
||||
createParams.GetOptimizedClearValue(), committedAllocParams.m_ProtectedSession,
|
||||
createParams.GetNumCastableFormats(), createParams.GetCastableFormats(),
|
||||
createParams.GetNumCastableFormats(), const_cast<DXGI_FORMAT*>(createParams.GetCastableFormats()),
|
||||
D3D12MA_IID_PPV_ARGS(&res));
|
||||
} else
|
||||
#endif
|
||||
@@ -7396,8 +7478,8 @@ HRESULT AllocatorPimpl::CalcAllocationParams(const ALLOCATION_DESC& allocDesc, U
|
||||
outCommittedAllocationParams = CommittedAllocationParameters();
|
||||
outPreferCommitted = false;
|
||||
|
||||
D3D12MA_ASSERT((allocDesc.HeapType != D3D12_HEAP_TYPE_GPU_UPLOAD_COPY || IsGPUUploadHeapSupported()) &&
|
||||
"Trying to allocate from D3D12_HEAP_TYPE_GPU_UPLOAD while GPUUploadHeapSupported == FALSE or D3D12MA_OPTIONS16_SUPPORTED macro was not defined when compiling D3D12MA library.");
|
||||
if (allocDesc.HeapType == D3D12_HEAP_TYPE_GPU_UPLOAD_COPY && !IsGPUUploadHeapSupported())
|
||||
return E_NOTIMPL;
|
||||
|
||||
bool msaaAlwaysCommitted;
|
||||
if (allocDesc.CustomPool != NULL)
|
||||
@@ -7405,7 +7487,8 @@ HRESULT AllocatorPimpl::CalcAllocationParams(const ALLOCATION_DESC& allocDesc, U
|
||||
PoolPimpl* const pool = allocDesc.CustomPool->m_Pimpl;
|
||||
|
||||
msaaAlwaysCommitted = pool->GetBlockVector()->DeniesMsaaTextures();
|
||||
outBlockVector = pool->GetBlockVector();
|
||||
if(!pool->AlwaysCommitted())
|
||||
outBlockVector = pool->GetBlockVector();
|
||||
|
||||
const auto& desc = pool->GetDesc();
|
||||
outCommittedAllocationParams.m_ProtectedSession = desc.pProtectedSession;
|
||||
@@ -7444,12 +7527,6 @@ HRESULT AllocatorPimpl::CalcAllocationParams(const ALLOCATION_DESC& allocDesc, U
|
||||
outPreferCommitted = true;
|
||||
}
|
||||
}
|
||||
|
||||
const D3D12_HEAP_FLAGS extraHeapFlags = allocDesc.ExtraHeapFlags & ~RESOURCE_CLASS_HEAP_FLAGS;
|
||||
if (outBlockVector != NULL && extraHeapFlags != 0)
|
||||
{
|
||||
outBlockVector = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ((allocDesc.Flags & ALLOCATION_FLAG_COMMITTED) != 0 ||
|
||||
@@ -7479,12 +7556,7 @@ UINT AllocatorPimpl::CalcDefaultPoolIndex(const ALLOCATION_DESC& allocDesc, Reso
|
||||
D3D12_HEAP_FLAGS extraHeapFlags = allocDesc.ExtraHeapFlags & ~RESOURCE_CLASS_HEAP_FLAGS;
|
||||
|
||||
#if D3D12MA_CREATE_NOT_ZEROED_AVAILABLE
|
||||
// If allocator was created with ALLOCATOR_FLAG_DEFAULT_POOLS_NOT_ZEROED, also ignore
|
||||
// D3D12_HEAP_FLAG_CREATE_NOT_ZEROED.
|
||||
if(m_DefaultPoolsNotZeroed)
|
||||
{
|
||||
extraHeapFlags &= ~D3D12_HEAP_FLAG_CREATE_NOT_ZEROED;
|
||||
}
|
||||
extraHeapFlags &= ~D3D12_HEAP_FLAG_CREATE_NOT_ZEROED;
|
||||
#endif
|
||||
|
||||
if (extraHeapFlags != 0)
|
||||
@@ -7603,7 +7675,7 @@ D3D12_RESOURCE_ALLOCATION_INFO AllocatorPimpl::GetResourceAllocationInfoNative(c
|
||||
}
|
||||
|
||||
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
|
||||
D3D12_RESOURCE_ALLOCATION_INFO AllocatorPimpl::GetResourceAllocationInfoNative(const D3D12_RESOURCE_DESC1& resourceDesc) const
|
||||
D3D12_RESOURCE_ALLOCATION_INFO AllocatorPimpl::GetResourceAllocationInfo2Native(const D3D12_RESOURCE_DESC1& resourceDesc) const
|
||||
{
|
||||
D3D12MA_ASSERT(m_Device8 != NULL);
|
||||
D3D12_RESOURCE_ALLOCATION_INFO1 info1Unused;
|
||||
@@ -7619,8 +7691,71 @@ D3D12_RESOURCE_ALLOCATION_INFO AllocatorPimpl::GetResourceAllocationInfoNative(c
|
||||
}
|
||||
#endif // #ifdef __ID3D12Device8_INTERFACE_DEFINED__
|
||||
|
||||
#ifdef __ID3D12Device12_INTERFACE_DEFINED__
|
||||
D3D12_RESOURCE_ALLOCATION_INFO AllocatorPimpl::GetResourceAllocationInfo3Native(const D3D12_RESOURCE_DESC1& resourceDesc,
|
||||
UINT32 NumCastableFormats, const DXGI_FORMAT* pCastableFormats) const
|
||||
{
|
||||
D3D12MA_ASSERT(m_Device12 != NULL);
|
||||
D3D12_RESOURCE_ALLOCATION_INFO1 info1Unused;
|
||||
|
||||
// This is how new D3D12 headers define GetResourceAllocationInfo function -
|
||||
// different signature depending on these macros.
|
||||
#if defined(_MSC_VER) || !defined(_WIN32)
|
||||
return m_Device12->GetResourceAllocationInfo3(0, 1, &resourceDesc,
|
||||
&NumCastableFormats, &pCastableFormats, &info1Unused);
|
||||
#else
|
||||
D3D12_RESOURCE_ALLOCATION_INFO retVal;
|
||||
return *m_Device12->GetResourceAllocationInfo3(&retVal, 0, 1, &resourceDesc,
|
||||
&NumCastableFormats, &pCastableFormats, &info1Unused);
|
||||
#endif
|
||||
}
|
||||
#endif // #ifdef __ID3D12Device12_INTERFACE_DEFINED__
|
||||
|
||||
HRESULT AllocatorPimpl::GetResourceAllocationInfoMiddle(
|
||||
D3D12_RESOURCE_DESC& inOutResourceDesc,
|
||||
UINT32 NumCastableFormats, const DXGI_FORMAT* pCastableFormats,
|
||||
D3D12_RESOURCE_ALLOCATION_INFO& outAllocInfo) const
|
||||
{
|
||||
if (NumCastableFormats > 0)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
outAllocInfo = GetResourceAllocationInfoNative(inOutResourceDesc);
|
||||
return outAllocInfo.SizeInBytes != UINT64_MAX ? S_OK : E_INVALIDARG;
|
||||
}
|
||||
|
||||
#ifdef __ID3D12Device8_INTERFACE_DEFINED__
|
||||
|
||||
HRESULT AllocatorPimpl::GetResourceAllocationInfoMiddle(
|
||||
D3D12_RESOURCE_DESC1& inOutResourceDesc,
|
||||
UINT32 NumCastableFormats, const DXGI_FORMAT* pCastableFormats,
|
||||
D3D12_RESOURCE_ALLOCATION_INFO& outAllocInfo) const
|
||||
{
|
||||
if (NumCastableFormats > 0)
|
||||
{
|
||||
#ifdef __ID3D12Device12_INTERFACE_DEFINED__
|
||||
if (m_Device12 != NULL)
|
||||
{
|
||||
outAllocInfo = GetResourceAllocationInfo3Native(inOutResourceDesc, NumCastableFormats, pCastableFormats);
|
||||
return outAllocInfo.SizeInBytes != UINT64_MAX ? S_OK : E_INVALIDARG;
|
||||
}
|
||||
#else
|
||||
return E_NOTIMPL;
|
||||
#endif
|
||||
}
|
||||
|
||||
outAllocInfo = GetResourceAllocationInfo2Native(inOutResourceDesc);
|
||||
return outAllocInfo.SizeInBytes != UINT64_MAX ? S_OK : E_INVALIDARG;
|
||||
}
|
||||
|
||||
#endif // #ifdef __ID3D12Device8_INTERFACE_DEFINED__
|
||||
|
||||
template<typename D3D12_RESOURCE_DESC_T>
|
||||
D3D12_RESOURCE_ALLOCATION_INFO AllocatorPimpl::GetResourceAllocationInfo(D3D12_RESOURCE_DESC_T& inOutResourceDesc) const
|
||||
HRESULT AllocatorPimpl::GetResourceAllocationInfo(
|
||||
D3D12_RESOURCE_DESC_T& inOutResourceDesc,
|
||||
UINT32 NumCastableFormats, const DXGI_FORMAT* pCastableFormats,
|
||||
D3D12_RESOURCE_ALLOCATION_INFO& outAllocInfo) const
|
||||
{
|
||||
#ifdef __ID3D12Device1_INTERFACE_DEFINED__
|
||||
/* Optional optimization: Microsoft documentation says:
|
||||
@@ -7634,12 +7769,15 @@ D3D12_RESOURCE_ALLOCATION_INFO AllocatorPimpl::GetResourceAllocationInfo(D3D12_R
|
||||
if (inOutResourceDesc.Alignment == 0 &&
|
||||
inOutResourceDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
|
||||
{
|
||||
return {
|
||||
outAllocInfo = {
|
||||
AlignUp<UINT64>(inOutResourceDesc.Width, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT), // SizeInBytes
|
||||
D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT }; // Alignment
|
||||
return S_OK;
|
||||
}
|
||||
#endif // #ifdef __ID3D12Device1_INTERFACE_DEFINED__
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
#if D3D12MA_USE_SMALL_RESOURCE_PLACEMENT_ALIGNMENT
|
||||
if (inOutResourceDesc.Alignment == 0 &&
|
||||
inOutResourceDesc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D &&
|
||||
@@ -7657,17 +7795,19 @@ D3D12_RESOURCE_ALLOCATION_INFO AllocatorPimpl::GetResourceAllocationInfo(D3D12_R
|
||||
D3D12_SMALL_MSAA_RESOURCE_PLACEMENT_ALIGNMENT :
|
||||
D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT;
|
||||
inOutResourceDesc.Alignment = smallAlignmentToTry;
|
||||
const D3D12_RESOURCE_ALLOCATION_INFO smallAllocInfo = GetResourceAllocationInfoNative(inOutResourceDesc);
|
||||
hr = GetResourceAllocationInfoMiddle(
|
||||
inOutResourceDesc, NumCastableFormats, pCastableFormats, outAllocInfo);
|
||||
// Check if alignment requested has been granted.
|
||||
if (smallAllocInfo.Alignment == smallAlignmentToTry)
|
||||
if (SUCCEEDED(hr) && outAllocInfo.Alignment == smallAlignmentToTry)
|
||||
{
|
||||
return smallAllocInfo;
|
||||
return S_OK;
|
||||
}
|
||||
inOutResourceDesc.Alignment = 0; // Restore original
|
||||
}
|
||||
#endif // #if D3D12MA_USE_SMALL_RESOURCE_PLACEMENT_ALIGNMENT
|
||||
|
||||
return GetResourceAllocationInfoNative(inOutResourceDesc);
|
||||
return GetResourceAllocationInfoMiddle(
|
||||
inOutResourceDesc, NumCastableFormats, pCastableFormats, outAllocInfo);
|
||||
}
|
||||
|
||||
bool AllocatorPimpl::NewAllocationWithinBudget(D3D12_HEAP_TYPE heapType, UINT64 size)
|
||||
@@ -7988,6 +8128,7 @@ HRESULT BlockVector::Allocate(
|
||||
UINT64 size,
|
||||
UINT64 alignment,
|
||||
const ALLOCATION_DESC& allocDesc,
|
||||
bool committedAllowed,
|
||||
size_t allocationCount,
|
||||
Allocation** pAllocations)
|
||||
{
|
||||
@@ -8002,6 +8143,7 @@ HRESULT BlockVector::Allocate(
|
||||
size,
|
||||
alignment,
|
||||
allocDesc,
|
||||
committedAllowed,
|
||||
pAllocations + allocIndex);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
@@ -8090,40 +8232,43 @@ HRESULT BlockVector::CreateResource(
|
||||
UINT64 alignment,
|
||||
const ALLOCATION_DESC& allocDesc,
|
||||
const CREATE_RESOURCE_PARAMS& createParams,
|
||||
bool committedAllowed,
|
||||
Allocation** ppAllocation,
|
||||
REFIID riidResource,
|
||||
void** ppvResource)
|
||||
{
|
||||
HRESULT hr = Allocate(size, alignment, allocDesc, 1, ppAllocation);
|
||||
HRESULT hr = Allocate(size, alignment, allocDesc, committedAllowed, 1, ppAllocation);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
|
||||
ID3D12Resource* res = NULL;
|
||||
hr = m_hAllocator->CreatePlacedResourceWrap(
|
||||
(*ppAllocation)->m_Placed.block->GetHeap(),
|
||||
(*ppAllocation)->GetOffset(),
|
||||
createParams,
|
||||
D3D12MA_IID_PPV_ARGS(&res));
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
ID3D12Resource* res = NULL;
|
||||
hr = m_hAllocator->CreatePlacedResourceWrap(
|
||||
(*ppAllocation)->m_Placed.block->GetHeap(),
|
||||
(*ppAllocation)->GetOffset(),
|
||||
createParams,
|
||||
D3D12MA_IID_PPV_ARGS(&res));
|
||||
if (ppvResource != NULL)
|
||||
{
|
||||
hr = res->QueryInterface(riidResource, ppvResource);
|
||||
}
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (ppvResource != NULL)
|
||||
{
|
||||
hr = res->QueryInterface(riidResource, ppvResource);
|
||||
}
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
(*ppAllocation)->SetResourcePointer(res, createParams.GetBaseResourceDesc());
|
||||
}
|
||||
else
|
||||
{
|
||||
res->Release();
|
||||
SAFE_RELEASE(*ppAllocation);
|
||||
}
|
||||
(*ppAllocation)->SetResourcePointer(res, createParams.GetBaseResourceDesc());
|
||||
}
|
||||
else
|
||||
{
|
||||
res->Release();
|
||||
SAFE_RELEASE(*ppAllocation);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SAFE_RELEASE(*ppAllocation);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
@@ -8241,6 +8386,7 @@ HRESULT BlockVector::AllocatePage(
|
||||
UINT64 size,
|
||||
UINT64 alignment,
|
||||
const ALLOCATION_DESC& allocDesc,
|
||||
bool committedAllowed,
|
||||
Allocation** pAllocation)
|
||||
{
|
||||
// Early reject: requested allocation size is larger that maximum block size for this block vector.
|
||||
@@ -8257,13 +8403,19 @@ HRESULT BlockVector::AllocatePage(
|
||||
freeMemory = (budget.UsageBytes < budget.BudgetBytes) ? (budget.BudgetBytes - budget.UsageBytes) : 0;
|
||||
}
|
||||
|
||||
const bool canCreateNewBlock =
|
||||
const bool canExceedFreeMemory = !committedAllowed;
|
||||
|
||||
bool canCreateNewBlock =
|
||||
((allocDesc.Flags & ALLOCATION_FLAG_NEVER_ALLOCATE) == 0) &&
|
||||
(m_Blocks.size() < m_MaxBlockCount) &&
|
||||
// Even if we don't have to stay within budget with this allocation, when the
|
||||
// budget would be exceeded, we don't want to allocate new blocks, but always
|
||||
// create resources as committed.
|
||||
freeMemory >= size;
|
||||
(m_Blocks.size() < m_MaxBlockCount);
|
||||
|
||||
// Even if we don't have to stay within budget with this allocation, when the
|
||||
// budget would be exceeded, we don't want to allocate new blocks, but always
|
||||
// create resources as committed.
|
||||
if (freeMemory < size && !canExceedFreeMemory)
|
||||
{
|
||||
canCreateNewBlock = false;
|
||||
}
|
||||
|
||||
// 1. Search existing allocations
|
||||
{
|
||||
@@ -8313,26 +8465,29 @@ HRESULT BlockVector::AllocatePage(
|
||||
}
|
||||
}
|
||||
|
||||
size_t newBlockIndex = 0;
|
||||
HRESULT hr = newBlockSize <= freeMemory ?
|
||||
CreateBlock(newBlockSize, &newBlockIndex) : E_OUTOFMEMORY;
|
||||
size_t newBlockIndex = SIZE_MAX;
|
||||
HRESULT hr = E_OUTOFMEMORY;
|
||||
if (newBlockSize <= freeMemory || canExceedFreeMemory)
|
||||
{
|
||||
hr = CreateBlock(newBlockSize, &newBlockIndex);
|
||||
}
|
||||
// Allocation of this size failed? Try 1/2, 1/4, 1/8 of m_PreferredBlockSize.
|
||||
if (!m_ExplicitBlockSize)
|
||||
{
|
||||
while (FAILED(hr) && newBlockSizeShift < NEW_BLOCK_SIZE_SHIFT_MAX)
|
||||
{
|
||||
const UINT64 smallerNewBlockSize = newBlockSize / 2;
|
||||
if (smallerNewBlockSize >= size)
|
||||
{
|
||||
newBlockSize = smallerNewBlockSize;
|
||||
++newBlockSizeShift;
|
||||
hr = newBlockSize <= freeMemory ?
|
||||
CreateBlock(newBlockSize, &newBlockIndex) : E_OUTOFMEMORY;
|
||||
}
|
||||
else
|
||||
if (smallerNewBlockSize < size)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
newBlockSize = smallerNewBlockSize;
|
||||
++newBlockSizeShift;
|
||||
if (newBlockSize <= freeMemory || canExceedFreeMemory)
|
||||
{
|
||||
hr = CreateBlock(newBlockSize, &newBlockIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9509,6 +9664,8 @@ HRESULT Pool::BeginDefragmentation(const DEFRAGMENTATION_DESC* pDesc, Defragment
|
||||
// Check for support
|
||||
if (m_Pimpl->GetBlockVector()->GetAlgorithm() & POOL_FLAG_ALGORITHM_LINEAR)
|
||||
return E_NOINTERFACE;
|
||||
if(m_Pimpl->AlwaysCommitted())
|
||||
return E_NOINTERFACE;
|
||||
|
||||
AllocatorPimpl* allocator = m_Pimpl->GetAllocator();
|
||||
*ppContext = D3D12MA_NEW(allocator->GetAllocs(), DefragmentationContext)(allocator, *pDesc, m_Pimpl->GetBlockVector());
|
||||
@@ -9612,7 +9769,7 @@ HRESULT Allocator::CreateResource3(
|
||||
D3D12_BARRIER_LAYOUT InitialLayout,
|
||||
const D3D12_CLEAR_VALUE* pOptimizedClearValue,
|
||||
UINT32 NumCastableFormats,
|
||||
DXGI_FORMAT* pCastableFormats,
|
||||
const DXGI_FORMAT* pCastableFormats,
|
||||
Allocation** ppAllocation,
|
||||
REFIID riidResource,
|
||||
void** ppvResource)
|
||||
@@ -9702,7 +9859,7 @@ HRESULT Allocator::CreateAliasingResource2(
|
||||
D3D12_BARRIER_LAYOUT InitialLayout,
|
||||
const D3D12_CLEAR_VALUE* pOptimizedClearValue,
|
||||
UINT32 NumCastableFormats,
|
||||
DXGI_FORMAT* pCastableFormats,
|
||||
const DXGI_FORMAT* pCastableFormats,
|
||||
REFIID riidResource,
|
||||
void** ppvResource)
|
||||
{
|
||||
@@ -9732,6 +9889,12 @@ HRESULT Allocator::CreatePool(
|
||||
D3D12MA_ASSERT(0 && "Invalid arguments passed to Allocator::CreatePool.");
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
if ((pPoolDesc->Flags & POOL_FLAG_ALWAYS_COMMITTED) != 0 &&
|
||||
(pPoolDesc->BlockSize != 0 || pPoolDesc->MinBlockCount > 0))
|
||||
{
|
||||
D3D12MA_ASSERT(0 && "Invalid arguments passed to Allocator::CreatePool while POOL_FLAG_ALWAYS_COMMITTED is specified.");
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
if (!m_Pimpl->HeapFlagsFulfillResourceHeapTier(pPoolDesc->HeapFlags))
|
||||
{
|
||||
D3D12MA_ASSERT(0 && "Invalid pPoolDesc->HeapFlags passed to Allocator::CreatePool. Did you forget to handle ResourceHeapTier=1?");
|
||||
|
||||
1
3rdparty/fast_float/CONTRIBUTORS
vendored
1
3rdparty/fast_float/CONTRIBUTORS
vendored
@@ -8,3 +8,4 @@ Lénárd Szolnoki
|
||||
Jan Pharago
|
||||
Maya Warrier
|
||||
Taha Khokhar
|
||||
Anders Dalvander
|
||||
|
||||
541
3rdparty/fast_float/README.md
vendored
541
3rdparty/fast_float/README.md
vendored
@@ -1,160 +1,253 @@
|
||||
|
||||
## fast_float number parsing library: 4x faster than strtod
|
||||
[](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:fast_float)
|
||||
|
||||
[](https://github.com/fastfloat/fast_float/actions/workflows/ubuntu22.yml)
|
||||
|
||||
The fast_float library provides fast header-only implementations for the C++ from_chars
|
||||
functions for `float` and `double` types as well as integer types. These functions convert ASCII strings representing decimal values (e.g., `1.3e10`) into binary types. We provide exact rounding (including
|
||||
round to even). In our experience, these `fast_float` functions many times faster than comparable number-parsing functions from existing C++ standard libraries.
|
||||
The fast_float library provides fast header-only implementations for the C++
|
||||
from_chars functions for `float` and `double` types as well as integer types.
|
||||
These functions convert ASCII strings representing decimal values (e.g.,
|
||||
`1.3e10`) into binary types. We provide exact rounding (including round to
|
||||
even). In our experience, these `fast_float` functions many times faster than
|
||||
comparable number-parsing functions from existing C++ standard libraries.
|
||||
|
||||
Specifically, `fast_float` provides the following two functions to parse floating-point numbers with a C++17-like syntax (the library itself only requires C++11):
|
||||
Specifically, `fast_float` provides the following two functions to parse
|
||||
floating-point numbers with a C++17-like syntax (the library itself only
|
||||
requires C++11):
|
||||
|
||||
```C++
|
||||
from_chars_result from_chars(const char* first, const char* last, float& value, ...);
|
||||
from_chars_result from_chars(const char* first, const char* last, double& value, ...);
|
||||
from_chars_result from_chars(char const *first, char const *last, float &value, ...);
|
||||
from_chars_result from_chars(char const *first, char const *last, double &value, ...);
|
||||
```
|
||||
|
||||
You can also parse integer types:
|
||||
|
||||
|
||||
|
||||
```C++
|
||||
from_chars_result from_chars(char const *first, char const *last, int &value, ...);
|
||||
from_chars_result from_chars(char const *first, char const *last, unsigned &value, ...);
|
||||
```
|
||||
|
||||
The return type (`from_chars_result`) is defined as the struct:
|
||||
|
||||
```C++
|
||||
struct from_chars_result {
|
||||
const char* ptr;
|
||||
std::errc ec;
|
||||
char const *ptr;
|
||||
std::errc ec;
|
||||
};
|
||||
```
|
||||
|
||||
It parses the character sequence [first,last) for a number. It parses floating-point numbers expecting
|
||||
a locale-independent format equivalent to the C++17 from_chars function.
|
||||
The resulting floating-point value is the closest floating-point values (using either float or double),
|
||||
using the "round to even" convention for values that would otherwise fall right in-between two values.
|
||||
That is, we provide exact parsing according to the IEEE standard.
|
||||
It parses the character sequence `[first, last)` for a number. It parses
|
||||
floating-point numbers expecting a locale-independent format equivalent to the
|
||||
C++17 from_chars function. The resulting floating-point value is the closest
|
||||
floating-point values (using either `float` or `double`), using the "round to
|
||||
even" convention for values that would otherwise fall right in-between two
|
||||
values. That is, we provide exact parsing according to the IEEE standard.
|
||||
|
||||
Given a successful parse, the pointer (`ptr`) in the returned value is set to
|
||||
point right after the parsed number, and the `value` referenced is set to the
|
||||
parsed value. In case of error, the returned `ec` contains a representative
|
||||
error, otherwise the default (`std::errc()`) value is stored.
|
||||
|
||||
Given a successful parse, the pointer (`ptr`) in the returned value is set to point right after the
|
||||
parsed number, and the `value` referenced is set to the parsed value. In case of error, the returned
|
||||
`ec` contains a representative error, otherwise the default (`std::errc()`) value is stored.
|
||||
|
||||
The implementation does not throw and does not allocate memory (e.g., with `new` or `malloc`).
|
||||
The implementation does not throw and does not allocate memory (e.g., with `new`
|
||||
or `malloc`).
|
||||
|
||||
It will parse infinity and nan values.
|
||||
|
||||
Example:
|
||||
|
||||
``` C++
|
||||
```C++
|
||||
#include "fast_float/fast_float.h"
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
int main() {
|
||||
const std::string input = "3.1416 xyz ";
|
||||
double result;
|
||||
auto answer = fast_float::from_chars(input.data(), input.data()+input.size(), result);
|
||||
if(answer.ec != std::errc()) { std::cerr << "parsing failure\n"; return EXIT_FAILURE; }
|
||||
std::string input = "3.1416 xyz ";
|
||||
double result;
|
||||
auto answer = fast_float::from_chars(input.data(), input.data() + input.size(), result);
|
||||
if (answer.ec != std::errc()) { std::cerr << "parsing failure\n"; return EXIT_FAILURE; }
|
||||
std::cout << "parsed the number " << result << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
```
|
||||
|
||||
Though the C++17 standard has you do a comparison with `std::errc()` to check whether the conversion worked, you can avoid it by casting the result to a `bool` like so:
|
||||
|
||||
```cpp
|
||||
#include "fast_float/fast_float.h"
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
int main() {
|
||||
std::string input = "3.1416 xyz ";
|
||||
double result;
|
||||
if(auto answer = fast_float::from_chars(input.data(), input.data() + input.size(), result)) {
|
||||
std::cout << "parsed the number " << result << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
std::cerr << "failed to parse " << result << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
```
|
||||
|
||||
You can parse delimited numbers:
|
||||
|
||||
```C++
|
||||
const std::string input = "234532.3426362,7869234.9823,324562.645";
|
||||
std::string input = "234532.3426362,7869234.9823,324562.645";
|
||||
double result;
|
||||
auto answer = fast_float::from_chars(input.data(), input.data()+input.size(), result);
|
||||
if(answer.ec != std::errc()) {
|
||||
auto answer = fast_float::from_chars(input.data(), input.data() + input.size(), result);
|
||||
if (answer.ec != std::errc()) {
|
||||
// check error
|
||||
}
|
||||
// we have result == 234532.3426362.
|
||||
if(answer.ptr[0] != ',') {
|
||||
if (answer.ptr[0] != ',') {
|
||||
// unexpected delimiter
|
||||
}
|
||||
answer = fast_float::from_chars(answer.ptr + 1, input.data()+input.size(), result);
|
||||
if(answer.ec != std::errc()) {
|
||||
answer = fast_float::from_chars(answer.ptr + 1, input.data() + input.size(), result);
|
||||
if (answer.ec != std::errc()) {
|
||||
// check error
|
||||
}
|
||||
// we have result == 7869234.9823.
|
||||
if(answer.ptr[0] != ',') {
|
||||
if (answer.ptr[0] != ',') {
|
||||
// unexpected delimiter
|
||||
}
|
||||
answer = fast_float::from_chars(answer.ptr + 1, input.data()+input.size(), result);
|
||||
if(answer.ec != std::errc()) {
|
||||
answer = fast_float::from_chars(answer.ptr + 1, input.data() + input.size(), result);
|
||||
if (answer.ec != std::errc()) {
|
||||
// check error
|
||||
}
|
||||
// we have result == 324562.645.
|
||||
```
|
||||
|
||||
Like the C++17 standard, the `fast_float::from_chars` functions take an optional
|
||||
last argument of the type `fast_float::chars_format`. It is a bitset value: we
|
||||
check whether `fmt & fast_float::chars_format::fixed` and `fmt &
|
||||
fast_float::chars_format::scientific` are set to determine whether we allow the
|
||||
fixed point and scientific notation respectively. The default is
|
||||
`fast_float::chars_format::general` which allows both `fixed` and `scientific`.
|
||||
|
||||
The library seeks to follow the C++17 (see
|
||||
[28.2.3.(6.1)](https://eel.is/c++draft/charconv.from.chars#6.1)) specification.
|
||||
|
||||
Like the C++17 standard, the `fast_float::from_chars` functions take an optional last argument of
|
||||
the type `fast_float::chars_format`. It is a bitset value: we check whether
|
||||
`fmt & fast_float::chars_format::fixed` and `fmt & fast_float::chars_format::scientific` are set
|
||||
to determine whether we allow the fixed point and scientific notation respectively.
|
||||
The default is `fast_float::chars_format::general` which allows both `fixed` and `scientific`.
|
||||
|
||||
The library seeks to follow the C++17 (see [20.19.3](http://eel.is/c++draft/charconv.from.chars).(7.1)) specification.
|
||||
* The `from_chars` function does not skip leading white-space characters.
|
||||
* [A leading `+` sign](https://en.cppreference.com/w/cpp/utility/from_chars) is forbidden.
|
||||
* It is generally impossible to represent a decimal value exactly as binary floating-point number (`float` and `double` types). We seek the nearest value. We round to an even mantissa when we are in-between two binary floating-point numbers.
|
||||
* The `from_chars` function does not skip leading white-space characters (unless
|
||||
`fast_float::chars_format::skip_white_space` is set).
|
||||
* [A leading `+` sign](https://en.cppreference.com/w/cpp/utility/from_chars) is
|
||||
forbidden (unless `fast_float::chars_format::allow_leading_plus` is set).
|
||||
* It is generally impossible to represent a decimal value exactly as binary
|
||||
floating-point number (`float` and `double` types). We seek the nearest value.
|
||||
We round to an even mantissa when we are in-between two binary floating-point
|
||||
numbers.
|
||||
|
||||
Furthermore, we have the following restrictions:
|
||||
* We only support `float` and `double` types at this time.
|
||||
|
||||
* We support `float` and `double`, but not `long double`. We also support
|
||||
fixed-width floating-point types such as `std::float64_t`, `std::float32_t`,
|
||||
`std::float16_t`, and `std::bfloat16_t`.
|
||||
* We only support the decimal format: we do not support hexadecimal strings.
|
||||
* For values that are either very large or very small (e.g., `1e9999`), we represent it using the infinity or negative infinity value and the returned `ec` is set to `std::errc::result_out_of_range`.
|
||||
* For values that are either very large or very small (e.g., `1e9999`), we
|
||||
represent it using the infinity or negative infinity value and the returned
|
||||
`ec` is set to `std::errc::result_out_of_range`.
|
||||
|
||||
We support Visual Studio, macOS, Linux, freeBSD. We support big and little endian. We support 32-bit and 64-bit systems.
|
||||
|
||||
We assume that the rounding mode is set to nearest (`std::fegetround() == FE_TONEAREST`).
|
||||
We support Visual Studio, macOS, Linux, freeBSD. We support big and little
|
||||
endian. We support 32-bit and 64-bit systems.
|
||||
|
||||
We assume that the rounding mode is set to nearest (`std::fegetround() ==
|
||||
FE_TONEAREST`).
|
||||
|
||||
## Integer types
|
||||
|
||||
You can also parse integer types using different bases (e.g., 2, 10, 16). The following code will
|
||||
print the number 22250738585072012 three times:
|
||||
|
||||
You can also parse integer types using different bases (e.g., 2, 10, 16). The
|
||||
following code will print the number 22250738585072012 three times:
|
||||
|
||||
```C++
|
||||
#include "fast_float/fast_float.h"
|
||||
#include <iostream>
|
||||
|
||||
int main() {
|
||||
uint64_t i;
|
||||
const char str[] = "22250738585072012";
|
||||
auto answer = fast_float::from_chars(str, str + strlen(str), i);
|
||||
std::string str = "22250738585072012";
|
||||
auto answer = fast_float::from_chars(str.data(), str.data() + str.size(), i);
|
||||
if (answer.ec != std::errc()) {
|
||||
std::cerr << "parsing failure\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
std::cout << "parsed the number "<< i << std::endl;
|
||||
std::cout << "parsed the number " << i << std::endl;
|
||||
|
||||
const char binstr[] = "1001111000011001110110111001001010110100111000110001100";
|
||||
std::string binstr = "1001111000011001110110111001001010110100111000110001100";
|
||||
|
||||
answer = fast_float::from_chars(binstr, binstr + strlen(binstr), i, 2);
|
||||
answer = fast_float::from_chars(binstr.data(), binstr.data() + binstr.size(), i, 2);
|
||||
if (answer.ec != std::errc()) {
|
||||
std::cerr << "parsing failure\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
std::cout << "parsed the number "<< i << std::endl;
|
||||
std::cout << "parsed the number " << i << std::endl;
|
||||
|
||||
std::string hexstr = "4f0cedc95a718c";
|
||||
|
||||
const char hexstr[] = "4f0cedc95a718c";
|
||||
|
||||
answer = fast_float::from_chars(hexstr, hexstr + strlen(hexstr), i, 16);
|
||||
answer = fast_float::from_chars(hexstr.data(), hexstr.data() + hexstr.size(), i, 16);
|
||||
if (answer.ec != std::errc()) {
|
||||
std::cerr << "parsing failure\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
std::cout << "parsed the number "<< i << std::endl;
|
||||
std::cout << "parsed the number " << i << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
```
|
||||
|
||||
## Behavior of result_out_of_range
|
||||
|
||||
When parsing floating-point values, the numbers can sometimes be too small
|
||||
(e.g., `1e-1000`) or too large (e.g., `1e1000`). The C language established the
|
||||
precedent that these small values are out of range. In such cases, it is
|
||||
customary to parse small values to zero and large values to infinity. That is
|
||||
the behaviour of the C language (e.g., `stdtod`). That is the behaviour followed
|
||||
by the fast_float library.
|
||||
|
||||
Specifically, we follow Jonathan Wakely's interpretation of the standard:
|
||||
|
||||
> In any case, the resulting value is one of at most two floating-point values
|
||||
> closest to the value of the string matching the pattern.
|
||||
|
||||
It is also the approach taken by the [Microsoft C++
|
||||
library](https://github.com/microsoft/STL/blob/62205ab155d093e71dd9588a78f02c5396c3c14b/tests/std/tests/P0067R5_charconv/test.cpp#L943-L946).
|
||||
|
||||
Hence, we have the following examples:
|
||||
|
||||
```cpp
|
||||
double result = -1;
|
||||
std::string str = "3e-1000";
|
||||
auto r = fast_float::from_chars(str.data(), str.data() + str.size(), result);
|
||||
// r.ec == std::errc::result_out_of_range
|
||||
// r.ptr == str.data() + 7
|
||||
// result == 0
|
||||
```
|
||||
|
||||
```cpp
|
||||
double result = -1;
|
||||
std::string str = "3e1000";
|
||||
auto r = fast_float::from_chars(str.data(), str.data() + str.size(), result);
|
||||
// r.ec == std::errc::result_out_of_range
|
||||
// r.ptr == str.data() + 6
|
||||
// result == std::numeric_limits<double>::infinity()
|
||||
```
|
||||
|
||||
Users who wish for the value to be left unmodified given
|
||||
`std::errc::result_out_of_range` may do so by adding two lines of code:
|
||||
|
||||
```cpp
|
||||
double old_result = result; // make copy
|
||||
auto r = fast_float::from_chars(start, end, result);
|
||||
if (r.ec == std::errc::result_out_of_range) { result = old_result; }
|
||||
```
|
||||
|
||||
## C++20: compile-time evaluation (constexpr)
|
||||
|
||||
In C++20, you may use `fast_float::from_chars` to parse strings
|
||||
at compile-time, as in the following example:
|
||||
In C++20, you may use `fast_float::from_chars` to parse strings at compile-time,
|
||||
as in the following example:
|
||||
|
||||
```C++
|
||||
// consteval forces compile-time evaluation of the function in C++20.
|
||||
consteval double parse(std::string_view input) {
|
||||
double result;
|
||||
auto answer = fast_float::from_chars(input.data(), input.data()+input.size(), result);
|
||||
if(answer.ec != std::errc()) { return -1.0; }
|
||||
auto answer = fast_float::from_chars(input.data(), input.data() + input.size(), result);
|
||||
if (answer.ec != std::errc()) { return -1.0; }
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -167,108 +260,107 @@ constexpr double constexptest() {
|
||||
|
||||
## C++23: Fixed width floating-point types
|
||||
|
||||
The library also supports fixed-width floating-point types such as `std::float32_t` and `std::float64_t`. E.g., you can write:
|
||||
The library also supports fixed-width floating-point types such as
|
||||
`std::float64_t`, `std::float32_t`, `std::float16_t`, and `std::bfloat16_t`.
|
||||
E.g., you can write:
|
||||
|
||||
```C++
|
||||
std::float32_t result;
|
||||
auto answer = fast_float::from_chars(f.data(), f.data() + f.size(), result);
|
||||
``````
|
||||
|
||||
```
|
||||
|
||||
## Non-ASCII Inputs
|
||||
|
||||
We also support UTF-16 and UTF-32 inputs, as well as ASCII/UTF-8, as in the following example:
|
||||
We also support UTF-16 and UTF-32 inputs, as well as ASCII/UTF-8, as in the
|
||||
following example:
|
||||
|
||||
``` C++
|
||||
```C++
|
||||
#include "fast_float/fast_float.h"
|
||||
#include <iostream>
|
||||
|
||||
int main() {
|
||||
const std::u16string input = u"3.1416 xyz ";
|
||||
double result;
|
||||
auto answer = fast_float::from_chars(input.data(), input.data()+input.size(), result);
|
||||
if(answer.ec != std::errc()) { std::cerr << "parsing failure\n"; return EXIT_FAILURE; }
|
||||
std::cout << "parsed the number " << result << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
std::u16string input = u"3.1416 xyz ";
|
||||
double result;
|
||||
auto answer = fast_float::from_chars(input.data(), input.data() + input.size(), result);
|
||||
if (answer.ec != std::errc()) { std::cerr << "parsing failure\n"; return EXIT_FAILURE; }
|
||||
std::cout << "parsed the number " << result << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
```
|
||||
|
||||
## Advanced options: using commas as decimal separator, JSON and Fortran
|
||||
|
||||
## Advanced options: using commas as decimal separator, JSON and Fortran
|
||||
|
||||
The C++ standard stipulate that `from_chars` has to be locale-independent. In
|
||||
particular, the decimal separator has to be the period (`.`). However,
|
||||
some users still want to use the `fast_float` library with in a locale-dependent
|
||||
manner. Using a separate function called `from_chars_advanced`, we allow the users
|
||||
to pass a `parse_options` instance which contains a custom decimal separator (e.g.,
|
||||
the comma). You may use it as follows.
|
||||
particular, the decimal separator has to be the period (`.`). However, some
|
||||
users still want to use the `fast_float` library with in a locale-dependent
|
||||
manner. Using a separate function called `from_chars_advanced`, we allow the
|
||||
users to pass a `parse_options` instance which contains a custom decimal
|
||||
separator (e.g., the comma). You may use it as follows.
|
||||
|
||||
```C++
|
||||
#include "fast_float/fast_float.h"
|
||||
#include <iostream>
|
||||
|
||||
int main() {
|
||||
const std::string input = "3,1416 xyz ";
|
||||
double result;
|
||||
fast_float::parse_options options{fast_float::chars_format::general, ','};
|
||||
auto answer = fast_float::from_chars_advanced(input.data(), input.data()+input.size(), result, options);
|
||||
if((answer.ec != std::errc()) || ((result != 3.1416))) { std::cerr << "parsing failure\n"; return EXIT_FAILURE; }
|
||||
std::cout << "parsed the number " << result << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
std::string input = "3,1416 xyz ";
|
||||
double result;
|
||||
fast_float::parse_options options{fast_float::chars_format::general, ','};
|
||||
auto answer = fast_float::from_chars_advanced(input.data(), input.data() + input.size(), result, options);
|
||||
if ((answer.ec != std::errc()) || ((result != 3.1416))) { std::cerr << "parsing failure\n"; return EXIT_FAILURE; }
|
||||
std::cout << "parsed the number " << result << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
```
|
||||
|
||||
You can also parse Fortran-like inputs:
|
||||
### You can also parse Fortran-like inputs
|
||||
|
||||
```C++
|
||||
#include "fast_float/fast_float.h"
|
||||
#include <iostream>
|
||||
|
||||
int main() {
|
||||
const std::string input = "1d+4";
|
||||
double result;
|
||||
fast_float::parse_options options{ fast_float::chars_format::fortran };
|
||||
auto answer = fast_float::from_chars_advanced(input.data(), input.data()+input.size(), result, options);
|
||||
if((answer.ec != std::errc()) || ((result != 10000))) { std::cerr << "parsing failure\n"; return EXIT_FAILURE; }
|
||||
std::cout << "parsed the number " << result << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
std::string input = "1d+4";
|
||||
double result;
|
||||
fast_float::parse_options options{fast_float::chars_format::fortran};
|
||||
auto answer = fast_float::from_chars_advanced(input.data(), input.data() + input.size(), result, options);
|
||||
if ((answer.ec != std::errc()) || ((result != 10000))) { std::cerr << "parsing failure\n"; return EXIT_FAILURE; }
|
||||
std::cout << "parsed the number " << result << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
```
|
||||
|
||||
You may also enforce the JSON format ([RFC 8259](https://datatracker.ietf.org/doc/html/rfc8259#section-6)):
|
||||
|
||||
### You may also enforce the JSON format ([RFC 8259](https://datatracker.ietf.org/doc/html/rfc8259#section-6))
|
||||
|
||||
```C++
|
||||
#include "fast_float/fast_float.h"
|
||||
#include <iostream>
|
||||
|
||||
int main() {
|
||||
const std::string input = "+.1"; // not valid
|
||||
double result;
|
||||
fast_float::parse_options options{ fast_float::chars_format::json };
|
||||
auto answer = fast_float::from_chars_advanced(input.data(), input.data()+input.size(), result, options);
|
||||
if(answer.ec == std::errc()) { std::cerr << "should have failed\n"; return EXIT_FAILURE; }
|
||||
return EXIT_SUCCESS;
|
||||
std::string input = "+.1"; // not valid
|
||||
double result;
|
||||
fast_float::parse_options options{fast_float::chars_format::json};
|
||||
auto answer = fast_float::from_chars_advanced(input.data(), input.data() + input.size(), result, options);
|
||||
if (answer.ec == std::errc()) { std::cerr << "should have failed\n"; return EXIT_FAILURE; }
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
```
|
||||
|
||||
By default the JSON format does not allow `inf`:
|
||||
|
||||
```C++
|
||||
|
||||
#include "fast_float/fast_float.h"
|
||||
#include <iostream>
|
||||
|
||||
int main() {
|
||||
const std::string input = "inf"; // not valid in JSON
|
||||
double result;
|
||||
fast_float::parse_options options{ fast_float::chars_format::json };
|
||||
auto answer = fast_float::from_chars_advanced(input.data(), input.data()+input.size(), result, options);
|
||||
if(answer.ec == std::errc()) { std::cerr << "should have failed\n"; return EXIT_FAILURE; }
|
||||
std::string input = "inf"; // not valid in JSON
|
||||
double result;
|
||||
fast_float::parse_options options{fast_float::chars_format::json};
|
||||
auto answer = fast_float::from_chars_advanced(input.data(), input.data() + input.size(), result, options);
|
||||
if (answer.ec == std::errc()) { std::cerr << "should have failed\n"; return EXIT_FAILURE; }
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
You can allow it with a non-standard `json_or_infnan` variant:
|
||||
|
||||
```C++
|
||||
@@ -276,55 +368,118 @@ You can allow it with a non-standard `json_or_infnan` variant:
|
||||
#include <iostream>
|
||||
|
||||
int main() {
|
||||
const std::string input = "inf"; // not valid in JSON but we allow it with json_or_infnan
|
||||
double result;
|
||||
fast_float::parse_options options{ fast_float::chars_format::json_or_infnan };
|
||||
auto answer = fast_float::from_chars_advanced(input.data(), input.data()+input.size(), result, options);
|
||||
if(answer.ec != std::errc() || (!std::isinf(result))) { std::cerr << "should have parsed infinity\n"; return EXIT_FAILURE; }
|
||||
return EXIT_SUCCESS;
|
||||
std::string input = "inf"; // not valid in JSON but we allow it with json_or_infnan
|
||||
double result;
|
||||
fast_float::parse_options options{fast_float::chars_format::json_or_infnan};
|
||||
auto answer = fast_float::from_chars_advanced(input.data(), input.data() + input.size(), result, options);
|
||||
if (answer.ec != std::errc() || (!std::isinf(result))) { std::cerr << "should have parsed infinity\n"; return EXIT_FAILURE; }
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
``````
|
||||
```
|
||||
|
||||
## Relation With Other Work
|
||||
## Multiplication of an integer by a power of 10
|
||||
An integer `W` can be multiplied by a power of ten `10^Q` and
|
||||
converted to `double` with correctly rounded value
|
||||
(in "round to nearest, tie to even" fashion) using
|
||||
`fast_float::integer_times_pow10()`, e.g.:
|
||||
```C++
|
||||
const uint64_t W = 12345678901234567;
|
||||
const int Q = 23;
|
||||
const double result = fast_float::integer_times_pow10(W, Q);
|
||||
std::cout.precision(17);
|
||||
std::cout << W << " * 10^" << Q << " = " << result << " ("
|
||||
<< (result == 12345678901234567e23 ? "==" : "!=") << "expected)\n";
|
||||
```
|
||||
outputs
|
||||
```
|
||||
12345678901234567 * 10^23 = 1.2345678901234567e+39 (==expected)
|
||||
```
|
||||
`fast_float::integer_times_pow10()` gives the same result as
|
||||
using `fast_float::from_chars()` when parsing the string `"WeQ"`
|
||||
(in this example `"12345678901234567e23"`),
|
||||
except `fast_float::integer_times_pow10()` does not report out-of-range errors, and
|
||||
underflows to zero or overflows to infinity when the resulting value is
|
||||
out of range.
|
||||
|
||||
Overloads of `fast_float::integer_times_pow10()` are provided for
|
||||
signed and unsigned integer types: `int64_t`, `uint64_t`, etc.
|
||||
|
||||
|
||||
## Users and Related Work
|
||||
|
||||
The fast_float library is part of:
|
||||
|
||||
- GCC (as of version 12): the `from_chars` function in GCC relies on fast_float.
|
||||
- [WebKit](https://github.com/WebKit/WebKit), the engine behind Safari (Apple's web browser)
|
||||
* GCC (as of version 12): the `from_chars` function in GCC relies on fast_float,
|
||||
* [Chromium](https://github.com/Chromium/Chromium), the engine behind Google
|
||||
Chrome, Microsoft Edge, and Opera,
|
||||
* Boost JSON, MySQL, etc.
|
||||
* Blender
|
||||
* [WebKit](https://github.com/WebKit/WebKit), the engine behind Safari (Apple's
|
||||
web browser),
|
||||
* [DuckDB](https://duckdb.org),
|
||||
* [Redis](https://github.com/redis/redis) and [Valkey](https://github.com/valkey-io/valkey),
|
||||
* [Apache Arrow](https://github.com/apache/arrow/pull/8494) where it multiplied
|
||||
the number parsing speed by two or three times,
|
||||
* [Google Jsonnet](https://github.com/google/jsonnet),
|
||||
* [ClickHouse](https://github.com/ClickHouse/ClickHouse).
|
||||
|
||||
The fastfloat algorithm is part of the [LLVM standard
|
||||
libraries](https://github.com/llvm/llvm-project/commit/87c016078ad72c46505461e4ff8bfa04819fe7ba).
|
||||
There is a [derived implementation part of
|
||||
AdaCore](https://github.com/AdaCore/VSS). The [SerenityOS operating
|
||||
system](https://github.com/SerenityOS/serenity/commit/53b7f5e6a11e663c83df8030c3171c5945cb75ec)
|
||||
has a derived implementation that is inherited by the [Ladybird
|
||||
Browser](https://github.com/LadybirdBrowser/ladybird).
|
||||
|
||||
The fast_float library provides a performance similar to that of the
|
||||
[fast_double_parser](https://github.com/lemire/fast_double_parser) library but
|
||||
using an updated algorithm reworked from the ground up, and while offering an
|
||||
API more in line with the expectations of C++ programmers. The
|
||||
fast_double_parser library is part of the [Microsoft LightGBM machine-learning
|
||||
framework](https://github.com/microsoft/LightGBM).
|
||||
|
||||
|
||||
The fastfloat algorithm is part of the [LLVM standard libraries](https://github.com/llvm/llvm-project/commit/87c016078ad72c46505461e4ff8bfa04819fe7ba).
|
||||
|
||||
There is a [derived implementation part of AdaCore](https://github.com/AdaCore/VSS).
|
||||
Packages
|
||||
------
|
||||
|
||||
[](https://repology.org/project/fastfloat/versions)
|
||||
|
||||
The fast_float library provides a performance similar to that of the [fast_double_parser](https://github.com/lemire/fast_double_parser) library but using an updated algorithm reworked from the ground up, and while offering an API more in line with the expectations of C++ programmers. The fast_double_parser library is part of the [Microsoft LightGBM machine-learning framework](https://github.com/microsoft/LightGBM).
|
||||
|
||||
## References
|
||||
|
||||
- Daniel Lemire, [Number Parsing at a Gigabyte per Second](https://arxiv.org/abs/2101.11408), Software: Practice and Experience 51 (8), 2021.
|
||||
- Noble Mushtak, Daniel Lemire, [Fast Number Parsing Without Fallback](https://arxiv.org/abs/2212.06644), Software: Practice and Experience 53 (7), 2023.
|
||||
* Daniel Lemire, [Number Parsing at a Gigabyte per
|
||||
Second](https://arxiv.org/abs/2101.11408), Software: Practice and Experience
|
||||
51 (8), 2021.
|
||||
* Noble Mushtak, Daniel Lemire, [Fast Number Parsing Without
|
||||
Fallback](https://arxiv.org/abs/2212.06644), Software: Practice and Experience
|
||||
53 (7), 2023.
|
||||
|
||||
## Other programming languages
|
||||
|
||||
- [There is an R binding](https://github.com/eddelbuettel/rcppfastfloat) called `rcppfastfloat`.
|
||||
- [There is a Rust port of the fast_float library](https://github.com/aldanor/fast-float-rust/) called `fast-float-rust`.
|
||||
- [There is a Java port of the fast_float library](https://github.com/wrandelshofer/FastDoubleParser) called `FastDoubleParser`. It used for important systems such as [Jackson](https://github.com/FasterXML/jackson-core).
|
||||
- [There is a C# port of the fast_float library](https://github.com/CarlVerret/csFastFloat) called `csFastFloat`.
|
||||
|
||||
|
||||
## Users
|
||||
|
||||
The fast_float library is used by [Apache Arrow](https://github.com/apache/arrow/pull/8494) where it multiplied the number parsing speed by two or three times. It is also used by [ClickHouse](https://github.com/ClickHouse/ClickHouse) and by [Google Jsonnet](https://github.com/google/jsonnet). It is part of GCC (as of GCC 12). It is part of WebKit (Safari).
|
||||
|
||||
* [There is an R binding](https://github.com/eddelbuettel/rcppfastfloat) called
|
||||
`rcppfastfloat`.
|
||||
* [There is a Rust port of the fast_float
|
||||
library](https://github.com/aldanor/fast-float-rust/) called
|
||||
`fast-float-rust`.
|
||||
* [There is a Java port of the fast_float
|
||||
library](https://github.com/wrandelshofer/FastDoubleParser) called
|
||||
`FastDoubleParser`. It used for important systems such as
|
||||
[Jackson](https://github.com/FasterXML/jackson-core).
|
||||
* [There is a C# port of the fast_float
|
||||
library](https://github.com/CarlVerret/csFastFloat) called `csFastFloat`.
|
||||
|
||||
## How fast is it?
|
||||
|
||||
It can parse random floating-point numbers at a speed of 1 GB/s on some systems. We find that it is often twice as fast as the best available competitor, and many times faster than many standard-library implementations.
|
||||
It can parse random floating-point numbers at a speed of 1 GB/s on some systems.
|
||||
We find that it is often twice as fast as the best available competitor, and
|
||||
many times faster than many standard-library implementations.
|
||||
|
||||
<img src="http://lemire.me/blog/wp-content/uploads/2020/11/fastfloat_speed.png" width="400">
|
||||
<img src="https://lemire.me/blog/wp-content/uploads/2020/11/fastfloat_speed.png"
|
||||
width="400" alt="fast_float is many times faster than many standard-library
|
||||
implementations">
|
||||
|
||||
```
|
||||
```bash
|
||||
$ ./build/benchmarks/benchmark
|
||||
# parsing random integers in the range [0,1)
|
||||
volume = 2.09808 MB
|
||||
@@ -335,75 +490,123 @@ abseil : 430.45 MB/s (+/- 2.2 %) 20.52 Mfl
|
||||
fastfloat : 1042.38 MB/s (+/- 9.9 %) 49.68 Mfloat/s
|
||||
```
|
||||
|
||||
See https://github.com/lemire/simple_fastfloat_benchmark for our benchmarking code.
|
||||
|
||||
See the [Benchmarking](#benchmarking) section for instructions on how to run our benchmarks.
|
||||
|
||||
## Video
|
||||
|
||||
[](http://www.youtube.com/watch?v=AVXgvlMeIm4)<br />
|
||||
[](https://www.youtube.com/watch?v=AVXgvlMeIm4)
|
||||
|
||||
## Using as a CMake dependency
|
||||
|
||||
This library is header-only by design. The CMake file provides the `fast_float` target
|
||||
which is merely a pointer to the `include` directory.
|
||||
This library is header-only by design. The CMake file provides the `fast_float`
|
||||
target which is merely a pointer to the `include` directory.
|
||||
|
||||
If you drop the `fast_float` repository in your CMake project, you should be able to use
|
||||
it in this manner:
|
||||
If you drop the `fast_float` repository in your CMake project, you should be
|
||||
able to use it in this manner:
|
||||
|
||||
```cmake
|
||||
add_subdirectory(fast_float)
|
||||
target_link_libraries(myprogram PUBLIC fast_float)
|
||||
```
|
||||
|
||||
Or you may want to retrieve the dependency automatically if you have a sufficiently recent version of CMake (3.11 or better at least):
|
||||
Or you may want to retrieve the dependency automatically if you have a
|
||||
sufficiently recent version of CMake (3.11 or better at least):
|
||||
|
||||
```cmake
|
||||
FetchContent_Declare(
|
||||
fast_float
|
||||
GIT_REPOSITORY https://github.com/lemire/fast_float.git
|
||||
GIT_TAG tags/v1.1.2
|
||||
GIT_REPOSITORY https://github.com/fastfloat/fast_float.git
|
||||
GIT_TAG tags/v8.1.0
|
||||
GIT_SHALLOW TRUE)
|
||||
|
||||
FetchContent_MakeAvailable(fast_float)
|
||||
target_link_libraries(myprogram PUBLIC fast_float)
|
||||
|
||||
```
|
||||
|
||||
You should change the `GIT_TAG` line so that you recover the version you wish to use.
|
||||
You should change the `GIT_TAG` line so that you recover the version you wish to
|
||||
use.
|
||||
|
||||
You may also use [CPM](https://github.com/cpm-cmake/CPM.cmake), like so:
|
||||
|
||||
```cmake
|
||||
CPMAddPackage(
|
||||
NAME fast_float
|
||||
GITHUB_REPOSITORY "fastfloat/fast_float"
|
||||
GIT_TAG v8.1.0)
|
||||
```
|
||||
|
||||
## Using as single header
|
||||
|
||||
The script `script/amalgamate.py` may be used to generate a single header
|
||||
version of the library if so desired.
|
||||
Just run the script from the root directory of this repository.
|
||||
You can customize the license type and output file if desired as described in
|
||||
the command line help.
|
||||
version of the library if so desired. Just run the script from the root
|
||||
directory of this repository. You can customize the license type and output file
|
||||
if desired as described in the command line help.
|
||||
|
||||
You may directly download automatically generated single-header files:
|
||||
|
||||
https://github.com/fastfloat/fast_float/releases/download/v6.1.1/fast_float.h
|
||||
<https://github.com/fastfloat/fast_float/releases/download/v8.1.0/fast_float.h>
|
||||
|
||||
## RFC 7159
|
||||
## Benchmarking
|
||||
|
||||
If you need support for RFC 7159 (JSON standard), you may want to consider using the [fast_double_parser](https://github.com/lemire/fast_double_parser/) library instead.
|
||||
The project has its own benchmarks with realistic data inputs. Under Linux or macOS,
|
||||
you can use it as follows if your system supports C++17:
|
||||
|
||||
```
|
||||
cmake -B build -D FASTFLOAT_BENCHMARKS=ON
|
||||
cmake --build build
|
||||
./build/benchmarks/realbenchmark
|
||||
```
|
||||
|
||||
Importantly, by default, the benchmark is built in Release mode.
|
||||
|
||||
The instructions are similar under Windows.
|
||||
|
||||
Under Linux and macOS, it is recommended to run the benchmarks in a privileged manner to get access
|
||||
to hardware performance counters. You may be able to do so with the `sudo` command
|
||||
in some cases:
|
||||
|
||||
```
|
||||
sudo ./build/benchmarks/realbenchmark
|
||||
```
|
||||
|
||||
If you have a text file containing one number per line (`myfile.txt`), you can run a benchmark over it like so:
|
||||
```
|
||||
cmake -B build -D FASTFLOAT_BENCHMARKS=ON
|
||||
cmake --build build
|
||||
./build/benchmarks/realbenchmark myfile.txt
|
||||
```
|
||||
|
||||
|
||||
## Packages
|
||||
|
||||
* The fast_float library is part of the [Conan package
|
||||
manager](https://conan.io/center/recipes/fast_float).
|
||||
* It is part of the [brew package
|
||||
manager](https://formulae.brew.sh/formula/fast_float).
|
||||
* fast_float is available on [xmake](https://xmake.io) repository.
|
||||
* Some Linux distribution like Fedora include fast_float (e.g., as
|
||||
`fast_float-devel`).
|
||||
|
||||
## Credit
|
||||
|
||||
Though this work is inspired by many different people, this work benefited especially from exchanges with
|
||||
Michael Eisel, who motivated the original research with his key insights, and with Nigel Tao who provided
|
||||
invaluable feedback. Rémy Oudompheng first implemented a fast path we use in the case of long digits.
|
||||
Though this work is inspired by many different people, this work benefited
|
||||
especially from exchanges with Michael Eisel, who motivated the original
|
||||
research with his key insights, and with Nigel Tao who provided invaluable
|
||||
feedback. Rémy Oudompheng first implemented a fast path we use in the case of
|
||||
long digits.
|
||||
|
||||
The library includes code adapted from Google Wuffs (written by Nigel Tao) which was originally published
|
||||
under the Apache 2.0 license.
|
||||
The library includes code adapted from Google Wuffs (written by Nigel Tao) which
|
||||
was originally published under the Apache 2.0 license.
|
||||
|
||||
## License
|
||||
|
||||
<sup>
|
||||
Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
|
||||
2.0</a> or <a href="LICENSE-MIT">MIT license</a> or <a href="LICENSE-BOOST">BOOST license</a> .
|
||||
2.0</a> or <a href="LICENSE-MIT">MIT license</a> or <a
|
||||
href="LICENSE-BOOST">BOOST license</a>.
|
||||
</sup>
|
||||
|
||||
<br>
|
||||
<br/>
|
||||
|
||||
<sub>
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted
|
||||
|
||||
@@ -20,8 +20,7 @@
|
||||
|
||||
namespace fast_float {
|
||||
|
||||
template <typename UC>
|
||||
fastfloat_really_inline constexpr bool has_simd_opt() {
|
||||
template <typename UC> fastfloat_really_inline constexpr bool has_simd_opt() {
|
||||
#ifdef FASTFLOAT_HAS_SIMD
|
||||
return std::is_same<UC, char16_t>::value;
|
||||
#else
|
||||
@@ -37,24 +36,20 @@ fastfloat_really_inline constexpr bool is_integer(UC c) noexcept {
|
||||
}
|
||||
|
||||
fastfloat_really_inline constexpr uint64_t byteswap(uint64_t val) {
|
||||
return (val & 0xFF00000000000000) >> 56
|
||||
| (val & 0x00FF000000000000) >> 40
|
||||
| (val & 0x0000FF0000000000) >> 24
|
||||
| (val & 0x000000FF00000000) >> 8
|
||||
| (val & 0x00000000FF000000) << 8
|
||||
| (val & 0x0000000000FF0000) << 24
|
||||
| (val & 0x000000000000FF00) << 40
|
||||
| (val & 0x00000000000000FF) << 56;
|
||||
return (val & 0xFF00000000000000) >> 56 | (val & 0x00FF000000000000) >> 40 |
|
||||
(val & 0x0000FF0000000000) >> 24 | (val & 0x000000FF00000000) >> 8 |
|
||||
(val & 0x00000000FF000000) << 8 | (val & 0x0000000000FF0000) << 24 |
|
||||
(val & 0x000000000000FF00) << 40 | (val & 0x00000000000000FF) << 56;
|
||||
}
|
||||
|
||||
// Read 8 UC into a u64. Truncates UC if not char.
|
||||
template <typename UC>
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20
|
||||
uint64_t read8_to_u64(const UC *chars) {
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint64_t
|
||||
read8_to_u64(UC const *chars) {
|
||||
if (cpp20_and_in_constexpr() || !std::is_same<UC, char>::value) {
|
||||
uint64_t val = 0;
|
||||
for(int i = 0; i < 8; ++i) {
|
||||
val |= uint64_t(uint8_t(*chars)) << (i*8);
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
val |= uint64_t(uint8_t(*chars)) << (i * 8);
|
||||
++chars;
|
||||
}
|
||||
return val;
|
||||
@@ -70,44 +65,41 @@ uint64_t read8_to_u64(const UC *chars) {
|
||||
|
||||
#ifdef FASTFLOAT_SSE2
|
||||
|
||||
fastfloat_really_inline
|
||||
uint64_t simd_read8_to_u64(const __m128i data) {
|
||||
FASTFLOAT_SIMD_DISABLE_WARNINGS
|
||||
const __m128i packed = _mm_packus_epi16(data, data);
|
||||
fastfloat_really_inline uint64_t simd_read8_to_u64(__m128i const data) {
|
||||
FASTFLOAT_SIMD_DISABLE_WARNINGS
|
||||
__m128i const packed = _mm_packus_epi16(data, data);
|
||||
#ifdef FASTFLOAT_64BIT
|
||||
return uint64_t(_mm_cvtsi128_si64(packed));
|
||||
#else
|
||||
uint64_t value;
|
||||
// Visual Studio + older versions of GCC don't support _mm_storeu_si64
|
||||
_mm_storel_epi64(reinterpret_cast<__m128i*>(&value), packed);
|
||||
_mm_storel_epi64(reinterpret_cast<__m128i *>(&value), packed);
|
||||
return value;
|
||||
#endif
|
||||
FASTFLOAT_SIMD_RESTORE_WARNINGS
|
||||
FASTFLOAT_SIMD_RESTORE_WARNINGS
|
||||
}
|
||||
|
||||
fastfloat_really_inline
|
||||
uint64_t simd_read8_to_u64(const char16_t* chars) {
|
||||
FASTFLOAT_SIMD_DISABLE_WARNINGS
|
||||
return simd_read8_to_u64(_mm_loadu_si128(reinterpret_cast<const __m128i*>(chars)));
|
||||
FASTFLOAT_SIMD_RESTORE_WARNINGS
|
||||
fastfloat_really_inline uint64_t simd_read8_to_u64(char16_t const *chars) {
|
||||
FASTFLOAT_SIMD_DISABLE_WARNINGS
|
||||
return simd_read8_to_u64(
|
||||
_mm_loadu_si128(reinterpret_cast<__m128i const *>(chars)));
|
||||
FASTFLOAT_SIMD_RESTORE_WARNINGS
|
||||
}
|
||||
|
||||
#elif defined(FASTFLOAT_NEON)
|
||||
|
||||
|
||||
fastfloat_really_inline
|
||||
uint64_t simd_read8_to_u64(const uint16x8_t data) {
|
||||
FASTFLOAT_SIMD_DISABLE_WARNINGS
|
||||
fastfloat_really_inline uint64_t simd_read8_to_u64(uint16x8_t const data) {
|
||||
FASTFLOAT_SIMD_DISABLE_WARNINGS
|
||||
uint8x8_t utf8_packed = vmovn_u16(data);
|
||||
return vget_lane_u64(vreinterpret_u64_u8(utf8_packed), 0);
|
||||
FASTFLOAT_SIMD_RESTORE_WARNINGS
|
||||
FASTFLOAT_SIMD_RESTORE_WARNINGS
|
||||
}
|
||||
|
||||
fastfloat_really_inline
|
||||
uint64_t simd_read8_to_u64(const char16_t* chars) {
|
||||
FASTFLOAT_SIMD_DISABLE_WARNINGS
|
||||
return simd_read8_to_u64(vld1q_u16(reinterpret_cast<const uint16_t*>(chars)));
|
||||
FASTFLOAT_SIMD_RESTORE_WARNINGS
|
||||
fastfloat_really_inline uint64_t simd_read8_to_u64(char16_t const *chars) {
|
||||
FASTFLOAT_SIMD_DISABLE_WARNINGS
|
||||
return simd_read8_to_u64(
|
||||
vld1q_u16(reinterpret_cast<uint16_t const *>(chars)));
|
||||
FASTFLOAT_SIMD_RESTORE_WARNINGS
|
||||
}
|
||||
|
||||
#endif // FASTFLOAT_SSE2
|
||||
@@ -119,101 +111,84 @@ template <typename UC>
|
||||
template <typename UC, FASTFLOAT_ENABLE_IF(!has_simd_opt<UC>()) = 0>
|
||||
#endif
|
||||
// dummy for compile
|
||||
uint64_t simd_read8_to_u64(UC const*) {
|
||||
uint64_t simd_read8_to_u64(UC const *) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20
|
||||
void write_u64(uint8_t *chars, uint64_t val) {
|
||||
if (cpp20_and_in_constexpr()) {
|
||||
for(int i = 0; i < 8; ++i) {
|
||||
*chars = uint8_t(val);
|
||||
val >>= 8;
|
||||
++chars;
|
||||
}
|
||||
return;
|
||||
}
|
||||
#if FASTFLOAT_IS_BIG_ENDIAN == 1
|
||||
// Need to read as-if the number was in little-endian order.
|
||||
val = byteswap(val);
|
||||
#endif
|
||||
::memcpy(chars, &val, sizeof(uint64_t));
|
||||
}
|
||||
|
||||
// credit @aqrit
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR14
|
||||
uint32_t parse_eight_digits_unrolled(uint64_t val) {
|
||||
const uint64_t mask = 0x000000FF000000FF;
|
||||
const uint64_t mul1 = 0x000F424000000064; // 100 + (1000000ULL << 32)
|
||||
const uint64_t mul2 = 0x0000271000000001; // 1 + (10000ULL << 32)
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR14 uint32_t
|
||||
parse_eight_digits_unrolled(uint64_t val) {
|
||||
uint64_t const mask = 0x000000FF000000FF;
|
||||
uint64_t const mul1 = 0x000F424000000064; // 100 + (1000000ULL << 32)
|
||||
uint64_t const mul2 = 0x0000271000000001; // 1 + (10000ULL << 32)
|
||||
val -= 0x3030303030303030;
|
||||
val = (val * 10) + (val >> 8); // val = (val * 2561) >> 8;
|
||||
val = (((val & mask) * mul1) + (((val >> 16) & mask) * mul2)) >> 32;
|
||||
return uint32_t(val);
|
||||
}
|
||||
|
||||
|
||||
// Call this if chars are definitely 8 digits.
|
||||
template <typename UC>
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20
|
||||
uint32_t parse_eight_digits_unrolled(UC const * chars) noexcept {
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint32_t
|
||||
parse_eight_digits_unrolled(UC const *chars) noexcept {
|
||||
if (cpp20_and_in_constexpr() || !has_simd_opt<UC>()) {
|
||||
return parse_eight_digits_unrolled(read8_to_u64(chars)); // truncation okay
|
||||
}
|
||||
return parse_eight_digits_unrolled(simd_read8_to_u64(chars));
|
||||
}
|
||||
|
||||
|
||||
// credit @aqrit
|
||||
fastfloat_really_inline constexpr bool is_made_of_eight_digits_fast(uint64_t val) noexcept {
|
||||
fastfloat_really_inline constexpr bool
|
||||
is_made_of_eight_digits_fast(uint64_t val) noexcept {
|
||||
return !((((val + 0x4646464646464646) | (val - 0x3030303030303030)) &
|
||||
0x8080808080808080));
|
||||
0x8080808080808080));
|
||||
}
|
||||
|
||||
|
||||
#ifdef FASTFLOAT_HAS_SIMD
|
||||
|
||||
// Call this if chars might not be 8 digits.
|
||||
// Using this style (instead of is_made_of_eight_digits_fast() then parse_eight_digits_unrolled())
|
||||
// ensures we don't load SIMD registers twice.
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20
|
||||
bool simd_parse_if_eight_digits_unrolled(const char16_t* chars, uint64_t& i) noexcept {
|
||||
// Using this style (instead of is_made_of_eight_digits_fast() then
|
||||
// parse_eight_digits_unrolled()) ensures we don't load SIMD registers twice.
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 bool
|
||||
simd_parse_if_eight_digits_unrolled(char16_t const *chars,
|
||||
uint64_t &i) noexcept {
|
||||
if (cpp20_and_in_constexpr()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#ifdef FASTFLOAT_SSE2
|
||||
FASTFLOAT_SIMD_DISABLE_WARNINGS
|
||||
const __m128i data = _mm_loadu_si128(reinterpret_cast<const __m128i*>(chars));
|
||||
FASTFLOAT_SIMD_DISABLE_WARNINGS
|
||||
__m128i const data =
|
||||
_mm_loadu_si128(reinterpret_cast<__m128i const *>(chars));
|
||||
|
||||
// (x - '0') <= 9
|
||||
// http://0x80.pl/articles/simd-parsing-int-sequences.html
|
||||
const __m128i t0 = _mm_add_epi16(data, _mm_set1_epi16(32720));
|
||||
const __m128i t1 = _mm_cmpgt_epi16(t0, _mm_set1_epi16(-32759));
|
||||
__m128i const t0 = _mm_add_epi16(data, _mm_set1_epi16(32720));
|
||||
__m128i const t1 = _mm_cmpgt_epi16(t0, _mm_set1_epi16(-32759));
|
||||
|
||||
if (_mm_movemask_epi8(t1) == 0) {
|
||||
i = i * 100000000 + parse_eight_digits_unrolled(simd_read8_to_u64(data));
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
FASTFLOAT_SIMD_RESTORE_WARNINGS
|
||||
} else
|
||||
return false;
|
||||
FASTFLOAT_SIMD_RESTORE_WARNINGS
|
||||
#elif defined(FASTFLOAT_NEON)
|
||||
FASTFLOAT_SIMD_DISABLE_WARNINGS
|
||||
const uint16x8_t data = vld1q_u16(reinterpret_cast<const uint16_t*>(chars));
|
||||
|
||||
FASTFLOAT_SIMD_DISABLE_WARNINGS
|
||||
uint16x8_t const data = vld1q_u16(reinterpret_cast<uint16_t const *>(chars));
|
||||
|
||||
// (x - '0') <= 9
|
||||
// http://0x80.pl/articles/simd-parsing-int-sequences.html
|
||||
const uint16x8_t t0 = vsubq_u16(data, vmovq_n_u16('0'));
|
||||
const uint16x8_t mask = vcltq_u16(t0, vmovq_n_u16('9' - '0' + 1));
|
||||
uint16x8_t const t0 = vsubq_u16(data, vmovq_n_u16('0'));
|
||||
uint16x8_t const mask = vcltq_u16(t0, vmovq_n_u16('9' - '0' + 1));
|
||||
|
||||
if (vminvq_u16(mask) == 0xFFFF) {
|
||||
i = i * 100000000 + parse_eight_digits_unrolled(simd_read8_to_u64(data));
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
FASTFLOAT_SIMD_RESTORE_WARNINGS
|
||||
} else
|
||||
return false;
|
||||
FASTFLOAT_SIMD_RESTORE_WARNINGS
|
||||
#else
|
||||
(void)chars; (void)i;
|
||||
(void)chars;
|
||||
(void)i;
|
||||
return false;
|
||||
#endif // FASTFLOAT_SSE2
|
||||
}
|
||||
@@ -227,79 +202,119 @@ template <typename UC>
|
||||
template <typename UC, FASTFLOAT_ENABLE_IF(!has_simd_opt<UC>()) = 0>
|
||||
#endif
|
||||
// dummy for compile
|
||||
bool simd_parse_if_eight_digits_unrolled(UC const*, uint64_t&) {
|
||||
bool simd_parse_if_eight_digits_unrolled(UC const *, uint64_t &) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
template <typename UC, FASTFLOAT_ENABLE_IF(!std::is_same<UC, char>::value) = 0>
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20
|
||||
void loop_parse_if_eight_digits(const UC*& p, const UC* const pend, uint64_t& i) {
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void
|
||||
loop_parse_if_eight_digits(UC const *&p, UC const *const pend, uint64_t &i) {
|
||||
if (!has_simd_opt<UC>()) {
|
||||
return;
|
||||
}
|
||||
while ((std::distance(p, pend) >= 8) && simd_parse_if_eight_digits_unrolled(p, i)) { // in rare cases, this will overflow, but that's ok
|
||||
while ((std::distance(p, pend) >= 8) &&
|
||||
simd_parse_if_eight_digits_unrolled(
|
||||
p, i)) { // in rare cases, this will overflow, but that's ok
|
||||
p += 8;
|
||||
}
|
||||
}
|
||||
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20
|
||||
void loop_parse_if_eight_digits(const char*& p, const char* const pend, uint64_t& i) {
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void
|
||||
loop_parse_if_eight_digits(char const *&p, char const *const pend,
|
||||
uint64_t &i) {
|
||||
// optimizes better than parse_if_eight_digits_unrolled() for UC = char.
|
||||
while ((std::distance(p, pend) >= 8) && is_made_of_eight_digits_fast(read8_to_u64(p))) {
|
||||
i = i * 100000000 + parse_eight_digits_unrolled(read8_to_u64(p)); // in rare cases, this will overflow, but that's ok
|
||||
while ((std::distance(p, pend) >= 8) &&
|
||||
is_made_of_eight_digits_fast(read8_to_u64(p))) {
|
||||
i = i * 100000000 +
|
||||
parse_eight_digits_unrolled(read8_to_u64(
|
||||
p)); // in rare cases, this will overflow, but that's ok
|
||||
p += 8;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename UC>
|
||||
struct parsed_number_string_t {
|
||||
enum class parse_error {
|
||||
no_error,
|
||||
// [JSON-only] The minus sign must be followed by an integer.
|
||||
missing_integer_after_sign,
|
||||
// A sign must be followed by an integer or dot.
|
||||
missing_integer_or_dot_after_sign,
|
||||
// [JSON-only] The integer part must not have leading zeros.
|
||||
leading_zeros_in_integer_part,
|
||||
// [JSON-only] The integer part must have at least one digit.
|
||||
no_digits_in_integer_part,
|
||||
// [JSON-only] If there is a decimal point, there must be digits in the
|
||||
// fractional part.
|
||||
no_digits_in_fractional_part,
|
||||
// The mantissa must have at least one digit.
|
||||
no_digits_in_mantissa,
|
||||
// Scientific notation requires an exponential part.
|
||||
missing_exponential_part,
|
||||
};
|
||||
|
||||
template <typename UC> struct parsed_number_string_t {
|
||||
int64_t exponent{0};
|
||||
uint64_t mantissa{0};
|
||||
UC const * lastmatch{nullptr};
|
||||
UC const *lastmatch{nullptr};
|
||||
bool negative{false};
|
||||
bool valid{false};
|
||||
bool too_many_digits{false};
|
||||
// contains the range of the significant digits
|
||||
span<const UC> integer{}; // non-nullable
|
||||
span<const UC> fraction{}; // nullable
|
||||
span<UC const> integer{}; // non-nullable
|
||||
span<UC const> fraction{}; // nullable
|
||||
parse_error error{parse_error::no_error};
|
||||
};
|
||||
|
||||
using byte_span = span<const char>;
|
||||
using byte_span = span<char const>;
|
||||
using parsed_number_string = parsed_number_string_t<char>;
|
||||
|
||||
template <typename UC>
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 parsed_number_string_t<UC>
|
||||
report_parse_error(UC const *p, parse_error error) {
|
||||
parsed_number_string_t<UC> answer;
|
||||
answer.valid = false;
|
||||
answer.lastmatch = p;
|
||||
answer.error = error;
|
||||
return answer;
|
||||
}
|
||||
|
||||
// Assuming that you use no more than 19 digits, this will
|
||||
// parse an ASCII string.
|
||||
template <typename UC>
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20
|
||||
parsed_number_string_t<UC> parse_number_string(UC const *p, UC const * pend, parse_options_t<UC> options) noexcept {
|
||||
chars_format const fmt = options.format;
|
||||
template <bool basic_json_fmt, typename UC>
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 parsed_number_string_t<UC>
|
||||
parse_number_string(UC const *p, UC const *pend,
|
||||
parse_options_t<UC> options) noexcept {
|
||||
chars_format const fmt = detail::adjust_for_feature_macros(options.format);
|
||||
UC const decimal_point = options.decimal_point;
|
||||
|
||||
parsed_number_string_t<UC> answer;
|
||||
answer.valid = false;
|
||||
answer.too_many_digits = false;
|
||||
// assume p < pend, so dereference without checks;
|
||||
answer.negative = (*p == UC('-'));
|
||||
#ifdef FASTFLOAT_ALLOWS_LEADING_PLUS // disabled by default
|
||||
if ((*p == UC('-')) || (!(fmt & FASTFLOAT_JSONFMT) && *p == UC('+'))) {
|
||||
#else
|
||||
if (*p == UC('-')) { // C++17 20.19.3.(7.1) explicitly forbids '+' sign here
|
||||
#endif
|
||||
// C++17 20.19.3.(7.1) explicitly forbids '+' sign here
|
||||
if ((*p == UC('-')) || (uint64_t(fmt & chars_format::allow_leading_plus) &&
|
||||
!basic_json_fmt && *p == UC('+'))) {
|
||||
++p;
|
||||
if (p == pend) {
|
||||
return answer;
|
||||
return report_parse_error<UC>(
|
||||
p, parse_error::missing_integer_or_dot_after_sign);
|
||||
}
|
||||
if (fmt & FASTFLOAT_JSONFMT) {
|
||||
FASTFLOAT_IF_CONSTEXPR17(basic_json_fmt) {
|
||||
if (!is_integer(*p)) { // a sign must be followed by an integer
|
||||
return answer;
|
||||
}
|
||||
} else {
|
||||
if (!is_integer(*p) && (*p != decimal_point)) { // a sign must be followed by an integer or the dot
|
||||
return answer;
|
||||
return report_parse_error<UC>(p,
|
||||
parse_error::missing_integer_after_sign);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!is_integer(*p) &&
|
||||
(*p !=
|
||||
decimal_point)) { // a sign must be followed by an integer or the dot
|
||||
return report_parse_error<UC>(
|
||||
p, parse_error::missing_integer_or_dot_after_sign);
|
||||
}
|
||||
}
|
||||
}
|
||||
UC const * const start_digits = p;
|
||||
UC const *const start_digits = p;
|
||||
|
||||
uint64_t i = 0; // an unsigned int avoids signed overflows (which are bad)
|
||||
|
||||
@@ -307,24 +322,29 @@ parsed_number_string_t<UC> parse_number_string(UC const *p, UC const * pend, par
|
||||
// a multiplication by 10 is cheaper than an arbitrary integer
|
||||
// multiplication
|
||||
i = 10 * i +
|
||||
uint64_t(*p - UC('0')); // might overflow, we will handle the overflow later
|
||||
uint64_t(*p -
|
||||
UC('0')); // might overflow, we will handle the overflow later
|
||||
++p;
|
||||
}
|
||||
UC const * const end_of_integer_part = p;
|
||||
UC const *const end_of_integer_part = p;
|
||||
int64_t digit_count = int64_t(end_of_integer_part - start_digits);
|
||||
answer.integer = span<const UC>(start_digits, size_t(digit_count));
|
||||
if (fmt & FASTFLOAT_JSONFMT) {
|
||||
answer.integer = span<UC const>(start_digits, size_t(digit_count));
|
||||
FASTFLOAT_IF_CONSTEXPR17(basic_json_fmt) {
|
||||
// at least 1 digit in integer part, without leading zeros
|
||||
if (digit_count == 0 || (start_digits[0] == UC('0') && digit_count > 1)) {
|
||||
return answer;
|
||||
if (digit_count == 0) {
|
||||
return report_parse_error<UC>(p, parse_error::no_digits_in_integer_part);
|
||||
}
|
||||
if ((start_digits[0] == UC('0') && digit_count > 1)) {
|
||||
return report_parse_error<UC>(start_digits,
|
||||
parse_error::leading_zeros_in_integer_part);
|
||||
}
|
||||
}
|
||||
|
||||
int64_t exponent = 0;
|
||||
const bool has_decimal_point = (p != pend) && (*p == decimal_point);
|
||||
bool const has_decimal_point = (p != pend) && (*p == decimal_point);
|
||||
if (has_decimal_point) {
|
||||
++p;
|
||||
UC const * before = p;
|
||||
UC const *before = p;
|
||||
// can occur at most twice without overflowing, but let it occur more, since
|
||||
// for integers with many digits, digit parsing is the primary bottleneck.
|
||||
loop_parse_if_eight_digits(p, pend, i);
|
||||
@@ -335,41 +355,45 @@ parsed_number_string_t<UC> parse_number_string(UC const *p, UC const * pend, par
|
||||
i = i * 10 + digit; // in rare cases, this will overflow, but that's ok
|
||||
}
|
||||
exponent = before - p;
|
||||
answer.fraction = span<const UC>(before, size_t(p - before));
|
||||
answer.fraction = span<UC const>(before, size_t(p - before));
|
||||
digit_count -= exponent;
|
||||
}
|
||||
if (fmt & FASTFLOAT_JSONFMT) {
|
||||
FASTFLOAT_IF_CONSTEXPR17(basic_json_fmt) {
|
||||
// at least 1 digit in fractional part
|
||||
if (has_decimal_point && exponent == 0) {
|
||||
return answer;
|
||||
return report_parse_error<UC>(p,
|
||||
parse_error::no_digits_in_fractional_part);
|
||||
}
|
||||
}
|
||||
else if (digit_count == 0) { // we must have encountered at least one integer!
|
||||
return answer;
|
||||
}
|
||||
int64_t exp_number = 0; // explicit exponential part
|
||||
if ( ((fmt & chars_format::scientific) &&
|
||||
(p != pend) &&
|
||||
((UC('e') == *p) || (UC('E') == *p)))
|
||||
||
|
||||
((fmt & FASTFLOAT_FORTRANFMT) &&
|
||||
(p != pend) &&
|
||||
((UC('+') == *p) || (UC('-') == *p) || (UC('d') == *p) || (UC('D') == *p)))) {
|
||||
UC const * location_of_e = p;
|
||||
if ((UC('e') == *p) || (UC('E') == *p) || (UC('d') == *p) || (UC('D') == *p)) {
|
||||
else if (digit_count == 0) { // we must have encountered at least one integer!
|
||||
return report_parse_error<UC>(p, parse_error::no_digits_in_mantissa);
|
||||
}
|
||||
int64_t exp_number = 0; // explicit exponential part
|
||||
if ((uint64_t(fmt & chars_format::scientific) && (p != pend) &&
|
||||
((UC('e') == *p) || (UC('E') == *p))) ||
|
||||
(uint64_t(fmt & detail::basic_fortran_fmt) && (p != pend) &&
|
||||
((UC('+') == *p) || (UC('-') == *p) || (UC('d') == *p) ||
|
||||
(UC('D') == *p)))) {
|
||||
UC const *location_of_e = p;
|
||||
if ((UC('e') == *p) || (UC('E') == *p) || (UC('d') == *p) ||
|
||||
(UC('D') == *p)) {
|
||||
++p;
|
||||
}
|
||||
bool neg_exp = false;
|
||||
if ((p != pend) && (UC('-') == *p)) {
|
||||
neg_exp = true;
|
||||
++p;
|
||||
} else if ((p != pend) && (UC('+') == *p)) { // '+' on exponent is allowed by C++17 20.19.3.(7.1)
|
||||
} else if ((p != pend) &&
|
||||
(UC('+') ==
|
||||
*p)) { // '+' on exponent is allowed by C++17 20.19.3.(7.1)
|
||||
++p;
|
||||
}
|
||||
if ((p == pend) || !is_integer(*p)) {
|
||||
if(!(fmt & chars_format::fixed)) {
|
||||
// We are in error.
|
||||
return answer;
|
||||
if (!uint64_t(fmt & chars_format::fixed)) {
|
||||
// The exponential part is invalid for scientific notation, so it must
|
||||
// be a trailing token for fixed notation. However, fixed notation is
|
||||
// disabled, so report a scientific notation error.
|
||||
return report_parse_error<UC>(p, parse_error::missing_exponential_part);
|
||||
}
|
||||
// Otherwise, we will be ignoring the 'e'.
|
||||
p = location_of_e;
|
||||
@@ -381,12 +405,17 @@ parsed_number_string_t<UC> parse_number_string(UC const *p, UC const * pend, par
|
||||
}
|
||||
++p;
|
||||
}
|
||||
if(neg_exp) { exp_number = - exp_number; }
|
||||
if (neg_exp) {
|
||||
exp_number = -exp_number;
|
||||
}
|
||||
exponent += exp_number;
|
||||
}
|
||||
} else {
|
||||
// If it scientific and not fixed, we have to bail out.
|
||||
if((fmt & chars_format::scientific) && !(fmt & chars_format::fixed)) { return answer; }
|
||||
if (uint64_t(fmt & chars_format::scientific) &&
|
||||
!uint64_t(fmt & chars_format::fixed)) {
|
||||
return report_parse_error<UC>(p, parse_error::missing_exponential_part);
|
||||
}
|
||||
}
|
||||
answer.lastmatch = p;
|
||||
answer.valid = true;
|
||||
@@ -401,31 +430,32 @@ parsed_number_string_t<UC> parse_number_string(UC const *p, UC const * pend, par
|
||||
// We have to handle the case where we have 0.0000somenumber.
|
||||
// We need to be mindful of the case where we only have zeroes...
|
||||
// E.g., 0.000000000...000.
|
||||
UC const * start = start_digits;
|
||||
UC const *start = start_digits;
|
||||
while ((start != pend) && (*start == UC('0') || *start == decimal_point)) {
|
||||
if(*start == UC('0')) { digit_count --; }
|
||||
if (*start == UC('0')) {
|
||||
digit_count--;
|
||||
}
|
||||
start++;
|
||||
}
|
||||
|
||||
if (digit_count > 19) {
|
||||
answer.too_many_digits = true;
|
||||
// Let us start again, this time, avoiding overflows.
|
||||
// We don't need to check if is_integer, since we use the
|
||||
// We don't need to call if is_integer, since we use the
|
||||
// pre-tokenized spans from above.
|
||||
i = 0;
|
||||
p = answer.integer.ptr;
|
||||
UC const* int_end = p + answer.integer.len();
|
||||
const uint64_t minimal_nineteen_digit_integer{ 1000000000000000000 };
|
||||
UC const *int_end = p + answer.integer.len();
|
||||
uint64_t const minimal_nineteen_digit_integer{1000000000000000000};
|
||||
while ((i < minimal_nineteen_digit_integer) && (p != int_end)) {
|
||||
i = i * 10 + uint64_t(*p - UC('0'));
|
||||
++p;
|
||||
}
|
||||
if (i >= minimal_nineteen_digit_integer) { // We have a big integers
|
||||
if (i >= minimal_nineteen_digit_integer) { // We have a big integer
|
||||
exponent = end_of_integer_part - p + exp_number;
|
||||
}
|
||||
else { // We have a value with a fractional component.
|
||||
} else { // We have a value with a fractional component.
|
||||
p = answer.fraction.ptr;
|
||||
UC const* frac_end = p + answer.fraction.len();
|
||||
UC const *frac_end = p + answer.fraction.len();
|
||||
while ((i < minimal_nineteen_digit_integer) && (p != frac_end)) {
|
||||
i = i * 10 + uint64_t(*p - UC('0'));
|
||||
++p;
|
||||
@@ -441,35 +471,43 @@ parsed_number_string_t<UC> parse_number_string(UC const *p, UC const * pend, par
|
||||
}
|
||||
|
||||
template <typename T, typename UC>
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20
|
||||
from_chars_result_t<UC> parse_int_string(UC const* p, UC const* pend, T& value, int base) {
|
||||
from_chars_result_t<UC> answer;
|
||||
|
||||
UC const* const first = p;
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
||||
parse_int_string(UC const *p, UC const *pend, T &value,
|
||||
parse_options_t<UC> options) {
|
||||
chars_format const fmt = detail::adjust_for_feature_macros(options.format);
|
||||
int const base = options.base;
|
||||
|
||||
bool negative = (*p == UC('-'));
|
||||
from_chars_result_t<UC> answer;
|
||||
|
||||
UC const *const first = p;
|
||||
|
||||
bool const negative = (*p == UC('-'));
|
||||
#ifdef FASTFLOAT_VISUAL_STUDIO
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4127)
|
||||
#endif
|
||||
if (!std::is_signed<T>::value && negative) {
|
||||
#ifdef FASTFLOAT_VISUAL_STUDIO
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
answer.ec = std::errc::invalid_argument;
|
||||
answer.ptr = first;
|
||||
return answer;
|
||||
}
|
||||
#ifdef FASTFLOAT_ALLOWS_LEADING_PLUS // disabled by default
|
||||
if ((*p == UC('-')) || (*p == UC('+'))) {
|
||||
#else
|
||||
if (*p == UC('-')) {
|
||||
#endif
|
||||
if ((*p == UC('-')) ||
|
||||
(uint64_t(fmt & chars_format::allow_leading_plus) && (*p == UC('+')))) {
|
||||
++p;
|
||||
}
|
||||
|
||||
UC const* const start_num = p;
|
||||
UC const *const start_num = p;
|
||||
|
||||
while (p!= pend && *p == UC('0')) {
|
||||
++p;
|
||||
while (p != pend && *p == UC('0')) {
|
||||
++p;
|
||||
}
|
||||
|
||||
const bool has_leading_zeros = p > start_num;
|
||||
bool const has_leading_zeros = p > start_num;
|
||||
|
||||
UC const* const start_digits = p;
|
||||
UC const *const start_digits = p;
|
||||
|
||||
uint64_t i = 0;
|
||||
if (base == 10) {
|
||||
@@ -481,9 +519,9 @@ from_chars_result_t<UC> parse_int_string(UC const* p, UC const* pend, T& value,
|
||||
break;
|
||||
}
|
||||
i = uint64_t(base) * i + digit; // might overflow, check this later
|
||||
p++;
|
||||
p++;
|
||||
}
|
||||
|
||||
|
||||
size_t digit_count = size_t(p - start_digits);
|
||||
|
||||
if (digit_count == 0) {
|
||||
@@ -491,12 +529,11 @@ from_chars_result_t<UC> parse_int_string(UC const* p, UC const* pend, T& value,
|
||||
value = 0;
|
||||
answer.ec = std::errc();
|
||||
answer.ptr = p;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
answer.ec = std::errc::invalid_argument;
|
||||
answer.ptr = first;
|
||||
}
|
||||
return answer;
|
||||
return answer;
|
||||
}
|
||||
|
||||
answer.ptr = p;
|
||||
@@ -507,7 +544,8 @@ from_chars_result_t<UC> parse_int_string(UC const* p, UC const* pend, T& value,
|
||||
answer.ec = std::errc::result_out_of_range;
|
||||
return answer;
|
||||
}
|
||||
// this check can be eliminated for all other types, but they will all require a max_digits(base) equivalent
|
||||
// this check can be eliminated for all other types, but they will all require
|
||||
// a max_digits(base) equivalent
|
||||
if (digit_count == max_digits && i < min_safe_u64(base)) {
|
||||
answer.ec = std::errc::result_out_of_range;
|
||||
return answer;
|
||||
@@ -524,18 +562,22 @@ from_chars_result_t<UC> parse_int_string(UC const* p, UC const* pend, T& value,
|
||||
if (negative) {
|
||||
#ifdef FASTFLOAT_VISUAL_STUDIO
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4146)
|
||||
#pragma warning(disable : 4146)
|
||||
#endif
|
||||
// this weird workaround is required because:
|
||||
// - converting unsigned to signed when its value is greater than signed max is UB pre-C++23.
|
||||
// - converting unsigned to signed when its value is greater than signed max
|
||||
// is UB pre-C++23.
|
||||
// - reinterpret_casting (~i + 1) would work, but it is not constexpr
|
||||
// this is always optimized into a neg instruction (note: T is an integer type)
|
||||
value = T(-std::numeric_limits<T>::max() - T(i - uint64_t(std::numeric_limits<T>::max())));
|
||||
// this is always optimized into a neg instruction (note: T is an integer
|
||||
// type)
|
||||
value = T(-std::numeric_limits<T>::max() -
|
||||
T(i - uint64_t(std::numeric_limits<T>::max())));
|
||||
#ifdef FASTFLOAT_VISUAL_STUDIO
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
} else {
|
||||
value = T(i);
|
||||
}
|
||||
else { value = T(i); }
|
||||
|
||||
answer.ec = std::errc();
|
||||
return answer;
|
||||
|
||||
223
3rdparty/fast_float/include/fast_float/bigint.h
vendored
223
3rdparty/fast_float/include/fast_float/bigint.h
vendored
@@ -37,15 +37,14 @@ constexpr size_t bigint_limbs = bigint_bits / limb_bits;
|
||||
|
||||
// vector-like type that is allocated on the stack. the entire
|
||||
// buffer is pre-allocated, and only the length changes.
|
||||
template <uint16_t size>
|
||||
struct stackvec {
|
||||
template <uint16_t size> struct stackvec {
|
||||
limb data[size];
|
||||
// we never need more than 150 limbs
|
||||
uint16_t length{0};
|
||||
|
||||
stackvec() = default;
|
||||
stackvec(const stackvec &) = delete;
|
||||
stackvec &operator=(const stackvec &) = delete;
|
||||
stackvec(stackvec const &) = delete;
|
||||
stackvec &operator=(stackvec const &) = delete;
|
||||
stackvec(stackvec &&) = delete;
|
||||
stackvec &operator=(stackvec &&other) = delete;
|
||||
|
||||
@@ -54,16 +53,18 @@ struct stackvec {
|
||||
FASTFLOAT_ASSERT(try_extend(s));
|
||||
}
|
||||
|
||||
FASTFLOAT_CONSTEXPR14 limb& operator[](size_t index) noexcept {
|
||||
FASTFLOAT_CONSTEXPR14 limb &operator[](size_t index) noexcept {
|
||||
FASTFLOAT_DEBUG_ASSERT(index < length);
|
||||
return data[index];
|
||||
}
|
||||
FASTFLOAT_CONSTEXPR14 const limb& operator[](size_t index) const noexcept {
|
||||
|
||||
FASTFLOAT_CONSTEXPR14 const limb &operator[](size_t index) const noexcept {
|
||||
FASTFLOAT_DEBUG_ASSERT(index < length);
|
||||
return data[index];
|
||||
}
|
||||
|
||||
// index from the end of the container
|
||||
FASTFLOAT_CONSTEXPR14 const limb& rindex(size_t index) const noexcept {
|
||||
FASTFLOAT_CONSTEXPR14 const limb &rindex(size_t index) const noexcept {
|
||||
FASTFLOAT_DEBUG_ASSERT(index < length);
|
||||
size_t rindex = length - index - 1;
|
||||
return data[rindex];
|
||||
@@ -73,20 +74,19 @@ struct stackvec {
|
||||
FASTFLOAT_CONSTEXPR14 void set_len(size_t len) noexcept {
|
||||
length = uint16_t(len);
|
||||
}
|
||||
constexpr size_t len() const noexcept {
|
||||
return length;
|
||||
}
|
||||
constexpr bool is_empty() const noexcept {
|
||||
return length == 0;
|
||||
}
|
||||
constexpr size_t capacity() const noexcept {
|
||||
return size;
|
||||
}
|
||||
|
||||
constexpr size_t len() const noexcept { return length; }
|
||||
|
||||
constexpr bool is_empty() const noexcept { return length == 0; }
|
||||
|
||||
constexpr size_t capacity() const noexcept { return size; }
|
||||
|
||||
// append item to vector, without bounds checking
|
||||
FASTFLOAT_CONSTEXPR14 void push_unchecked(limb value) noexcept {
|
||||
data[length] = value;
|
||||
length++;
|
||||
}
|
||||
|
||||
// append item to vector, returning if item was added
|
||||
FASTFLOAT_CONSTEXPR14 bool try_push(limb value) noexcept {
|
||||
if (len() < capacity()) {
|
||||
@@ -96,12 +96,14 @@ struct stackvec {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// add items to the vector, from a span, without bounds checking
|
||||
FASTFLOAT_CONSTEXPR20 void extend_unchecked(limb_span s) noexcept {
|
||||
limb* ptr = data + length;
|
||||
limb *ptr = data + length;
|
||||
std::copy_n(s.ptr, s.len(), ptr);
|
||||
set_len(len() + s.len());
|
||||
}
|
||||
|
||||
// try to add items to the vector, returning if items were added
|
||||
FASTFLOAT_CONSTEXPR20 bool try_extend(limb_span s) noexcept {
|
||||
if (len() + s.len() <= capacity()) {
|
||||
@@ -111,6 +113,7 @@ struct stackvec {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// resize the vector, without bounds checking
|
||||
// if the new size is longer than the vector, assign value to each
|
||||
// appended item.
|
||||
@@ -118,14 +121,15 @@ struct stackvec {
|
||||
void resize_unchecked(size_t new_len, limb value) noexcept {
|
||||
if (new_len > len()) {
|
||||
size_t count = new_len - len();
|
||||
limb* first = data + len();
|
||||
limb* last = first + count;
|
||||
limb *first = data + len();
|
||||
limb *last = first + count;
|
||||
::std::fill(first, last, value);
|
||||
set_len(new_len);
|
||||
} else {
|
||||
set_len(new_len);
|
||||
}
|
||||
}
|
||||
|
||||
// try to resize the vector, returning if the vector was resized.
|
||||
FASTFLOAT_CONSTEXPR20 bool try_resize(size_t new_len, limb value) noexcept {
|
||||
if (new_len > capacity()) {
|
||||
@@ -135,6 +139,7 @@ struct stackvec {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// check if any limbs are non-zero after the given index.
|
||||
// this needs to be done in reverse order, since the index
|
||||
// is relative to the most significant limbs.
|
||||
@@ -147,6 +152,7 @@ struct stackvec {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// normalize the big integer, so most-significant zero limbs are removed.
|
||||
FASTFLOAT_CONSTEXPR14 void normalize() noexcept {
|
||||
while (len() > 0 && rindex(0) == 0) {
|
||||
@@ -155,21 +161,21 @@ struct stackvec {
|
||||
}
|
||||
};
|
||||
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR14
|
||||
uint64_t empty_hi64(bool& truncated) noexcept {
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR14 uint64_t
|
||||
empty_hi64(bool &truncated) noexcept {
|
||||
truncated = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20
|
||||
uint64_t uint64_hi64(uint64_t r0, bool& truncated) noexcept {
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint64_t
|
||||
uint64_hi64(uint64_t r0, bool &truncated) noexcept {
|
||||
truncated = false;
|
||||
int shl = leading_zeroes(r0);
|
||||
return r0 << shl;
|
||||
}
|
||||
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20
|
||||
uint64_t uint64_hi64(uint64_t r0, uint64_t r1, bool& truncated) noexcept {
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint64_t
|
||||
uint64_hi64(uint64_t r0, uint64_t r1, bool &truncated) noexcept {
|
||||
int shl = leading_zeroes(r0);
|
||||
if (shl == 0) {
|
||||
truncated = r1 != 0;
|
||||
@@ -181,20 +187,20 @@ uint64_t uint64_hi64(uint64_t r0, uint64_t r1, bool& truncated) noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20
|
||||
uint64_t uint32_hi64(uint32_t r0, bool& truncated) noexcept {
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint64_t
|
||||
uint32_hi64(uint32_t r0, bool &truncated) noexcept {
|
||||
return uint64_hi64(r0, truncated);
|
||||
}
|
||||
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20
|
||||
uint64_t uint32_hi64(uint32_t r0, uint32_t r1, bool& truncated) noexcept {
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint64_t
|
||||
uint32_hi64(uint32_t r0, uint32_t r1, bool &truncated) noexcept {
|
||||
uint64_t x0 = r0;
|
||||
uint64_t x1 = r1;
|
||||
return uint64_hi64((x0 << 32) | x1, truncated);
|
||||
}
|
||||
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20
|
||||
uint64_t uint32_hi64(uint32_t r0, uint32_t r1, uint32_t r2, bool& truncated) noexcept {
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint64_t
|
||||
uint32_hi64(uint32_t r0, uint32_t r1, uint32_t r2, bool &truncated) noexcept {
|
||||
uint64_t x0 = r0;
|
||||
uint64_t x1 = r1;
|
||||
uint64_t x2 = r2;
|
||||
@@ -205,17 +211,17 @@ uint64_t uint32_hi64(uint32_t r0, uint32_t r1, uint32_t r2, bool& truncated) noe
|
||||
// we want an efficient operation. for msvc, where
|
||||
// we don't have built-in intrinsics, this is still
|
||||
// pretty fast.
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20
|
||||
limb scalar_add(limb x, limb y, bool& overflow) noexcept {
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 limb
|
||||
scalar_add(limb x, limb y, bool &overflow) noexcept {
|
||||
limb z;
|
||||
// gcc and clang
|
||||
#if defined(__has_builtin)
|
||||
#if __has_builtin(__builtin_add_overflow)
|
||||
if (!cpp20_and_in_constexpr()) {
|
||||
overflow = __builtin_add_overflow(x, y, &z);
|
||||
return z;
|
||||
}
|
||||
#endif
|
||||
#if __has_builtin(__builtin_add_overflow)
|
||||
if (!cpp20_and_in_constexpr()) {
|
||||
overflow = __builtin_add_overflow(x, y, &z);
|
||||
return z;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// generic, this still optimizes correctly on MSVC.
|
||||
@@ -225,24 +231,24 @@ limb scalar_add(limb x, limb y, bool& overflow) noexcept {
|
||||
}
|
||||
|
||||
// multiply two small integers, getting both the high and low bits.
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20
|
||||
limb scalar_mul(limb x, limb y, limb& carry) noexcept {
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 limb
|
||||
scalar_mul(limb x, limb y, limb &carry) noexcept {
|
||||
#ifdef FASTFLOAT_64BIT_LIMB
|
||||
#if defined(__SIZEOF_INT128__)
|
||||
#if defined(__SIZEOF_INT128__)
|
||||
// GCC and clang both define it as an extension.
|
||||
__uint128_t z = __uint128_t(x) * __uint128_t(y) + __uint128_t(carry);
|
||||
carry = limb(z >> limb_bits);
|
||||
return limb(z);
|
||||
#else
|
||||
#else
|
||||
// fallback, no native 128-bit integer multiplication with carry.
|
||||
// on msvc, this optimizes identically, somehow.
|
||||
value128 z = full_multiplication(x, y);
|
||||
bool overflow;
|
||||
z.low = scalar_add(z.low, carry, overflow);
|
||||
z.high += uint64_t(overflow); // cannot overflow
|
||||
z.high += uint64_t(overflow); // cannot overflow
|
||||
carry = z.high;
|
||||
return z.low;
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
uint64_t z = uint64_t(x) * uint64_t(y) + uint64_t(carry);
|
||||
carry = limb(z >> limb_bits);
|
||||
@@ -253,8 +259,8 @@ limb scalar_mul(limb x, limb y, limb& carry) noexcept {
|
||||
// add scalar value to bigint starting from offset.
|
||||
// used in grade school multiplication
|
||||
template <uint16_t size>
|
||||
inline FASTFLOAT_CONSTEXPR20
|
||||
bool small_add_from(stackvec<size>& vec, limb y, size_t start) noexcept {
|
||||
inline FASTFLOAT_CONSTEXPR20 bool small_add_from(stackvec<size> &vec, limb y,
|
||||
size_t start) noexcept {
|
||||
size_t index = start;
|
||||
limb carry = y;
|
||||
bool overflow;
|
||||
@@ -271,15 +277,15 @@ bool small_add_from(stackvec<size>& vec, limb y, size_t start) noexcept {
|
||||
|
||||
// add scalar value to bigint.
|
||||
template <uint16_t size>
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20
|
||||
bool small_add(stackvec<size>& vec, limb y) noexcept {
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 bool
|
||||
small_add(stackvec<size> &vec, limb y) noexcept {
|
||||
return small_add_from(vec, y, 0);
|
||||
}
|
||||
|
||||
// multiply bigint by scalar value.
|
||||
template <uint16_t size>
|
||||
inline FASTFLOAT_CONSTEXPR20
|
||||
bool small_mul(stackvec<size>& vec, limb y) noexcept {
|
||||
inline FASTFLOAT_CONSTEXPR20 bool small_mul(stackvec<size> &vec,
|
||||
limb y) noexcept {
|
||||
limb carry = 0;
|
||||
for (size_t index = 0; index < vec.len(); index++) {
|
||||
vec[index] = scalar_mul(vec[index], y, carry);
|
||||
@@ -293,12 +299,12 @@ bool small_mul(stackvec<size>& vec, limb y) noexcept {
|
||||
// add bigint to bigint starting from index.
|
||||
// used in grade school multiplication
|
||||
template <uint16_t size>
|
||||
FASTFLOAT_CONSTEXPR20
|
||||
bool large_add_from(stackvec<size>& x, limb_span y, size_t start) noexcept {
|
||||
FASTFLOAT_CONSTEXPR20 bool large_add_from(stackvec<size> &x, limb_span y,
|
||||
size_t start) noexcept {
|
||||
// the effective x buffer is from `xstart..x.len()`, so exit early
|
||||
// if we can't get that current range.
|
||||
if (x.len() < start || y.len() > x.len() - start) {
|
||||
FASTFLOAT_TRY(x.try_resize(y.len() + start, 0));
|
||||
FASTFLOAT_TRY(x.try_resize(y.len() + start, 0));
|
||||
}
|
||||
|
||||
bool carry = false;
|
||||
@@ -324,15 +330,14 @@ bool large_add_from(stackvec<size>& x, limb_span y, size_t start) noexcept {
|
||||
|
||||
// add bigint to bigint.
|
||||
template <uint16_t size>
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20
|
||||
bool large_add_from(stackvec<size>& x, limb_span y) noexcept {
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 bool
|
||||
large_add_from(stackvec<size> &x, limb_span y) noexcept {
|
||||
return large_add_from(x, y, 0);
|
||||
}
|
||||
|
||||
// grade-school multiplication algorithm
|
||||
template <uint16_t size>
|
||||
FASTFLOAT_CONSTEXPR20
|
||||
bool long_mul(stackvec<size>& x, limb_span y) noexcept {
|
||||
FASTFLOAT_CONSTEXPR20 bool long_mul(stackvec<size> &x, limb_span y) noexcept {
|
||||
limb_span xs = limb_span(x.data, x.len());
|
||||
stackvec<size> z(xs);
|
||||
limb_span zs = limb_span(z.data, z.len());
|
||||
@@ -360,8 +365,7 @@ bool long_mul(stackvec<size>& x, limb_span y) noexcept {
|
||||
|
||||
// grade-school multiplication algorithm
|
||||
template <uint16_t size>
|
||||
FASTFLOAT_CONSTEXPR20
|
||||
bool large_mul(stackvec<size>& x, limb_span y) noexcept {
|
||||
FASTFLOAT_CONSTEXPR20 bool large_mul(stackvec<size> &x, limb_span y) noexcept {
|
||||
if (y.len() == 1) {
|
||||
FASTFLOAT_TRY(small_mul(x, y[0]));
|
||||
} else {
|
||||
@@ -370,36 +374,58 @@ bool large_mul(stackvec<size>& x, limb_span y) noexcept {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename = void>
|
||||
struct pow5_tables {
|
||||
template <typename = void> struct pow5_tables {
|
||||
static constexpr uint32_t large_step = 135;
|
||||
static constexpr uint64_t small_power_of_5[] = {
|
||||
1UL, 5UL, 25UL, 125UL, 625UL, 3125UL, 15625UL, 78125UL, 390625UL,
|
||||
1953125UL, 9765625UL, 48828125UL, 244140625UL, 1220703125UL,
|
||||
6103515625UL, 30517578125UL, 152587890625UL, 762939453125UL,
|
||||
3814697265625UL, 19073486328125UL, 95367431640625UL, 476837158203125UL,
|
||||
2384185791015625UL, 11920928955078125UL, 59604644775390625UL,
|
||||
298023223876953125UL, 1490116119384765625UL, 7450580596923828125UL,
|
||||
1UL,
|
||||
5UL,
|
||||
25UL,
|
||||
125UL,
|
||||
625UL,
|
||||
3125UL,
|
||||
15625UL,
|
||||
78125UL,
|
||||
390625UL,
|
||||
1953125UL,
|
||||
9765625UL,
|
||||
48828125UL,
|
||||
244140625UL,
|
||||
1220703125UL,
|
||||
6103515625UL,
|
||||
30517578125UL,
|
||||
152587890625UL,
|
||||
762939453125UL,
|
||||
3814697265625UL,
|
||||
19073486328125UL,
|
||||
95367431640625UL,
|
||||
476837158203125UL,
|
||||
2384185791015625UL,
|
||||
11920928955078125UL,
|
||||
59604644775390625UL,
|
||||
298023223876953125UL,
|
||||
1490116119384765625UL,
|
||||
7450580596923828125UL,
|
||||
};
|
||||
#ifdef FASTFLOAT_64BIT_LIMB
|
||||
constexpr static limb large_power_of_5[] = {
|
||||
1414648277510068013UL, 9180637584431281687UL, 4539964771860779200UL,
|
||||
10482974169319127550UL, 198276706040285095UL};
|
||||
1414648277510068013UL, 9180637584431281687UL, 4539964771860779200UL,
|
||||
10482974169319127550UL, 198276706040285095UL};
|
||||
#else
|
||||
constexpr static limb large_power_of_5[] = {
|
||||
4279965485U, 329373468U, 4020270615U, 2137533757U, 4287402176U,
|
||||
1057042919U, 1071430142U, 2440757623U, 381945767U, 46164893U};
|
||||
4279965485U, 329373468U, 4020270615U, 2137533757U, 4287402176U,
|
||||
1057042919U, 1071430142U, 2440757623U, 381945767U, 46164893U};
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
constexpr uint32_t pow5_tables<T>::large_step;
|
||||
#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE
|
||||
|
||||
template <typename T>
|
||||
constexpr uint64_t pow5_tables<T>::small_power_of_5[];
|
||||
template <typename T> constexpr uint32_t pow5_tables<T>::large_step;
|
||||
|
||||
template <typename T>
|
||||
constexpr limb pow5_tables<T>::large_power_of_5[];
|
||||
template <typename T> constexpr uint64_t pow5_tables<T>::small_power_of_5[];
|
||||
|
||||
template <typename T> constexpr limb pow5_tables<T>::large_power_of_5[];
|
||||
|
||||
#endif
|
||||
|
||||
// big integer type. implements a small subset of big integer
|
||||
// arithmetic, using simple algorithms since asymptotically
|
||||
@@ -409,13 +435,14 @@ struct bigint : pow5_tables<> {
|
||||
// storage of the limbs, in little-endian order.
|
||||
stackvec<bigint_limbs> vec;
|
||||
|
||||
FASTFLOAT_CONSTEXPR20 bigint(): vec() {}
|
||||
bigint(const bigint &) = delete;
|
||||
bigint &operator=(const bigint &) = delete;
|
||||
FASTFLOAT_CONSTEXPR20 bigint() : vec() {}
|
||||
|
||||
bigint(bigint const &) = delete;
|
||||
bigint &operator=(bigint const &) = delete;
|
||||
bigint(bigint &&) = delete;
|
||||
bigint &operator=(bigint &&other) = delete;
|
||||
|
||||
FASTFLOAT_CONSTEXPR20 bigint(uint64_t value): vec() {
|
||||
FASTFLOAT_CONSTEXPR20 bigint(uint64_t value) : vec() {
|
||||
#ifdef FASTFLOAT_64BIT_LIMB
|
||||
vec.push_unchecked(value);
|
||||
#else
|
||||
@@ -427,7 +454,7 @@ struct bigint : pow5_tables<> {
|
||||
|
||||
// get the high 64 bits from the vector, and if bits were truncated.
|
||||
// this is to get the significant digits for the float.
|
||||
FASTFLOAT_CONSTEXPR20 uint64_t hi64(bool& truncated) const noexcept {
|
||||
FASTFLOAT_CONSTEXPR20 uint64_t hi64(bool &truncated) const noexcept {
|
||||
#ifdef FASTFLOAT_64BIT_LIMB
|
||||
if (vec.len() == 0) {
|
||||
return empty_hi64(truncated);
|
||||
@@ -446,7 +473,8 @@ struct bigint : pow5_tables<> {
|
||||
} else if (vec.len() == 2) {
|
||||
return uint32_hi64(vec.rindex(0), vec.rindex(1), truncated);
|
||||
} else {
|
||||
uint64_t result = uint32_hi64(vec.rindex(0), vec.rindex(1), vec.rindex(2), truncated);
|
||||
uint64_t result =
|
||||
uint32_hi64(vec.rindex(0), vec.rindex(1), vec.rindex(2), truncated);
|
||||
truncated |= vec.nonzero(3);
|
||||
return result;
|
||||
}
|
||||
@@ -459,7 +487,7 @@ struct bigint : pow5_tables<> {
|
||||
// positive, this is larger, otherwise they are equal.
|
||||
// the limbs are stored in little-endian order, so we
|
||||
// must compare the limbs in ever order.
|
||||
FASTFLOAT_CONSTEXPR20 int compare(const bigint& other) const noexcept {
|
||||
FASTFLOAT_CONSTEXPR20 int compare(bigint const &other) const noexcept {
|
||||
if (vec.len() > other.vec.len()) {
|
||||
return 1;
|
||||
} else if (vec.len() < other.vec.len()) {
|
||||
@@ -512,12 +540,12 @@ struct bigint : pow5_tables<> {
|
||||
return false;
|
||||
} else if (!vec.is_empty()) {
|
||||
// move limbs
|
||||
limb* dst = vec.data + n;
|
||||
const limb* src = vec.data;
|
||||
limb *dst = vec.data + n;
|
||||
limb const *src = vec.data;
|
||||
std::copy_backward(src, src + vec.len(), dst + vec.len());
|
||||
// fill in empty limbs
|
||||
limb* first = vec.data;
|
||||
limb* last = first + n;
|
||||
limb *first = vec.data;
|
||||
limb *last = first + n;
|
||||
::std::fill(first, last, 0);
|
||||
vec.set_len(n + vec.len());
|
||||
return true;
|
||||
@@ -560,18 +588,12 @@ struct bigint : pow5_tables<> {
|
||||
return int(limb_bits * vec.len()) - lz;
|
||||
}
|
||||
|
||||
FASTFLOAT_CONSTEXPR20 bool mul(limb y) noexcept {
|
||||
return small_mul(vec, y);
|
||||
}
|
||||
FASTFLOAT_CONSTEXPR20 bool mul(limb y) noexcept { return small_mul(vec, y); }
|
||||
|
||||
FASTFLOAT_CONSTEXPR20 bool add(limb y) noexcept {
|
||||
return small_add(vec, y);
|
||||
}
|
||||
FASTFLOAT_CONSTEXPR20 bool add(limb y) noexcept { return small_add(vec, y); }
|
||||
|
||||
// multiply as if by 2 raised to a power.
|
||||
FASTFLOAT_CONSTEXPR20 bool pow2(uint32_t exp) noexcept {
|
||||
return shl(exp);
|
||||
}
|
||||
FASTFLOAT_CONSTEXPR20 bool pow2(uint32_t exp) noexcept { return shl(exp); }
|
||||
|
||||
// multiply as if by 5 raised to a power.
|
||||
FASTFLOAT_CONSTEXPR20 bool pow5(uint32_t exp) noexcept {
|
||||
@@ -597,9 +619,8 @@ struct bigint : pow5_tables<> {
|
||||
// Work around clang bug https://godbolt.org/z/zedh7rrhc
|
||||
// This is similar to https://github.com/llvm/llvm-project/issues/47746,
|
||||
// except the workaround described there don't work here
|
||||
FASTFLOAT_TRY(
|
||||
small_mul(vec, limb(((void)small_power_of_5[0], small_power_of_5[exp])))
|
||||
);
|
||||
FASTFLOAT_TRY(small_mul(
|
||||
vec, limb(((void)small_power_of_5[0], small_power_of_5[exp]))));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#endif
|
||||
|
||||
// Testing for https://wg21.link/N3652, adopted in C++14
|
||||
#if __cpp_constexpr >= 201304
|
||||
#if defined(__cpp_constexpr) && __cpp_constexpr >= 201304
|
||||
#define FASTFLOAT_CONSTEXPR14 constexpr
|
||||
#else
|
||||
#define FASTFLOAT_CONSTEXPR14
|
||||
@@ -20,16 +20,23 @@
|
||||
#define FASTFLOAT_HAS_BIT_CAST 0
|
||||
#endif
|
||||
|
||||
#if defined(__cpp_lib_is_constant_evaluated) && __cpp_lib_is_constant_evaluated >= 201811L
|
||||
#if defined(__cpp_lib_is_constant_evaluated) && \
|
||||
__cpp_lib_is_constant_evaluated >= 201811L
|
||||
#define FASTFLOAT_HAS_IS_CONSTANT_EVALUATED 1
|
||||
#else
|
||||
#define FASTFLOAT_HAS_IS_CONSTANT_EVALUATED 0
|
||||
#endif
|
||||
|
||||
#if defined(__cpp_if_constexpr) && __cpp_if_constexpr >= 201606L
|
||||
#define FASTFLOAT_IF_CONSTEXPR17(x) if constexpr (x)
|
||||
#else
|
||||
#define FASTFLOAT_IF_CONSTEXPR17(x) if (x)
|
||||
#endif
|
||||
|
||||
// Testing for relevant C++20 constexpr library features
|
||||
#if FASTFLOAT_HAS_IS_CONSTANT_EVALUATED \
|
||||
&& FASTFLOAT_HAS_BIT_CAST \
|
||||
&& __cpp_lib_constexpr_algorithms >= 201806L /*For std::copy and std::fill*/
|
||||
#if FASTFLOAT_HAS_IS_CONSTANT_EVALUATED && FASTFLOAT_HAS_BIT_CAST && \
|
||||
defined(__cpp_lib_constexpr_algorithms) && \
|
||||
__cpp_lib_constexpr_algorithms >= 201806L /*For std::copy and std::fill*/
|
||||
#define FASTFLOAT_CONSTEXPR20 constexpr
|
||||
#define FASTFLOAT_IS_CONSTEXPR 1
|
||||
#else
|
||||
@@ -37,4 +44,10 @@
|
||||
#define FASTFLOAT_IS_CONSTEXPR 0
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
|
||||
#define FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE 0
|
||||
#else
|
||||
#define FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE 1
|
||||
#endif
|
||||
|
||||
#endif // FASTFLOAT_CONSTEXPR_FEATURE_DETECT_H
|
||||
|
||||
@@ -12,27 +12,34 @@
|
||||
|
||||
namespace fast_float {
|
||||
|
||||
// This will compute or rather approximate w * 5**q and return a pair of 64-bit words approximating
|
||||
// the result, with the "high" part corresponding to the most significant bits and the
|
||||
// low part corresponding to the least significant bits.
|
||||
// This will compute or rather approximate w * 5**q and return a pair of 64-bit
|
||||
// words approximating the result, with the "high" part corresponding to the
|
||||
// most significant bits and the low part corresponding to the least significant
|
||||
// bits.
|
||||
//
|
||||
template <int bit_precision>
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20
|
||||
value128 compute_product_approximation(int64_t q, uint64_t w) {
|
||||
const int index = 2 * int(q - powers::smallest_power_of_five);
|
||||
// For small values of q, e.g., q in [0,27], the answer is always exact because
|
||||
// The line value128 firstproduct = full_multiplication(w, power_of_five_128[index]);
|
||||
// gives the exact answer.
|
||||
value128 firstproduct = full_multiplication(w, powers::power_of_five_128[index]);
|
||||
static_assert((bit_precision >= 0) && (bit_precision <= 64), " precision should be in (0,64]");
|
||||
constexpr uint64_t precision_mask = (bit_precision < 64) ?
|
||||
(uint64_t(0xFFFFFFFFFFFFFFFF) >> bit_precision)
|
||||
: uint64_t(0xFFFFFFFFFFFFFFFF);
|
||||
if((firstproduct.high & precision_mask) == precision_mask) { // could further guard with (lower + w < lower)
|
||||
// regarding the second product, we only need secondproduct.high, but our expectation is that the compiler will optimize this extra work away if needed.
|
||||
value128 secondproduct = full_multiplication(w, powers::power_of_five_128[index + 1]);
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 value128
|
||||
compute_product_approximation(int64_t q, uint64_t w) {
|
||||
int const index = 2 * int(q - powers::smallest_power_of_five);
|
||||
// For small values of q, e.g., q in [0,27], the answer is always exact
|
||||
// because The line value128 firstproduct = full_multiplication(w,
|
||||
// power_of_five_128[index]); gives the exact answer.
|
||||
value128 firstproduct =
|
||||
full_multiplication(w, powers::power_of_five_128[index]);
|
||||
static_assert((bit_precision >= 0) && (bit_precision <= 64),
|
||||
" precision should be in (0,64]");
|
||||
constexpr uint64_t precision_mask =
|
||||
(bit_precision < 64) ? (uint64_t(0xFFFFFFFFFFFFFFFF) >> bit_precision)
|
||||
: uint64_t(0xFFFFFFFFFFFFFFFF);
|
||||
if ((firstproduct.high & precision_mask) ==
|
||||
precision_mask) { // could further guard with (lower + w < lower)
|
||||
// regarding the second product, we only need secondproduct.high, but our
|
||||
// expectation is that the compiler will optimize this extra work away if
|
||||
// needed.
|
||||
value128 secondproduct =
|
||||
full_multiplication(w, powers::power_of_five_128[index + 1]);
|
||||
firstproduct.low += secondproduct.high;
|
||||
if(secondproduct.high > firstproduct.low) {
|
||||
if (secondproduct.high > firstproduct.low) {
|
||||
firstproduct.high++;
|
||||
}
|
||||
}
|
||||
@@ -55,43 +62,45 @@ namespace detail {
|
||||
* where
|
||||
* p = log(5**-q)/log(2) = -q * log(5)/log(2)
|
||||
*/
|
||||
constexpr fastfloat_really_inline int32_t power(int32_t q) noexcept {
|
||||
return (((152170 + 65536) * q) >> 16) + 63;
|
||||
}
|
||||
constexpr fastfloat_really_inline int32_t power(int32_t q) noexcept {
|
||||
return (((152170 + 65536) * q) >> 16) + 63;
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
// create an adjusted mantissa, biased by the invalid power2
|
||||
// for significant digits already multiplied by 10 ** q.
|
||||
template <typename binary>
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR14
|
||||
adjusted_mantissa compute_error_scaled(int64_t q, uint64_t w, int lz) noexcept {
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR14 adjusted_mantissa
|
||||
compute_error_scaled(int64_t q, uint64_t w, int lz) noexcept {
|
||||
int hilz = int(w >> 63) ^ 1;
|
||||
adjusted_mantissa answer;
|
||||
answer.mantissa = w << hilz;
|
||||
int bias = binary::mantissa_explicit_bits() - binary::minimum_exponent();
|
||||
answer.power2 = int32_t(detail::power(int32_t(q)) + bias - hilz - lz - 62 + invalid_am_bias);
|
||||
answer.power2 = int32_t(detail::power(int32_t(q)) + bias - hilz - lz - 62 +
|
||||
invalid_am_bias);
|
||||
return answer;
|
||||
}
|
||||
|
||||
// w * 10 ** q, without rounding the representation up.
|
||||
// the power2 in the exponent will be adjusted by invalid_am_bias.
|
||||
template <typename binary>
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20
|
||||
adjusted_mantissa compute_error(int64_t q, uint64_t w) noexcept {
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa
|
||||
compute_error(int64_t q, uint64_t w) noexcept {
|
||||
int lz = leading_zeroes(w);
|
||||
w <<= lz;
|
||||
value128 product = compute_product_approximation<binary::mantissa_explicit_bits() + 3>(q, w);
|
||||
value128 product =
|
||||
compute_product_approximation<binary::mantissa_explicit_bits() + 3>(q, w);
|
||||
return compute_error_scaled<binary>(q, product.high, lz);
|
||||
}
|
||||
|
||||
// w * 10 ** q
|
||||
// The returned value should be a valid ieee64 number that simply need to be packed.
|
||||
// However, in some very rare cases, the computation will fail. In such cases, we
|
||||
// return an adjusted_mantissa with a negative power of 2: the caller should recompute
|
||||
// in such cases.
|
||||
// Computers w * 10 ** q.
|
||||
// The returned value should be a valid number that simply needs to be
|
||||
// packed. However, in some very rare cases, the computation will fail. In such
|
||||
// cases, we return an adjusted_mantissa with a negative power of 2: the caller
|
||||
// should recompute in such cases.
|
||||
template <typename binary>
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20
|
||||
adjusted_mantissa compute_float(int64_t q, uint64_t w) noexcept {
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa
|
||||
compute_float(int64_t q, uint64_t w) noexcept {
|
||||
adjusted_mantissa answer;
|
||||
if ((w == 0) || (q < binary::smallest_power_of_ten())) {
|
||||
answer.power2 = 0;
|
||||
@@ -105,7 +114,8 @@ adjusted_mantissa compute_float(int64_t q, uint64_t w) noexcept {
|
||||
answer.mantissa = 0;
|
||||
return answer;
|
||||
}
|
||||
// At this point in time q is in [powers::smallest_power_of_five, powers::largest_power_of_five].
|
||||
// At this point in time q is in [powers::smallest_power_of_five,
|
||||
// powers::largest_power_of_five].
|
||||
|
||||
// We want the most significant bit of i to be 1. Shift if needed.
|
||||
int lz = leading_zeroes(w);
|
||||
@@ -114,26 +124,32 @@ adjusted_mantissa compute_float(int64_t q, uint64_t w) noexcept {
|
||||
// The required precision is binary::mantissa_explicit_bits() + 3 because
|
||||
// 1. We need the implicit bit
|
||||
// 2. We need an extra bit for rounding purposes
|
||||
// 3. We might lose a bit due to the "upperbit" routine (result too small, requiring a shift)
|
||||
// 3. We might lose a bit due to the "upperbit" routine (result too small,
|
||||
// requiring a shift)
|
||||
|
||||
value128 product = compute_product_approximation<binary::mantissa_explicit_bits() + 3>(q, w);
|
||||
value128 product =
|
||||
compute_product_approximation<binary::mantissa_explicit_bits() + 3>(q, w);
|
||||
// The computed 'product' is always sufficient.
|
||||
// Mathematical proof:
|
||||
// Noble Mushtak and Daniel Lemire, Fast Number Parsing Without Fallback (to appear)
|
||||
// See script/mushtak_lemire.py
|
||||
// Noble Mushtak and Daniel Lemire, Fast Number Parsing Without Fallback (to
|
||||
// appear) See script/mushtak_lemire.py
|
||||
|
||||
// The "compute_product_approximation" function can be slightly slower than a branchless approach:
|
||||
// value128 product = compute_product(q, w);
|
||||
// but in practice, we can win big with the compute_product_approximation if its additional branch
|
||||
// is easily predicted. Which is best is data specific.
|
||||
// The "compute_product_approximation" function can be slightly slower than a
|
||||
// branchless approach: value128 product = compute_product(q, w); but in
|
||||
// practice, we can win big with the compute_product_approximation if its
|
||||
// additional branch is easily predicted. Which is best is data specific.
|
||||
int upperbit = int(product.high >> 63);
|
||||
int shift = upperbit + 64 - binary::mantissa_explicit_bits() - 3;
|
||||
|
||||
answer.mantissa = product.high >> (upperbit + 64 - binary::mantissa_explicit_bits() - 3);
|
||||
answer.mantissa = product.high >> shift;
|
||||
|
||||
answer.power2 = int32_t(detail::power(int32_t(q)) + upperbit - lz - binary::minimum_exponent());
|
||||
answer.power2 = int32_t(detail::power(int32_t(q)) + upperbit - lz -
|
||||
binary::minimum_exponent());
|
||||
if (answer.power2 <= 0) { // we have a subnormal?
|
||||
// Here have that answer.power2 <= 0 so -answer.power2 >= 0
|
||||
if(-answer.power2 + 1 >= 64) { // if we have more than 64 bits below the minimum exponent, you have a zero for sure.
|
||||
if (-answer.power2 + 1 >=
|
||||
64) { // if we have more than 64 bits below the minimum exponent, you
|
||||
// have a zero for sure.
|
||||
answer.power2 = 0;
|
||||
answer.mantissa = 0;
|
||||
// result should be zero
|
||||
@@ -142,7 +158,8 @@ adjusted_mantissa compute_float(int64_t q, uint64_t w) noexcept {
|
||||
// next line is safe because -answer.power2 + 1 < 64
|
||||
answer.mantissa >>= -answer.power2 + 1;
|
||||
// Thankfully, we can't have both "round-to-even" and subnormals because
|
||||
// "round-to-even" only occurs for powers close to 0.
|
||||
// "round-to-even" only occurs for powers close to 0 in the 32-bit and
|
||||
// and 64-bit case (with no more than 19 digits).
|
||||
answer.mantissa += (answer.mantissa & 1); // round up
|
||||
answer.mantissa >>= 1;
|
||||
// There is a weird scenario where we don't have a subnormal but just.
|
||||
@@ -152,20 +169,26 @@ adjusted_mantissa compute_float(int64_t q, uint64_t w) noexcept {
|
||||
// up 0x3fffffffffffff x 2^-1023-53 and once we do, we are no longer
|
||||
// subnormal, but we can only know this after rounding.
|
||||
// So we only declare a subnormal if we are smaller than the threshold.
|
||||
answer.power2 = (answer.mantissa < (uint64_t(1) << binary::mantissa_explicit_bits())) ? 0 : 1;
|
||||
answer.power2 =
|
||||
(answer.mantissa < (uint64_t(1) << binary::mantissa_explicit_bits()))
|
||||
? 0
|
||||
: 1;
|
||||
return answer;
|
||||
}
|
||||
|
||||
// usually, we round *up*, but if we fall right in between and and we have an
|
||||
// even basis, we need to round down
|
||||
// We are only concerned with the cases where 5**q fits in single 64-bit word.
|
||||
if ((product.low <= 1) && (q >= binary::min_exponent_round_to_even()) && (q <= binary::max_exponent_round_to_even()) &&
|
||||
((answer.mantissa & 3) == 1) ) { // we may fall between two floats!
|
||||
if ((product.low <= 1) && (q >= binary::min_exponent_round_to_even()) &&
|
||||
(q <= binary::max_exponent_round_to_even()) &&
|
||||
((answer.mantissa & 3) == 1)) { // we may fall between two floats!
|
||||
// To be in-between two floats we need that in doing
|
||||
// answer.mantissa = product.high >> (upperbit + 64 - binary::mantissa_explicit_bits() - 3);
|
||||
// ... we dropped out only zeroes. But if this happened, then we can go back!!!
|
||||
if((answer.mantissa << (upperbit + 64 - binary::mantissa_explicit_bits() - 3)) == product.high) {
|
||||
answer.mantissa &= ~uint64_t(1); // flip it so that we do not round up
|
||||
// answer.mantissa = product.high >> (upperbit + 64 -
|
||||
// binary::mantissa_explicit_bits() - 3);
|
||||
// ... we dropped out only zeroes. But if this happened, then we can go
|
||||
// back!!!
|
||||
if ((answer.mantissa << shift) == product.high) {
|
||||
answer.mantissa &= ~uint64_t(1); // flip it so that we do not round up
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,19 +13,34 @@
|
||||
namespace fast_float {
|
||||
|
||||
// 1e0 to 1e19
|
||||
constexpr static uint64_t powers_of_ten_uint64[] = {
|
||||
1UL, 10UL, 100UL, 1000UL, 10000UL, 100000UL, 1000000UL, 10000000UL, 100000000UL,
|
||||
1000000000UL, 10000000000UL, 100000000000UL, 1000000000000UL, 10000000000000UL,
|
||||
100000000000000UL, 1000000000000000UL, 10000000000000000UL, 100000000000000000UL,
|
||||
1000000000000000000UL, 10000000000000000000UL};
|
||||
constexpr static uint64_t powers_of_ten_uint64[] = {1UL,
|
||||
10UL,
|
||||
100UL,
|
||||
1000UL,
|
||||
10000UL,
|
||||
100000UL,
|
||||
1000000UL,
|
||||
10000000UL,
|
||||
100000000UL,
|
||||
1000000000UL,
|
||||
10000000000UL,
|
||||
100000000000UL,
|
||||
1000000000000UL,
|
||||
10000000000000UL,
|
||||
100000000000000UL,
|
||||
1000000000000000UL,
|
||||
10000000000000000UL,
|
||||
100000000000000000UL,
|
||||
1000000000000000000UL,
|
||||
10000000000000000000UL};
|
||||
|
||||
// calculate the exponent, in scientific notation, of the number.
|
||||
// this algorithm is not even close to optimized, but it has no practical
|
||||
// effect on performance: in order to have a faster algorithm, we'd need
|
||||
// to slow down performance for faster algorithms, and this is still fast.
|
||||
template <typename UC>
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR14
|
||||
int32_t scientific_exponent(parsed_number_string_t<UC> & num) noexcept {
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR14 int32_t
|
||||
scientific_exponent(parsed_number_string_t<UC> &num) noexcept {
|
||||
uint64_t mantissa = num.mantissa;
|
||||
int32_t exponent = int32_t(num.exponent);
|
||||
while (mantissa >= 10000) {
|
||||
@@ -45,15 +60,16 @@ int32_t scientific_exponent(parsed_number_string_t<UC> & num) noexcept {
|
||||
|
||||
// this converts a native floating-point number to an extended-precision float.
|
||||
template <typename T>
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20
|
||||
adjusted_mantissa to_extended(T value) noexcept {
|
||||
using equiv_uint = typename binary_format<T>::equiv_uint;
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa
|
||||
to_extended(T value) noexcept {
|
||||
using equiv_uint = equiv_uint_t<T>;
|
||||
constexpr equiv_uint exponent_mask = binary_format<T>::exponent_mask();
|
||||
constexpr equiv_uint mantissa_mask = binary_format<T>::mantissa_mask();
|
||||
constexpr equiv_uint hidden_bit_mask = binary_format<T>::hidden_bit_mask();
|
||||
|
||||
adjusted_mantissa am;
|
||||
int32_t bias = binary_format<T>::mantissa_explicit_bits() - binary_format<T>::minimum_exponent();
|
||||
int32_t bias = binary_format<T>::mantissa_explicit_bits() -
|
||||
binary_format<T>::minimum_exponent();
|
||||
equiv_uint bits;
|
||||
#if FASTFLOAT_HAS_BIT_CAST
|
||||
bits = std::bit_cast<equiv_uint>(value);
|
||||
@@ -66,7 +82,8 @@ adjusted_mantissa to_extended(T value) noexcept {
|
||||
am.mantissa = bits & mantissa_mask;
|
||||
} else {
|
||||
// normal
|
||||
am.power2 = int32_t((bits & exponent_mask) >> binary_format<T>::mantissa_explicit_bits());
|
||||
am.power2 = int32_t((bits & exponent_mask) >>
|
||||
binary_format<T>::mantissa_explicit_bits());
|
||||
am.power2 -= bias;
|
||||
am.mantissa = (bits & mantissa_mask) | hidden_bit_mask;
|
||||
}
|
||||
@@ -78,8 +95,8 @@ adjusted_mantissa to_extended(T value) noexcept {
|
||||
// we are given a native float that represents b, so we need to adjust it
|
||||
// halfway between b and b+u.
|
||||
template <typename T>
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20
|
||||
adjusted_mantissa to_extended_halfway(T value) noexcept {
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa
|
||||
to_extended_halfway(T value) noexcept {
|
||||
adjusted_mantissa am = to_extended(value);
|
||||
am.mantissa <<= 1;
|
||||
am.mantissa += 1;
|
||||
@@ -89,15 +106,18 @@ adjusted_mantissa to_extended_halfway(T value) noexcept {
|
||||
|
||||
// round an extended-precision float to the nearest machine float.
|
||||
template <typename T, typename callback>
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR14
|
||||
void round(adjusted_mantissa& am, callback cb) noexcept {
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR14 void round(adjusted_mantissa &am,
|
||||
callback cb) noexcept {
|
||||
int32_t mantissa_shift = 64 - binary_format<T>::mantissa_explicit_bits() - 1;
|
||||
if (-am.power2 >= mantissa_shift) {
|
||||
// have a denormal float
|
||||
int32_t shift = -am.power2 + 1;
|
||||
cb(am, std::min<int32_t>(shift, 64));
|
||||
// check for round-up: if rounding-nearest carried us to the hidden bit.
|
||||
am.power2 = (am.mantissa < (uint64_t(1) << binary_format<T>::mantissa_explicit_bits())) ? 0 : 1;
|
||||
am.power2 = (am.mantissa <
|
||||
(uint64_t(1) << binary_format<T>::mantissa_explicit_bits()))
|
||||
? 0
|
||||
: 1;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -105,7 +125,8 @@ void round(adjusted_mantissa& am, callback cb) noexcept {
|
||||
cb(am, mantissa_shift);
|
||||
|
||||
// check for carry
|
||||
if (am.mantissa >= (uint64_t(2) << binary_format<T>::mantissa_explicit_bits())) {
|
||||
if (am.mantissa >=
|
||||
(uint64_t(2) << binary_format<T>::mantissa_explicit_bits())) {
|
||||
am.mantissa = (uint64_t(1) << binary_format<T>::mantissa_explicit_bits());
|
||||
am.power2++;
|
||||
}
|
||||
@@ -119,16 +140,11 @@ void round(adjusted_mantissa& am, callback cb) noexcept {
|
||||
}
|
||||
|
||||
template <typename callback>
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR14
|
||||
void round_nearest_tie_even(adjusted_mantissa& am, int32_t shift, callback cb) noexcept {
|
||||
const uint64_t mask
|
||||
= (shift == 64)
|
||||
? UINT64_MAX
|
||||
: (uint64_t(1) << shift) - 1;
|
||||
const uint64_t halfway
|
||||
= (shift == 0)
|
||||
? 0
|
||||
: uint64_t(1) << (shift - 1);
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR14 void
|
||||
round_nearest_tie_even(adjusted_mantissa &am, int32_t shift,
|
||||
callback cb) noexcept {
|
||||
uint64_t const mask = (shift == 64) ? UINT64_MAX : (uint64_t(1) << shift) - 1;
|
||||
uint64_t const halfway = (shift == 0) ? 0 : uint64_t(1) << (shift - 1);
|
||||
uint64_t truncated_bits = am.mantissa & mask;
|
||||
bool is_above = truncated_bits > halfway;
|
||||
bool is_halfway = truncated_bits == halfway;
|
||||
@@ -145,8 +161,8 @@ void round_nearest_tie_even(adjusted_mantissa& am, int32_t shift, callback cb) n
|
||||
am.mantissa += uint64_t(cb(is_odd, is_halfway, is_above));
|
||||
}
|
||||
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR14
|
||||
void round_down(adjusted_mantissa& am, int32_t shift) noexcept {
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR14 void
|
||||
round_down(adjusted_mantissa &am, int32_t shift) noexcept {
|
||||
if (shift == 64) {
|
||||
am.mantissa = 0;
|
||||
} else {
|
||||
@@ -154,11 +170,13 @@ void round_down(adjusted_mantissa& am, int32_t shift) noexcept {
|
||||
}
|
||||
am.power2 += shift;
|
||||
}
|
||||
|
||||
template <typename UC>
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20
|
||||
void skip_zeros(UC const * & first, UC const * last) noexcept {
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void
|
||||
skip_zeros(UC const *&first, UC const *last) noexcept {
|
||||
uint64_t val;
|
||||
while (!cpp20_and_in_constexpr() && std::distance(first, last) >= int_cmp_len<UC>()) {
|
||||
while (!cpp20_and_in_constexpr() &&
|
||||
std::distance(first, last) >= int_cmp_len<UC>()) {
|
||||
::memcpy(&val, first, sizeof(uint64_t));
|
||||
if (val != int_cmp_zeros<UC>()) {
|
||||
break;
|
||||
@@ -176,11 +194,12 @@ void skip_zeros(UC const * & first, UC const * last) noexcept {
|
||||
// determine if any non-zero digits were truncated.
|
||||
// all characters must be valid digits.
|
||||
template <typename UC>
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20
|
||||
bool is_truncated(UC const * first, UC const * last) noexcept {
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 bool
|
||||
is_truncated(UC const *first, UC const *last) noexcept {
|
||||
// do 8-bit optimizations, can just compare to 8 literal 0s.
|
||||
uint64_t val;
|
||||
while (!cpp20_and_in_constexpr() && std::distance(first, last) >= int_cmp_len<UC>()) {
|
||||
while (!cpp20_and_in_constexpr() &&
|
||||
std::distance(first, last) >= int_cmp_len<UC>()) {
|
||||
::memcpy(&val, first, sizeof(uint64_t));
|
||||
if (val != int_cmp_zeros<UC>()) {
|
||||
return true;
|
||||
@@ -195,16 +214,17 @@ bool is_truncated(UC const * first, UC const * last) noexcept {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename UC>
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20
|
||||
bool is_truncated(span<const UC> s) noexcept {
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 bool
|
||||
is_truncated(span<UC const> s) noexcept {
|
||||
return is_truncated(s.ptr, s.ptr + s.len());
|
||||
}
|
||||
|
||||
|
||||
template <typename UC>
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20
|
||||
void parse_eight_digits(const UC*& p, limb& value, size_t& counter, size_t& count) noexcept {
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void
|
||||
parse_eight_digits(UC const *&p, limb &value, size_t &counter,
|
||||
size_t &count) noexcept {
|
||||
value = value * 100000000 + parse_eight_digits_unrolled(p);
|
||||
p += 8;
|
||||
counter += 8;
|
||||
@@ -212,22 +232,23 @@ void parse_eight_digits(const UC*& p, limb& value, size_t& counter, size_t& coun
|
||||
}
|
||||
|
||||
template <typename UC>
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR14
|
||||
void parse_one_digit(UC const *& p, limb& value, size_t& counter, size_t& count) noexcept {
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR14 void
|
||||
parse_one_digit(UC const *&p, limb &value, size_t &counter,
|
||||
size_t &count) noexcept {
|
||||
value = value * 10 + limb(*p - UC('0'));
|
||||
p++;
|
||||
counter++;
|
||||
count++;
|
||||
}
|
||||
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20
|
||||
void add_native(bigint& big, limb power, limb value) noexcept {
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void
|
||||
add_native(bigint &big, limb power, limb value) noexcept {
|
||||
big.mul(power);
|
||||
big.add(value);
|
||||
}
|
||||
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20
|
||||
void round_up_bigint(bigint& big, size_t& count) noexcept {
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void
|
||||
round_up_bigint(bigint &big, size_t &count) noexcept {
|
||||
// need to round-up the digits, but need to avoid rounding
|
||||
// ....9999 to ...10000, which could cause a false halfway point.
|
||||
add_native(big, 10, 1);
|
||||
@@ -236,8 +257,9 @@ void round_up_bigint(bigint& big, size_t& count) noexcept {
|
||||
|
||||
// parse the significant digits into a big integer
|
||||
template <typename UC>
|
||||
inline FASTFLOAT_CONSTEXPR20
|
||||
void parse_mantissa(bigint& result, parsed_number_string_t<UC>& num, size_t max_digits, size_t& digits) noexcept {
|
||||
inline FASTFLOAT_CONSTEXPR20 void
|
||||
parse_mantissa(bigint &result, parsed_number_string_t<UC> &num,
|
||||
size_t max_digits, size_t &digits) noexcept {
|
||||
// try to minimize the number of big integer and scalar multiplication.
|
||||
// therefore, try to parse 8 digits at a time, and multiply by the largest
|
||||
// scalar value (9 or 19 digits) for each step.
|
||||
@@ -251,12 +273,13 @@ void parse_mantissa(bigint& result, parsed_number_string_t<UC>& num, size_t max_
|
||||
#endif
|
||||
|
||||
// process all integer digits.
|
||||
UC const * p = num.integer.ptr;
|
||||
UC const * pend = p + num.integer.len();
|
||||
UC const *p = num.integer.ptr;
|
||||
UC const *pend = p + num.integer.len();
|
||||
skip_zeros(p, pend);
|
||||
// process all digits, in increments of step per loop
|
||||
while (p != pend) {
|
||||
while ((std::distance(p, pend) >= 8) && (step - counter >= 8) && (max_digits - digits >= 8)) {
|
||||
while ((std::distance(p, pend) >= 8) && (step - counter >= 8) &&
|
||||
(max_digits - digits >= 8)) {
|
||||
parse_eight_digits(p, value, counter, digits);
|
||||
}
|
||||
while (counter < step && p != pend && digits < max_digits) {
|
||||
@@ -289,7 +312,8 @@ void parse_mantissa(bigint& result, parsed_number_string_t<UC>& num, size_t max_
|
||||
}
|
||||
// process all digits, in increments of step per loop
|
||||
while (p != pend) {
|
||||
while ((std::distance(p, pend) >= 8) && (step - counter >= 8) && (max_digits - digits >= 8)) {
|
||||
while ((std::distance(p, pend) >= 8) && (step - counter >= 8) &&
|
||||
(max_digits - digits >= 8)) {
|
||||
parse_eight_digits(p, value, counter, digits);
|
||||
}
|
||||
while (counter < step && p != pend && digits < max_digits) {
|
||||
@@ -317,19 +341,23 @@ void parse_mantissa(bigint& result, parsed_number_string_t<UC>& num, size_t max_
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline FASTFLOAT_CONSTEXPR20
|
||||
adjusted_mantissa positive_digit_comp(bigint& bigmant, int32_t exponent) noexcept {
|
||||
inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa
|
||||
positive_digit_comp(bigint &bigmant, int32_t exponent) noexcept {
|
||||
FASTFLOAT_ASSERT(bigmant.pow10(uint32_t(exponent)));
|
||||
adjusted_mantissa answer;
|
||||
bool truncated;
|
||||
answer.mantissa = bigmant.hi64(truncated);
|
||||
int bias = binary_format<T>::mantissa_explicit_bits() - binary_format<T>::minimum_exponent();
|
||||
int bias = binary_format<T>::mantissa_explicit_bits() -
|
||||
binary_format<T>::minimum_exponent();
|
||||
answer.power2 = bigmant.bit_length() - 64 + bias;
|
||||
|
||||
round<T>(answer, [truncated](adjusted_mantissa& a, int32_t shift) {
|
||||
round_nearest_tie_even(a, shift, [truncated](bool is_odd, bool is_halfway, bool is_above) -> bool {
|
||||
return is_above || (is_halfway && truncated) || (is_odd && is_halfway);
|
||||
});
|
||||
round<T>(answer, [truncated](adjusted_mantissa &a, int32_t shift) {
|
||||
round_nearest_tie_even(
|
||||
a, shift,
|
||||
[truncated](bool is_odd, bool is_halfway, bool is_above) -> bool {
|
||||
return is_above || (is_halfway && truncated) ||
|
||||
(is_odd && is_halfway);
|
||||
});
|
||||
});
|
||||
|
||||
return answer;
|
||||
@@ -341,15 +369,17 @@ adjusted_mantissa positive_digit_comp(bigint& bigmant, int32_t exponent) noexcep
|
||||
// we then need to scale by `2^(f- e)`, and then the two significant digits
|
||||
// are of the same magnitude.
|
||||
template <typename T>
|
||||
inline FASTFLOAT_CONSTEXPR20
|
||||
adjusted_mantissa negative_digit_comp(bigint& bigmant, adjusted_mantissa am, int32_t exponent) noexcept {
|
||||
bigint& real_digits = bigmant;
|
||||
inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa negative_digit_comp(
|
||||
bigint &bigmant, adjusted_mantissa am, int32_t exponent) noexcept {
|
||||
bigint &real_digits = bigmant;
|
||||
int32_t real_exp = exponent;
|
||||
|
||||
// get the value of `b`, rounded down, and get a bigint representation of b+h
|
||||
adjusted_mantissa am_b = am;
|
||||
// gcc7 buf: use a lambda to remove the noexcept qualifier bug with -Wnoexcept-type.
|
||||
round<T>(am_b, [](adjusted_mantissa&a, int32_t shift) { round_down(a, shift); });
|
||||
// gcc7 buf: use a lambda to remove the noexcept qualifier bug with
|
||||
// -Wnoexcept-type.
|
||||
round<T>(am_b,
|
||||
[](adjusted_mantissa &a, int32_t shift) { round_down(a, shift); });
|
||||
T b;
|
||||
to_float(false, am_b, b);
|
||||
adjusted_mantissa theor = to_extended_halfway(b);
|
||||
@@ -371,18 +401,19 @@ adjusted_mantissa negative_digit_comp(bigint& bigmant, adjusted_mantissa am, int
|
||||
// compare digits, and use it to director rounding
|
||||
int ord = real_digits.compare(theor_digits);
|
||||
adjusted_mantissa answer = am;
|
||||
round<T>(answer, [ord](adjusted_mantissa& a, int32_t shift) {
|
||||
round_nearest_tie_even(a, shift, [ord](bool is_odd, bool _, bool __) -> bool {
|
||||
(void)_; // not needed, since we've done our comparison
|
||||
(void)__; // not needed, since we've done our comparison
|
||||
if (ord > 0) {
|
||||
return true;
|
||||
} else if (ord < 0) {
|
||||
return false;
|
||||
} else {
|
||||
return is_odd;
|
||||
}
|
||||
});
|
||||
round<T>(answer, [ord](adjusted_mantissa &a, int32_t shift) {
|
||||
round_nearest_tie_even(
|
||||
a, shift, [ord](bool is_odd, bool _, bool __) -> bool {
|
||||
(void)_; // not needed, since we've done our comparison
|
||||
(void)__; // not needed, since we've done our comparison
|
||||
if (ord > 0) {
|
||||
return true;
|
||||
} else if (ord < 0) {
|
||||
return false;
|
||||
} else {
|
||||
return is_odd;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return answer;
|
||||
@@ -402,8 +433,8 @@ adjusted_mantissa negative_digit_comp(bigint& bigmant, adjusted_mantissa am, int
|
||||
// the actual digits. we then compare the big integer representations
|
||||
// of both, and use that to direct rounding.
|
||||
template <typename T, typename UC>
|
||||
inline FASTFLOAT_CONSTEXPR20
|
||||
adjusted_mantissa digit_comp(parsed_number_string_t<UC>& num, adjusted_mantissa am) noexcept {
|
||||
inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa
|
||||
digit_comp(parsed_number_string_t<UC> &num, adjusted_mantissa am) noexcept {
|
||||
// remove the invalid exponent bias
|
||||
am.power2 -= invalid_am_bias;
|
||||
|
||||
|
||||
@@ -6,43 +6,72 @@
|
||||
|
||||
namespace fast_float {
|
||||
/**
|
||||
* This function parses the character sequence [first,last) for a number. It parses floating-point numbers expecting
|
||||
* a locale-indepent format equivalent to what is used by std::strtod in the default ("C") locale.
|
||||
* The resulting floating-point value is the closest floating-point values (using either float or double),
|
||||
* using the "round to even" convention for values that would otherwise fall right in-between two values.
|
||||
* That is, we provide exact parsing according to the IEEE standard.
|
||||
* This function parses the character sequence [first,last) for a number. It
|
||||
* parses floating-point numbers expecting a locale-indepent format equivalent
|
||||
* to what is used by std::strtod in the default ("C") locale. The resulting
|
||||
* floating-point value is the closest floating-point values (using either float
|
||||
* or double), using the "round to even" convention for values that would
|
||||
* otherwise fall right in-between two values. That is, we provide exact parsing
|
||||
* according to the IEEE standard.
|
||||
*
|
||||
* Given a successful parse, the pointer (`ptr`) in the returned value is set to point right after the
|
||||
* parsed number, and the `value` referenced is set to the parsed value. In case of error, the returned
|
||||
* `ec` contains a representative error, otherwise the default (`std::errc()`) value is stored.
|
||||
* Given a successful parse, the pointer (`ptr`) in the returned value is set to
|
||||
* point right after the parsed number, and the `value` referenced is set to the
|
||||
* parsed value. In case of error, the returned `ec` contains a representative
|
||||
* error, otherwise the default (`std::errc()`) value is stored.
|
||||
*
|
||||
* The implementation does not throw and does not allocate memory (e.g., with `new` or `malloc`).
|
||||
* The implementation does not throw and does not allocate memory (e.g., with
|
||||
* `new` or `malloc`).
|
||||
*
|
||||
* Like the C++17 standard, the `fast_float::from_chars` functions take an optional last argument of
|
||||
* the type `fast_float::chars_format`. It is a bitset value: we check whether
|
||||
* `fmt & fast_float::chars_format::fixed` and `fmt & fast_float::chars_format::scientific` are set
|
||||
* to determine whether we allow the fixed point and scientific notation respectively.
|
||||
* The default is `fast_float::chars_format::general` which allows both `fixed` and `scientific`.
|
||||
* Like the C++17 standard, the `fast_float::from_chars` functions take an
|
||||
* optional last argument of the type `fast_float::chars_format`. It is a bitset
|
||||
* value: we check whether `fmt & fast_float::chars_format::fixed` and `fmt &
|
||||
* fast_float::chars_format::scientific` are set to determine whether we allow
|
||||
* the fixed point and scientific notation respectively. The default is
|
||||
* `fast_float::chars_format::general` which allows both `fixed` and
|
||||
* `scientific`.
|
||||
*/
|
||||
template<typename T, typename UC = char, typename = FASTFLOAT_ENABLE_IF(is_supported_float_type<T>())>
|
||||
FASTFLOAT_CONSTEXPR20
|
||||
from_chars_result_t<UC> from_chars(UC const * first, UC const * last,
|
||||
T &value, chars_format fmt = chars_format::general) noexcept;
|
||||
template <typename T, typename UC = char,
|
||||
typename = FASTFLOAT_ENABLE_IF(is_supported_float_type<T>::value)>
|
||||
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
||||
from_chars(UC const *first, UC const *last, T &value,
|
||||
chars_format fmt = chars_format::general) noexcept;
|
||||
|
||||
/**
|
||||
* Like from_chars, but accepts an `options` argument to govern number parsing.
|
||||
* Both for floating-point types and integer types.
|
||||
*/
|
||||
template<typename T, typename UC = char>
|
||||
FASTFLOAT_CONSTEXPR20
|
||||
from_chars_result_t<UC> from_chars_advanced(UC const * first, UC const * last,
|
||||
T &value, parse_options_t<UC> options) noexcept;
|
||||
template <typename T, typename UC = char>
|
||||
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
||||
from_chars_advanced(UC const *first, UC const *last, T &value,
|
||||
parse_options_t<UC> options) noexcept;
|
||||
|
||||
/**
|
||||
* from_chars for integer types.
|
||||
*/
|
||||
template <typename T, typename UC = char, typename = FASTFLOAT_ENABLE_IF(!is_supported_float_type<T>())>
|
||||
FASTFLOAT_CONSTEXPR20
|
||||
from_chars_result_t<UC> from_chars(UC const * first, UC const * last, T& value, int base = 10) noexcept;
|
||||
* This function multiplies an integer number by a power of 10 and returns
|
||||
* the result as a double precision floating-point value that is correctly
|
||||
* rounded. The resulting floating-point value is the closest floating-point
|
||||
* value, using the "round to nearest, tie to even" convention for values that
|
||||
* would otherwise fall right in-between two values. That is, we provide exact
|
||||
* conversion according to the IEEE standard.
|
||||
*
|
||||
* On overflow infinity is returned, on underflow 0 is returned.
|
||||
*
|
||||
* The implementation does not throw and does not allocate memory (e.g., with
|
||||
* `new` or `malloc`).
|
||||
*/
|
||||
FASTFLOAT_CONSTEXPR20 inline double
|
||||
integer_times_pow10(uint64_t mantissa, int decimal_exponent) noexcept;
|
||||
FASTFLOAT_CONSTEXPR20 inline double
|
||||
integer_times_pow10(int64_t mantissa, int decimal_exponent) noexcept;
|
||||
|
||||
/**
|
||||
* from_chars for integer types.
|
||||
*/
|
||||
template <typename T, typename UC = char,
|
||||
typename = FASTFLOAT_ENABLE_IF(is_supported_integer_type<T>::value)>
|
||||
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
||||
from_chars(UC const *first, UC const *last, T &value, int base = 10) noexcept;
|
||||
|
||||
} // namespace fast_float
|
||||
|
||||
#include "parse_number.h"
|
||||
#endif // FASTFLOAT_FAST_FLOAT_H
|
||||
|
||||
1326
3rdparty/fast_float/include/fast_float/fast_table.h
vendored
1326
3rdparty/fast_float/include/fast_float/fast_table.h
vendored
File diff suppressed because it is too large
Load Diff
1158
3rdparty/fast_float/include/fast_float/float_common.h
vendored
1158
3rdparty/fast_float/include/fast_float/float_common.h
vendored
File diff suppressed because it is too large
Load Diff
@@ -10,8 +10,8 @@
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <system_error>
|
||||
namespace fast_float {
|
||||
|
||||
namespace fast_float {
|
||||
|
||||
namespace detail {
|
||||
/**
|
||||
@@ -20,45 +20,49 @@ namespace detail {
|
||||
* strings a null-free and fixed.
|
||||
**/
|
||||
template <typename T, typename UC>
|
||||
from_chars_result_t<UC> FASTFLOAT_CONSTEXPR14
|
||||
parse_infnan(UC const * first, UC const * last, T &value) noexcept {
|
||||
from_chars_result_t<UC>
|
||||
FASTFLOAT_CONSTEXPR14 parse_infnan(UC const *first, UC const *last,
|
||||
T &value, chars_format fmt) noexcept {
|
||||
from_chars_result_t<UC> answer{};
|
||||
answer.ptr = first;
|
||||
answer.ec = std::errc(); // be optimistic
|
||||
bool minusSign = false;
|
||||
if (*first == UC('-')) { // assume first < last, so dereference without checks; C++17 20.19.3.(7.1) explicitly forbids '+' here
|
||||
minusSign = true;
|
||||
++first;
|
||||
// assume first < last, so dereference without checks;
|
||||
bool const minusSign = (*first == UC('-'));
|
||||
// C++17 20.19.3.(7.1) explicitly forbids '+' sign here
|
||||
if ((*first == UC('-')) ||
|
||||
(uint64_t(fmt & chars_format::allow_leading_plus) &&
|
||||
(*first == UC('+')))) {
|
||||
++first;
|
||||
}
|
||||
#ifdef FASTFLOAT_ALLOWS_LEADING_PLUS // disabled by default
|
||||
if (*first == UC('+')) {
|
||||
++first;
|
||||
}
|
||||
#endif
|
||||
if (last - first >= 3) {
|
||||
if (fastfloat_strncasecmp(first, str_const_nan<UC>(), 3)) {
|
||||
answer.ptr = (first += 3);
|
||||
value = minusSign ? -std::numeric_limits<T>::quiet_NaN() : std::numeric_limits<T>::quiet_NaN();
|
||||
// Check for possible nan(n-char-seq-opt), C++17 20.19.3.7, C11 7.20.1.3.3. At least MSVC produces nan(ind) and nan(snan).
|
||||
if(first != last && *first == UC('(')) {
|
||||
for(UC const * ptr = first + 1; ptr != last; ++ptr) {
|
||||
value = minusSign ? -std::numeric_limits<T>::quiet_NaN()
|
||||
: std::numeric_limits<T>::quiet_NaN();
|
||||
// Check for possible nan(n-char-seq-opt), C++17 20.19.3.7,
|
||||
// C11 7.20.1.3.3. At least MSVC produces nan(ind) and nan(snan).
|
||||
if (first != last && *first == UC('(')) {
|
||||
for (UC const *ptr = first + 1; ptr != last; ++ptr) {
|
||||
if (*ptr == UC(')')) {
|
||||
answer.ptr = ptr + 1; // valid nan(n-char-seq-opt)
|
||||
break;
|
||||
}
|
||||
else if(!((UC('a') <= *ptr && *ptr <= UC('z')) || (UC('A') <= *ptr && *ptr <= UC('Z')) || (UC('0') <= *ptr && *ptr <= UC('9')) || *ptr == UC('_')))
|
||||
} else if (!((UC('a') <= *ptr && *ptr <= UC('z')) ||
|
||||
(UC('A') <= *ptr && *ptr <= UC('Z')) ||
|
||||
(UC('0') <= *ptr && *ptr <= UC('9')) || *ptr == UC('_')))
|
||||
break; // forbidden char, not nan(n-char-seq-opt)
|
||||
}
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
if (fastfloat_strncasecmp(first, str_const_inf<UC>(), 3)) {
|
||||
if ((last - first >= 8) && fastfloat_strncasecmp(first + 3, str_const_inf<UC>() + 3, 5)) {
|
||||
if ((last - first >= 8) &&
|
||||
fastfloat_strncasecmp(first + 3, str_const_inf<UC>() + 3, 5)) {
|
||||
answer.ptr = first + 8;
|
||||
} else {
|
||||
answer.ptr = first + 3;
|
||||
}
|
||||
value = minusSign ? -std::numeric_limits<T>::infinity() : std::numeric_limits<T>::infinity();
|
||||
value = minusSign ? -std::numeric_limits<T>::infinity()
|
||||
: std::numeric_limits<T>::infinity();
|
||||
return answer;
|
||||
}
|
||||
}
|
||||
@@ -86,73 +90,71 @@ fastfloat_really_inline bool rounds_to_nearest() noexcept {
|
||||
// However, it is expected to be much faster than the fegetround()
|
||||
// function call.
|
||||
//
|
||||
// The volatile keywoard prevents the compiler from computing the function
|
||||
// The volatile keyword prevents the compiler from computing the function
|
||||
// at compile-time.
|
||||
// There might be other ways to prevent compile-time optimizations (e.g., asm).
|
||||
// The value does not need to be std::numeric_limits<float>::min(), any small
|
||||
// value so that 1 + x should round to 1 would do (after accounting for excess
|
||||
// precision, as in 387 instructions).
|
||||
static volatile float fmin = std::numeric_limits<float>::min();
|
||||
// There might be other ways to prevent compile-time optimizations (e.g.,
|
||||
// asm). The value does not need to be std::numeric_limits<float>::min(), any
|
||||
// small value so that 1 + x should round to 1 would do (after accounting for
|
||||
// excess precision, as in 387 instructions).
|
||||
static float volatile fmin = std::numeric_limits<float>::min();
|
||||
float fmini = fmin; // we copy it so that it gets loaded at most once.
|
||||
//
|
||||
// Explanation:
|
||||
// Only when fegetround() == FE_TONEAREST do we have that
|
||||
// fmin + 1.0f == 1.0f - fmin.
|
||||
//
|
||||
// FE_UPWARD:
|
||||
// fmin + 1.0f > 1
|
||||
// 1.0f - fmin == 1
|
||||
//
|
||||
// FE_DOWNWARD or FE_TOWARDZERO:
|
||||
// fmin + 1.0f == 1
|
||||
// 1.0f - fmin < 1
|
||||
//
|
||||
// Note: This may fail to be accurate if fast-math has been
|
||||
// enabled, as rounding conventions may not apply.
|
||||
#ifdef FASTFLOAT_VISUAL_STUDIO
|
||||
# pragma warning(push)
|
||||
// todo: is there a VS warning?
|
||||
// see https://stackoverflow.com/questions/46079446/is-there-a-warning-for-floating-point-equality-checking-in-visual-studio-2013
|
||||
#elif defined(__clang__)
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wfloat-equal"
|
||||
#elif defined(__GNUC__)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wfloat-equal"
|
||||
#endif
|
||||
//
|
||||
// Explanation:
|
||||
// Only when fegetround() == FE_TONEAREST do we have that
|
||||
// fmin + 1.0f == 1.0f - fmin.
|
||||
//
|
||||
// FE_UPWARD:
|
||||
// fmin + 1.0f > 1
|
||||
// 1.0f - fmin == 1
|
||||
//
|
||||
// FE_DOWNWARD or FE_TOWARDZERO:
|
||||
// fmin + 1.0f == 1
|
||||
// 1.0f - fmin < 1
|
||||
//
|
||||
// Note: This may fail to be accurate if fast-math has been
|
||||
// enabled, as rounding conventions may not apply.
|
||||
#ifdef FASTFLOAT_VISUAL_STUDIO
|
||||
#pragma warning(push)
|
||||
// todo: is there a VS warning?
|
||||
// see
|
||||
// https://stackoverflow.com/questions/46079446/is-there-a-warning-for-floating-point-equality-checking-in-visual-studio-2013
|
||||
#elif defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wfloat-equal"
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
||||
#endif
|
||||
return (fmini + 1.0f == 1.0f - fmini);
|
||||
#ifdef FASTFLOAT_VISUAL_STUDIO
|
||||
# pragma warning(pop)
|
||||
#elif defined(__clang__)
|
||||
# pragma clang diagnostic pop
|
||||
#elif defined(__GNUC__)
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
#ifdef FASTFLOAT_VISUAL_STUDIO
|
||||
#pragma warning(pop)
|
||||
#elif defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename T>
|
||||
struct from_chars_caller
|
||||
{
|
||||
template <typename T> struct from_chars_caller {
|
||||
template <typename UC>
|
||||
FASTFLOAT_CONSTEXPR20
|
||||
static from_chars_result_t<UC> call(UC const * first, UC const * last,
|
||||
T &value, parse_options_t<UC> options) noexcept {
|
||||
FASTFLOAT_CONSTEXPR20 static from_chars_result_t<UC>
|
||||
call(UC const *first, UC const *last, T &value,
|
||||
parse_options_t<UC> options) noexcept {
|
||||
return from_chars_advanced(first, last, value, options);
|
||||
}
|
||||
};
|
||||
|
||||
#if __STDCPP_FLOAT32_T__ == 1
|
||||
template <>
|
||||
struct from_chars_caller<std::float32_t>
|
||||
{
|
||||
#ifdef __STDCPP_FLOAT32_T__
|
||||
template <> struct from_chars_caller<std::float32_t> {
|
||||
template <typename UC>
|
||||
FASTFLOAT_CONSTEXPR20
|
||||
static from_chars_result_t<UC> call(UC const * first, UC const * last,
|
||||
std::float32_t &value, parse_options_t<UC> options) noexcept{
|
||||
// if std::float32_t is defined, and we are in C++23 mode; macro set for float32;
|
||||
// set value to float due to equivalence between float and float32_t
|
||||
FASTFLOAT_CONSTEXPR20 static from_chars_result_t<UC>
|
||||
call(UC const *first, UC const *last, std::float32_t &value,
|
||||
parse_options_t<UC> options) noexcept {
|
||||
// if std::float32_t is defined, and we are in C++23 mode; macro set for
|
||||
// float32; set value to float due to equivalence between float and
|
||||
// float32_t
|
||||
float val;
|
||||
auto ret = from_chars_advanced(first, last, val, options);
|
||||
value = val;
|
||||
@@ -161,16 +163,15 @@ struct from_chars_caller<std::float32_t>
|
||||
};
|
||||
#endif
|
||||
|
||||
#if __STDCPP_FLOAT64_T__ == 1
|
||||
template <>
|
||||
struct from_chars_caller<std::float64_t>
|
||||
{
|
||||
#ifdef __STDCPP_FLOAT64_T__
|
||||
template <> struct from_chars_caller<std::float64_t> {
|
||||
template <typename UC>
|
||||
FASTFLOAT_CONSTEXPR20
|
||||
static from_chars_result_t<UC> call(UC const * first, UC const * last,
|
||||
std::float64_t &value, parse_options_t<UC> options) noexcept{
|
||||
// if std::float64_t is defined, and we are in C++23 mode; macro set for float64;
|
||||
// set value as double due to equivalence between double and float64_t
|
||||
FASTFLOAT_CONSTEXPR20 static from_chars_result_t<UC>
|
||||
call(UC const *first, UC const *last, std::float64_t &value,
|
||||
parse_options_t<UC> options) noexcept {
|
||||
// if std::float64_t is defined, and we are in C++23 mode; macro set for
|
||||
// float64; set value as double due to equivalence between double and
|
||||
// float64_t
|
||||
double val;
|
||||
auto ret = from_chars_advanced(first, last, val, options);
|
||||
value = val;
|
||||
@@ -179,52 +180,25 @@ struct from_chars_caller<std::float64_t>
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
template<typename T, typename UC, typename>
|
||||
FASTFLOAT_CONSTEXPR20
|
||||
from_chars_result_t<UC> from_chars(UC const * first, UC const * last,
|
||||
T &value, chars_format fmt /*= chars_format::general*/) noexcept {
|
||||
return from_chars_caller<T>::call(first, last, value, parse_options_t<UC>(fmt));
|
||||
template <typename T, typename UC, typename>
|
||||
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
||||
from_chars(UC const *first, UC const *last, T &value,
|
||||
chars_format fmt /*= chars_format::general*/) noexcept {
|
||||
return from_chars_caller<T>::call(first, last, value,
|
||||
parse_options_t<UC>(fmt));
|
||||
}
|
||||
|
||||
template<typename T, typename UC>
|
||||
FASTFLOAT_CONSTEXPR20
|
||||
from_chars_result_t<UC> from_chars_advanced(UC const * first, UC const * last,
|
||||
T &value, parse_options_t<UC> options) noexcept {
|
||||
|
||||
static_assert (is_supported_float_type<T>(), "only some floating-point types are supported");
|
||||
static_assert (is_supported_char_type<UC>(), "only char, wchar_t, char16_t and char32_t are supported");
|
||||
|
||||
from_chars_result_t<UC> answer;
|
||||
#ifdef FASTFLOAT_SKIP_WHITE_SPACE // disabled by default
|
||||
while ((first != last) && fast_float::is_space(uint8_t(*first))) {
|
||||
first++;
|
||||
}
|
||||
#endif
|
||||
if (first == last) {
|
||||
answer.ec = std::errc::invalid_argument;
|
||||
answer.ptr = first;
|
||||
return answer;
|
||||
}
|
||||
parsed_number_string_t<UC> pns = parse_number_string<UC>(first, last, options);
|
||||
if (!pns.valid) {
|
||||
if (options.format & chars_format::no_infnan) {
|
||||
answer.ec = std::errc::invalid_argument;
|
||||
answer.ptr = first;
|
||||
return answer;
|
||||
} else {
|
||||
return detail::parse_infnan(first, last, value);
|
||||
}
|
||||
}
|
||||
|
||||
answer.ec = std::errc(); // be optimistic
|
||||
answer.ptr = pns.lastmatch;
|
||||
template <typename T>
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 bool
|
||||
clinger_fast_path_impl(uint64_t mantissa, int64_t exponent, bool is_negative,
|
||||
T &value) noexcept {
|
||||
// The implementation of the Clinger's fast path is convoluted because
|
||||
// we want round-to-nearest in all cases, irrespective of the rounding mode
|
||||
// selected on the thread.
|
||||
// We proceed optimistically, assuming that detail::rounds_to_nearest() returns
|
||||
// true.
|
||||
if (binary_format<T>::min_exponent_fast_path() <= pns.exponent && pns.exponent <= binary_format<T>::max_exponent_fast_path() && !pns.too_many_digits) {
|
||||
// We proceed optimistically, assuming that detail::rounds_to_nearest()
|
||||
// returns true.
|
||||
if (binary_format<T>::min_exponent_fast_path() <= exponent &&
|
||||
exponent <= binary_format<T>::max_exponent_fast_path()) {
|
||||
// Unfortunately, the conventional Clinger's fast path is only possible
|
||||
// when the system rounds to the nearest float.
|
||||
//
|
||||
@@ -232,68 +206,245 @@ from_chars_result_t<UC> from_chars_advanced(UC const * first, UC const * last,
|
||||
// We could check it first (before the previous branch), but
|
||||
// there might be performance advantages at having the check
|
||||
// be last.
|
||||
if(!cpp20_and_in_constexpr() && detail::rounds_to_nearest()) {
|
||||
if (!cpp20_and_in_constexpr() && detail::rounds_to_nearest()) {
|
||||
// We have that fegetround() == FE_TONEAREST.
|
||||
// Next is Clinger's fast path.
|
||||
if (pns.mantissa <=binary_format<T>::max_mantissa_fast_path()) {
|
||||
value = T(pns.mantissa);
|
||||
if (pns.exponent < 0) { value = value / binary_format<T>::exact_power_of_ten(-pns.exponent); }
|
||||
else { value = value * binary_format<T>::exact_power_of_ten(pns.exponent); }
|
||||
if (pns.negative) { value = -value; }
|
||||
return answer;
|
||||
if (mantissa <= binary_format<T>::max_mantissa_fast_path()) {
|
||||
value = T(mantissa);
|
||||
if (exponent < 0) {
|
||||
value = value / binary_format<T>::exact_power_of_ten(-exponent);
|
||||
} else {
|
||||
value = value * binary_format<T>::exact_power_of_ten(exponent);
|
||||
}
|
||||
if (is_negative) {
|
||||
value = -value;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// We do not have that fegetround() == FE_TONEAREST.
|
||||
// Next is a modified Clinger's fast path, inspired by Jakub Jelínek's proposal
|
||||
if (pns.exponent >= 0 && pns.mantissa <=binary_format<T>::max_mantissa_fast_path(pns.exponent)) {
|
||||
// Next is a modified Clinger's fast path, inspired by Jakub Jelínek's
|
||||
// proposal
|
||||
if (exponent >= 0 &&
|
||||
mantissa <= binary_format<T>::max_mantissa_fast_path(exponent)) {
|
||||
#if defined(__clang__) || defined(FASTFLOAT_32BIT)
|
||||
// Clang may map 0 to -0.0 when fegetround() == FE_DOWNWARD
|
||||
if(pns.mantissa == 0) {
|
||||
value = pns.negative ? T(-0.) : T(0.);
|
||||
return answer;
|
||||
if (mantissa == 0) {
|
||||
value = is_negative ? T(-0.) : T(0.);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
value = T(pns.mantissa) * binary_format<T>::exact_power_of_ten(pns.exponent);
|
||||
if (pns.negative) { value = -value; }
|
||||
return answer;
|
||||
value = T(mantissa) * binary_format<T>::exact_power_of_ten(exponent);
|
||||
if (is_negative) {
|
||||
value = -value;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
adjusted_mantissa am = compute_float<binary_format<T>>(pns.exponent, pns.mantissa);
|
||||
if(pns.too_many_digits && am.power2 >= 0) {
|
||||
if(am != compute_float<binary_format<T>>(pns.exponent, pns.mantissa + 1)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function overload takes parsed_number_string_t structure that is created
|
||||
* and populated either by from_chars_advanced function taking chars range and
|
||||
* parsing options or other parsing custom function implemented by user.
|
||||
*/
|
||||
template <typename T, typename UC>
|
||||
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
||||
from_chars_advanced(parsed_number_string_t<UC> &pns, T &value) noexcept {
|
||||
static_assert(is_supported_float_type<T>::value,
|
||||
"only some floating-point types are supported");
|
||||
static_assert(is_supported_char_type<UC>::value,
|
||||
"only char, wchar_t, char16_t and char32_t are supported");
|
||||
|
||||
from_chars_result_t<UC> answer;
|
||||
|
||||
answer.ec = std::errc(); // be optimistic
|
||||
answer.ptr = pns.lastmatch;
|
||||
|
||||
if (!pns.too_many_digits &&
|
||||
clinger_fast_path_impl(pns.mantissa, pns.exponent, pns.negative, value))
|
||||
return answer;
|
||||
|
||||
adjusted_mantissa am =
|
||||
compute_float<binary_format<T>>(pns.exponent, pns.mantissa);
|
||||
if (pns.too_many_digits && am.power2 >= 0) {
|
||||
if (am != compute_float<binary_format<T>>(pns.exponent, pns.mantissa + 1)) {
|
||||
am = compute_error<binary_format<T>>(pns.exponent, pns.mantissa);
|
||||
}
|
||||
}
|
||||
// If we called compute_float<binary_format<T>>(pns.exponent, pns.mantissa) and we have an invalid power (am.power2 < 0),
|
||||
// then we need to go the long way around again. This is very uncommon.
|
||||
if(am.power2 < 0) { am = digit_comp<T>(pns, am); }
|
||||
// If we called compute_float<binary_format<T>>(pns.exponent, pns.mantissa)
|
||||
// and we have an invalid power (am.power2 < 0), then we need to go the long
|
||||
// way around again. This is very uncommon.
|
||||
if (am.power2 < 0) {
|
||||
am = digit_comp<T>(pns, am);
|
||||
}
|
||||
to_float(pns.negative, am, value);
|
||||
// Test for over/underflow.
|
||||
if ((pns.mantissa != 0 && am.mantissa == 0 && am.power2 == 0) || am.power2 == binary_format<T>::infinite_power()) {
|
||||
if ((pns.mantissa != 0 && am.mantissa == 0 && am.power2 == 0) ||
|
||||
am.power2 == binary_format<T>::infinite_power()) {
|
||||
answer.ec = std::errc::result_out_of_range;
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
template <typename T, typename UC>
|
||||
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
||||
from_chars_float_advanced(UC const *first, UC const *last, T &value,
|
||||
parse_options_t<UC> options) noexcept {
|
||||
|
||||
template <typename T, typename UC, typename>
|
||||
FASTFLOAT_CONSTEXPR20
|
||||
from_chars_result_t<UC> from_chars(UC const* first, UC const* last, T& value, int base) noexcept {
|
||||
static_assert (is_supported_char_type<UC>(), "only char, wchar_t, char16_t and char32_t are supported");
|
||||
static_assert(is_supported_float_type<T>::value,
|
||||
"only some floating-point types are supported");
|
||||
static_assert(is_supported_char_type<UC>::value,
|
||||
"only char, wchar_t, char16_t and char32_t are supported");
|
||||
|
||||
chars_format const fmt = detail::adjust_for_feature_macros(options.format);
|
||||
|
||||
from_chars_result_t<UC> answer;
|
||||
#ifdef FASTFLOAT_SKIP_WHITE_SPACE // disabled by default
|
||||
while ((first != last) && fast_float::is_space(uint8_t(*first))) {
|
||||
first++;
|
||||
if (uint64_t(fmt & chars_format::skip_white_space)) {
|
||||
while ((first != last) && fast_float::is_space(*first)) {
|
||||
first++;
|
||||
}
|
||||
}
|
||||
if (first == last) {
|
||||
answer.ec = std::errc::invalid_argument;
|
||||
answer.ptr = first;
|
||||
return answer;
|
||||
}
|
||||
parsed_number_string_t<UC> pns =
|
||||
uint64_t(fmt & detail::basic_json_fmt)
|
||||
? parse_number_string<true, UC>(first, last, options)
|
||||
: parse_number_string<false, UC>(first, last, options);
|
||||
if (!pns.valid) {
|
||||
if (uint64_t(fmt & chars_format::no_infnan)) {
|
||||
answer.ec = std::errc::invalid_argument;
|
||||
answer.ptr = first;
|
||||
return answer;
|
||||
} else {
|
||||
return detail::parse_infnan(first, last, value, fmt);
|
||||
}
|
||||
}
|
||||
|
||||
// call overload that takes parsed_number_string_t directly.
|
||||
return from_chars_advanced(pns, value);
|
||||
}
|
||||
|
||||
template <typename T, typename UC, typename>
|
||||
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
||||
from_chars(UC const *first, UC const *last, T &value, int base) noexcept {
|
||||
|
||||
static_assert(is_supported_integer_type<T>::value,
|
||||
"only integer types are supported");
|
||||
static_assert(is_supported_char_type<UC>::value,
|
||||
"only char, wchar_t, char16_t and char32_t are supported");
|
||||
|
||||
parse_options_t<UC> options;
|
||||
options.base = base;
|
||||
return from_chars_advanced(first, last, value, options);
|
||||
}
|
||||
|
||||
FASTFLOAT_CONSTEXPR20 inline double
|
||||
integer_times_pow10(uint64_t mantissa, int decimal_exponent) noexcept {
|
||||
double value;
|
||||
if (clinger_fast_path_impl(mantissa, decimal_exponent, false, value))
|
||||
return value;
|
||||
|
||||
adjusted_mantissa am =
|
||||
compute_float<binary_format<double>>(decimal_exponent, mantissa);
|
||||
to_float(false, am, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
FASTFLOAT_CONSTEXPR20 inline double
|
||||
integer_times_pow10(int64_t mantissa, int decimal_exponent) noexcept {
|
||||
const bool is_negative = mantissa < 0;
|
||||
const uint64_t m = static_cast<uint64_t>(is_negative ? -mantissa : mantissa);
|
||||
|
||||
double value;
|
||||
if (clinger_fast_path_impl(m, decimal_exponent, is_negative, value))
|
||||
return value;
|
||||
|
||||
adjusted_mantissa am =
|
||||
compute_float<binary_format<double>>(decimal_exponent, m);
|
||||
to_float(is_negative, am, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
// the following overloads are here to avoid surprising ambiguity for int,
|
||||
// unsigned, etc.
|
||||
template <typename Int>
|
||||
FASTFLOAT_CONSTEXPR20 inline typename std::enable_if<
|
||||
std::is_integral<Int>::value && !std::is_signed<Int>::value, double>::type
|
||||
integer_times_pow10(Int mantissa, int decimal_exponent) noexcept {
|
||||
return integer_times_pow10(static_cast<uint64_t>(mantissa), decimal_exponent);
|
||||
}
|
||||
|
||||
template <typename Int>
|
||||
FASTFLOAT_CONSTEXPR20 inline typename std::enable_if<
|
||||
std::is_integral<Int>::value && std::is_signed<Int>::value, double>::type
|
||||
integer_times_pow10(Int mantissa, int decimal_exponent) noexcept {
|
||||
return integer_times_pow10(static_cast<int64_t>(mantissa), decimal_exponent);
|
||||
}
|
||||
|
||||
template <typename T, typename UC>
|
||||
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
||||
from_chars_int_advanced(UC const *first, UC const *last, T &value,
|
||||
parse_options_t<UC> options) noexcept {
|
||||
|
||||
static_assert(is_supported_integer_type<T>::value,
|
||||
"only integer types are supported");
|
||||
static_assert(is_supported_char_type<UC>::value,
|
||||
"only char, wchar_t, char16_t and char32_t are supported");
|
||||
|
||||
chars_format const fmt = detail::adjust_for_feature_macros(options.format);
|
||||
int const base = options.base;
|
||||
|
||||
from_chars_result_t<UC> answer;
|
||||
if (uint64_t(fmt & chars_format::skip_white_space)) {
|
||||
while ((first != last) && fast_float::is_space(*first)) {
|
||||
first++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (first == last || base < 2 || base > 36) {
|
||||
answer.ec = std::errc::invalid_argument;
|
||||
answer.ptr = first;
|
||||
return answer;
|
||||
}
|
||||
return parse_int_string(first, last, value, base);
|
||||
|
||||
return parse_int_string(first, last, value, options);
|
||||
}
|
||||
|
||||
template <size_t TypeIx> struct from_chars_advanced_caller {
|
||||
static_assert(TypeIx > 0, "unsupported type");
|
||||
};
|
||||
|
||||
template <> struct from_chars_advanced_caller<1> {
|
||||
template <typename T, typename UC>
|
||||
FASTFLOAT_CONSTEXPR20 static from_chars_result_t<UC>
|
||||
call(UC const *first, UC const *last, T &value,
|
||||
parse_options_t<UC> options) noexcept {
|
||||
return from_chars_float_advanced(first, last, value, options);
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct from_chars_advanced_caller<2> {
|
||||
template <typename T, typename UC>
|
||||
FASTFLOAT_CONSTEXPR20 static from_chars_result_t<UC>
|
||||
call(UC const *first, UC const *last, T &value,
|
||||
parse_options_t<UC> options) noexcept {
|
||||
return from_chars_int_advanced(first, last, value, options);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename UC>
|
||||
FASTFLOAT_CONSTEXPR20 from_chars_result_t<UC>
|
||||
from_chars_advanced(UC const *first, UC const *last, T &value,
|
||||
parse_options_t<UC> options) noexcept {
|
||||
return from_chars_advanced_caller<
|
||||
size_t(is_supported_float_type<T>::value) +
|
||||
2 * size_t(is_supported_integer_type<T>::value)>::call(first, last, value,
|
||||
options);
|
||||
}
|
||||
|
||||
} // namespace fast_float
|
||||
|
||||
18
3rdparty/ffmpeg/COPYING.LGPLv2.1
vendored
18
3rdparty/ffmpeg/COPYING.LGPLv2.1
vendored
@@ -55,7 +55,7 @@ modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
@@ -111,7 +111,7 @@ modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
@@ -158,7 +158,7 @@ Library.
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
@@ -216,7 +216,7 @@ instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
@@ -267,7 +267,7 @@ Library will still fall under Section 6.)
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
@@ -329,7 +329,7 @@ restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
@@ -370,7 +370,7 @@ subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
@@ -422,7 +422,7 @@ conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
@@ -456,7 +456,7 @@ SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
|
||||
2235
3rdparty/ffmpeg/Changelog
vendored
Normal file
2235
3rdparty/ffmpeg/Changelog
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user